JavaScript to PNG Converter
Convert JavaScript code to a syntax-highlighted PNG image. Customize font size, padding, line numbers, and export beautiful code screenshots instantly.
About
Sharing code as plain text risks formatting loss across platforms, chat apps, and social media. Pasted snippets lose indentation, syntax colors vanish, and monospace fonts revert to proportional. This converter rasterizes raw JavaScript source into a pixel-perfect PNG with full syntax highlighting computed by a lexical tokenizer. It classifies every token - keywords, strings, numbers, comments - and paints them onto an HTML Canvas at a configurable font size s (range 12 - 32 px). Output resolution scales with content: a 40-line file at 16 px produces roughly 800 × 960 px. The tool runs entirely in-browser; no code leaves your machine.
Limitations: the tokenizer handles standard ES2024 syntax but does not parse template literal interpolations recursively. JSX and TypeScript-specific tokens (type annotations, angle-bracket generics) render as plain text. For files exceeding 500 lines, consider splitting into logical blocks - canvas dimensions beyond 16384 px may be silently clamped by the browser.
Formulas
The output image dimensions are computed from the code content and rendering parameters:
where P = padding in pixels, G = gutter width (line number column width, 0 if disabled), Lmax = pixel width of the longest syntax-highlighted line measured via CanvasRenderingContext2D.measureText(), N = total line count, and h = line height (s ⋅ 1.5, where s = font size in px).
The tokenizer operates as a single-pass greedy scanner. At each cursor position i, it tests ordered regex patterns. The first match wins, the cursor advances by match length, and the token is stored as a tuple (type, value). Ordering matters: comments before operators (to catch // before /), strings before identifiers, and numbers before dot-operators.
Reference Data
| Token Type | Example | Default Color | Regex Pattern Summary |
|---|---|---|---|
| Line Comment | // comment | #6A9955 | \/\/.* |
| Block Comment | /* ... */ | #6A9955 | \/\*[\s\S]*?\*\/ |
| String (double) | "hello" | #CE9178 | "(?:[^"\\]|\\.)*" |
| String (single) | "world" | #CE9178 | '(?:[^'\\]|\\.)*' |
| Template Literal | `text` | #CE9178 | `(?:[^`\\]|\\.)*` |
| Number | 42, 3.14, 0xFF | #B5CEA8 | 0[xXoObB][\da-fA-F_]+|\d[\d_]*\.?[\d_]*(?:[eE][+-]?\d+)?n? |
| Keyword | const, if, return | #569CD6 | Word-boundary match against keyword set |
| Boolean / Null | true, false, null | #569CD6 | Subset of keyword list |
| Function Call | fetch(, Math.max( | #DCDCAA | [a-zA-Z_$][\w$]*(?=\() |
| Operator | === + => && | #D4D4D4 | Multi-char then single-char operator set |
| Punctuation | { } ( ) ; , | #D4D4D4 | Single character match |
| Identifier | myVar, _private | #9CDCFE | [a-zA-Z_$][\w$]* |
| Regex Literal | /\d+/g | #D16969 | /(?:[^/\\]|\\.)+/[gimsuy]* |
| Whitespace | Spaces, tabs | Transparent | \s+ (non-newline) |
Frequently Asked Questions
await, async, yield, import, export, class, const, let, and optional chaining operators. It handles numeric separators (1_000_000), BigInt literals (42n), and hex/octal/binary number formats. Template literals are highlighted as strings but interpolation expressions inside ${...} are not recursively tokenized - they render in the string color.: string, interface, type) will render as plain identifiers without special highlighting. JSX angle brackets (<Component />) are tokenized as operators and identifiers. The output is still readable but lacks semantic accuracy for non-JS syntax. A future extension could add TS/JSX keyword sets.