Turn a snippet of source code into a beautiful, shareable image.
The open-source, no-login, self-hostable answer to carbon.now.sh and ray.so.
π Live demo β snapcode-hazel.vercel.app
SnapCode is a single-page web app: paste code β pick a theme and background β export an editor-grade, high-DPI image (PNG or SVG) or copy it straight to your clipboard. Everything runs in your browser β no accounts, no backend, no tracking, nothing leaves your machine.
The entire value of this project is how good the exported image looks, so two things get disproportionate care:
- Editor-grade syntax highlighting via Shiki, which uses the same TextMate grammars as VS Code β so output looks like a real editor, not a regex approximation.
- Faithful, crisp image export β a bundled ligature font that's embedded into the output, 2Γ rendering for high-DPI sharpness, and a single, carefully controlled node that gets rasterized.
- π¨ 8 curated themes β GitHub Dark/Light, Nord, Dracula, Vitesse Dark/Light, One Dark Pro, Catppuccin Mocha.
- π§βπ» 15 languages with grammars lazy-loaded on demand (TS/TSX, JS/JSX, Python, Rust, Go, Java, JSON, HTML, CSS, Shell, SQL, Markdown, YAML).
- πΌοΈ 14 backgrounds β tasteful gradients, solids, and transparent.
- π€ JetBrains Mono with ligatures, self-hosted and embedded into exports (no system-font fallback surprises).
- πͺ macOS-style window chrome, adjustable padding, rounded corners, shadow.
- π€ Export to PNG & SVG, or copy to clipboard as an image.
- β¨οΈ Keyboard friendly β
Cmd/Ctrl + Sto export,Tab/Shift+Tabto indent in the editor. - π± Responsive, and 100% static β deploy it anywhere.
![]() |
![]() |
| TSX Β· GitHub Dark Β· Grape | Python Β· Dracula Β· Sunset |
![]() |
|
| Rust Β· Nord Β· Ocean | |
git clone https://github.com/SachaIRL/snapcode snapcode
cd snapcode
npm install
npm run devThen open the URL Vite prints (default http://localhost:5173).
| Script | What it does |
|---|---|
npm run dev |
Start the dev server with HMR |
npm run build |
Type-check and build to dist/ |
npm run preview |
Serve the production build locally |
npm run typecheck |
tsc in strict mode, no emit |
npm run lint |
ESLint over the project |
npm run format |
Prettier write |
- Paste or edit code in the left panel.
- Pick a language, theme, background, padding, and toggle the window chrome in the toolbar.
- Export with the buttons in the top-right: Copy (to clipboard),
SVG, or Export PNG.
Cmd/Ctrl + Salso exports a PNG.
Exports are named snapcode-<timestamp>.png / .svg.
SnapCode builds to a fully static site in dist/ β host it on anything.
npm run build # outputs to dist/
npm run preview # sanity-check the build locally- Vercel β a
vercel.jsonis included; import the repo and it deploys with zero extra config. - Netlify / Cloudflare Pages / GitHub Pages / any static host β build
command
npm run build, publish directorydist. (For GitHub Pages served from a subpath, set Vite'sbase.) - Self-host β serve the
dist/folder with any static file server (nginx, Caddy,npx serve dist, β¦).
The project keeps a clean boundary so a future headless/CLI export path stays cheap to add:
src/
core/ # framework-agnostic: Shiki highlighter, themes, languages,
# backgrounds, settings types β NO React imports
lib/ # React glue: settings hook, highlight hook, image export
components/ # Editor, PreviewCard (the one exportable node), Toolbar, ExportBar
fonts/ # self-hosted JetBrains Mono (woff2) + OFL license
Two principles do the heavy lifting:
- One exportable node. Exactly one DOM element β the preview card
(
#snap-preview-card) β gets rasterized. Everything visual lives inside it, so the export captures the preview faithfully. - The highlighter is a singleton. Shiki is created once as a module-level promise (with the pure-JS RegExp engine, so there's no WASM to ship) and reused everywhere; themes and grammars load lazily and are cached.
- v2: headless / CLI export via Satori +
resvg β the
core/boundary above is designed to make this a small addition.
Out of scope by design: accounts, backends, databases, sharing/permalink services. v1 is intentionally 100% client-side.
Issues and PRs welcome. Before pushing:
npm run typecheck && npm run lint && npm run buildCI runs the same three checks on every push and pull request
(.github/workflows/ci.yml).
The README example images are generated from the live app with
scripts/save-image-server.mjs β see the
comment at the top of that file.
- Code: MIT.
- Bundled font: JetBrains Mono, SIL Open Font License 1.1.
- Syntax highlighting by Shiki; image export by html-to-image.


