Code Syntax Highlighter
Turns a code snippet into highlighted HTML with inline styles that survive email and CMS sanitisers, or CSS classes for your own site. Six languages done properly, escaping verified against hostile input, and the source is provably unchanged.
🔒 This tool runs entirely in your browser. Your files are never uploaded to a server.
Preview
HTML to paste
Highlighted in this page, so nothing is uploaded — worth knowing if the snippet came out of a private repository. Six languages are supported properly rather than two hundred approximately; anything else can be pasted as plain text to get the formatting without the colours.
How to use it
- Paste your code and pick the language.
- Choose inline styles for somewhere you do not control the CSS, or classes for your own site.
- Check the preview, then copy the HTML — and the stylesheet too if you chose classes.
Inline styles versus classes
This is the only choice here that really matters, and it depends entirely on where the HTML is going.
inline <span style="color:#c678dd">const</span>
classes <span class="tok-keyword">const</span> + a stylesheet
Inline styles survive anywhere. Email clients, CMS rich-text editors, wikis and note-taking apps routinely strip a
<style> block while keeping
style attributes — so classes would arrive with nothing to match and
your carefully highlighted code would render as plain text. The cost is verbosity: every token carries its own colour, so the
HTML is several times larger.
Classes are the better choice for a site you own. The markup is compact, the colours live in one place, and switching theme later means editing a stylesheet rather than regenerating every snippet.
Escaping, and why the order matters
A syntax highlighter has to solve two problems at once: it inserts HTML tags, and its input frequently contains HTML. Get the order wrong and you either break the code or create a hole.
Escaping before tokenising turns < into a five-character
entity, which moves every subsequent offset and corrupts the token boundaries. Escaping after emitting the tags escapes
the tool's own markup and you see the span tags as text. The only correct arrangement is to tokenise the raw source, then escape
each token's text at the moment it is wrapped — which is what happens here.
The result was checked against deliberately hostile input: a <script>
tag, an onerror attribute, and a literal closing span tag inside a
comment. In each case no unescaped angle bracket survived outside the generated spans.
The code must come back unchanged
This is the property nobody thinks to test and everybody depends on. If highlighting alters your source — swallowing a character, collapsing whitespace, mangling a template literal — you get a snippet that looks correct on the page and fails when somebody copies it.
So the check is a round trip: strip the spans, reverse the escaping, and compare with the input. That returns the original exactly for all six languages, including awkward cases like nested template literals, triple-quoted Python strings and SQL's doubled-quote escape. The line-number option keeps this property too — the numbering is inserted after highlighting, and a multi-line comment ends up with the gutter nested inside its span, which is valid HTML and leaves the tags balanced.
What a tokeniser cannot know
This recognises patterns; it does not understand your code. That produces a few predictable imperfections, and it is better to name them than to pretend they do not exist.
A variable named after a keyword will be coloured as a keyword. Any identifier beginning with a capital letter is treated as a type, which is right for classes and wrong for a constant. A regular expression literal in JavaScript is hard to distinguish from division without parsing, so it may be coloured as punctuation. And a variable inside a double-quoted shell string is not picked out separately, because the string rule matches first.
None of these change your code — they only change a colour. That is the trade-off of a small tokeniser against a real parser, and for a snippet on a page it is usually the right one.
FAQ
Why only six languages?
Because six can be done properly and two hundred cannot — not without a large highlighting library, which this page deliberately does not load. A tokeniser that half-recognises a language produces output that is worse than plain text, since the miscoloured parts actively mislead. JavaScript and TypeScript, JSON, CSS, Python, SQL and shell cover most of what people paste into a page. Anything else can be run through as plain text to get the monospace formatting without invented colours.
Should I use inline styles or CSS classes?
Inline styles if you are pasting into somewhere you do not control the stylesheet — an email, a CMS rich-text field, a wiki, a Notion page. Many of those strip a <style> block entirely, which would leave classes with nothing to match and your code rendered unstyled. Classes if it is going into a site you own, because the markup is far smaller and you can restyle everything at once.
Will the highlighting change my code?
No, and that was tested rather than assumed. Stripping the generated spans and reversing the HTML escaping returns the original source byte for byte, in every supported language. It is worth checking because a highlighter that silently alters whitespace or drops a character produces code that looks right and does not run.
Is it safe to paste code containing HTML?
Yes. The code is tokenised first and each token is HTML-escaped as it is emitted, so a snippet containing <script> tags, an <img onerror> attribute, or even a literal closing span tag inside a comment comes out as inert text. That ordering matters: escaping before tokenising would corrupt the token boundaries, and escaping afterwards would destroy the markup the tool just generated.
Why does my keyword look like a variable, or vice versa?
Because this is a tokeniser rather than a parser — it recognises patterns without understanding scope or context. So a variable named "type" in JavaScript may be coloured as a keyword, and a function you defined will be coloured as a type if it starts with a capital letter. Those are the honest limits of pattern matching; a real parser is a much larger piece of software.
Is my code uploaded?
No. Everything happens in the page. That matters here more than for most tools, since the snippet you are highlighting has usually come straight out of a private repository.
How we compare
| Feature | Online Tool Store | A JS highlighter on your site | Code screenshot tools |
|---|---|---|---|
| Code never leaves your device | ✓ | ✓ | Varies |
| Output is selectable, copyable text | ✓ | ✓ | ✗ |
| Works where a stylesheet is stripped | ✓ | ✗ | ✓ |
| No JavaScript needed on the target page | ✓ | ✗ | ✓ |
| Verified not to alter the source | ✓ | Usually fine | — |
| Dozens of languages, parser-accurate | ✗ | ✓ | ✓ |
| Window chrome, shadows, shareable images | ✗ | ✗ | ✓ |
The niche this fills is pasting highlighted code somewhere that will not run JavaScript for you — a newsletter, a CMS, a knowledge base. If you control the page and can load a library, a proper highlighter covers far more languages more accurately. If you want an image rather than text, that is a screenshot tool's job.