Turn code into visuals, stories, lessons, and experiences.
A zero-dependency, single-file Cloudflare Worker that turns any snippet of code into beautiful, shareable images — with a visual canvas, presentation mode, animation, and a teacher mode built in.
- Why Cloner Code
- Features
- Screenshots
- Quick Start
- Deploy to Cloudflare
- Custom Domain
- Export Engine
- Keyboard Shortcuts
- Project Structure
- Architecture Notes
- Roadmap
- Contributing
- License
Most code-to-image tools give you a pretty screenshot and stop there. Cloner Code is built for teaching and storytelling: you can place multiple code blocks on an infinite canvas, annotate them, animate them, and export the whole board as a razor-sharp vector or raster image.
It ships as one file. No bundler, no npm install, no framework. Copy it to a Cloudflare Worker and it runs.
| Cloner Code | |
|---|---|
| Dependencies | 0 |
| Build step | None |
| Backend | Single Cloudflare Worker |
| Data storage | Browser localStorage (fully client-side) |
| Cold start | Effectively instant |
- Smart syntax highlighting with automatic language detection
- 30+ premium themes plus a full custom theme editor
- Window chrome presets: macOS, Windows, Linux, Terminal, Browser, VS Code, Glass, Presentation
- Backgrounds: solid, linear, radial, mesh, noise, grid, dots, aurora, glass, animated, shapes
- Typography, padding, radius, shadow, scale and rotation controls
- Line numbers, line highlighting, language badge, custom window title
- Infinite pannable and zoomable board
- Code blocks, titles, text, badges, arrows and annotation notes
- Drag to move, double-click to edit, drag corner to resize
- Pinch-to-zoom and full touch support
- Export the entire board as PNG / JPEG / WebP / SVG
- Vector SVG output: infinite zoom with zero quality loss
- Raster PNG / JPEG / WebP at 1x, 2x, 3x or 4x retina scale
- Transparent background support
- Copy straight to clipboard
- Choose your source: Studio preview or the whole canvas board
- Presentation mode for live talks and classrooms
- Animation mode for typewriter-style code reveals
- Teacher mode that turns a snippet into a structured lesson
- Project manager with favorites, duplication and search
- Command palette (
Ctrl+K) for everything - Full Persian (RTL) interface with a live auto-translation layer
- Light and dark themes
- Responsive down to mobile
You need Node.js 18+ and a free Cloudflare account.
git clone https://github.com/YOUR_USERNAME/cloner-code.git
cd cloner-code
npm install
npm run devOpen the URL Wrangler prints (usually http://localhost:8787) and you are running Cloner Code locally.
There is no build step.
src/index.jsis the whole application.
npx wrangler login
npm run deployThat is it. Your worker goes live at https://cloner-code.<your-subdomain>.workers.dev.
Automatic deployment is off by default — you do not need any Cloudflare credentials to clone, run, or share this project.
If you later want every push to deploy itself, copy the ready-made workflow into place:
mkdir -p .github/workflows
cp docs/deploy.yml.example .github/workflows/deploy.ymlThen add two repository secrets under Settings → Secrets and variables → Actions:
| Secret | Where to find it |
|---|---|
CLOUDFLARE_API_TOKEN |
Cloudflare Dashboard → My Profile → API Tokens → Edit Cloudflare Workers template |
CLOUDFLARE_ACCOUNT_ID |
Cloudflare Dashboard → Workers & Pages → right sidebar |
The only workflow that runs out of the box is ci.yml, which just checks that the worker file is valid JavaScript. It needs no secrets and no account.
The live instance runs at code.clonerr.ir. To point your own domain at your worker, uncomment the routes block in wrangler.toml:
[[routes]]
pattern = "code.yourdomain.com"
custom_domain = trueThen redeploy with npm run deploy. Cloudflare provisions the TLS certificate for you.
Exports are produced by serializing live DOM into an SVG foreignObject, then optionally rasterizing it on a canvas.
| Format | Type | Best for |
|---|---|---|
| SVG | Vector | Slides, print, docs — infinite zoom, text stays real text |
| PNG | Raster | Social media, chat apps, anywhere SVG is unsupported |
| WebP | Raster | Web embedding at a smaller file size |
| JPEG | Raster | Maximum compression, no transparency |
Implementation details worth knowing:
- All stylesheets are collected from
document.styleSheetsand inlined, so themes survive the export. - CSS custom properties are read from the document root and inlined, because the exported document has no
<html>of its own. - Attribute values are XML-escaped — font stacks like
"JetBrains Mono"contain quotes that would otherwise corrupt the SVG. - An
svg:rootoverride is injected so the app's ownsvg { width: 16px }icon rule cannot shrink the exported file when it is opened standalone. document.fonts.readyis awaited before serialization so text never renders with a fallback font.- Rasterization loads via
data:URL with an automatic Blob URL fallback.
| Shortcut | Action |
|---|---|
Ctrl + K |
Command palette |
Ctrl + S |
Save project |
Ctrl + Enter |
Format code |
Ctrl + Shift + C |
Copy code |
Ctrl + Shift + E |
Export image |
Esc |
Close modal or dialog |
cloner-code/
├── src/
│ └── index.js # The entire application (HTML + CSS + JS + Worker)
├── docs/
│ ├── deploy.yml.example # Optional auto-deploy workflow
│ ├── preview-studio.png
│ ├── preview-canvas.png
│ └── preview-export.png
├── .github/
│ └── workflows/
│ └── ci.yml # Syntax check — no secrets required
├── wrangler.toml # Cloudflare Worker configuration
├── package.json # Scripts only — zero runtime dependencies
├── README.md # English guide
├── README.fa.md # Persian guide
├── CONTRIBUTING.md
├── LICENSE
└── .gitignore
The worker exports a single fetch handler that returns one HTML string:
export default {
async fetch(request, env, ctx) {
return new Response(HTML, {
headers: {
"content-type": "text/html;charset=UTF-8",
"cache-control": "no-store"
}
})
}
}Everything else — the design system, syntax highlighter, theme engine, canvas, localization layer and export pipeline — lives inside that HTML template literal as plain CSS and vanilla JavaScript wrapped in an IIFE.
Why a single file? Deployment becomes a copy-paste operation, there is no supply-chain risk, nothing to audit but your own code, and the whole app is cached at the edge as one response.
Where is my data? Entirely in your browser's localStorage. The worker never receives, stores, or logs your code.
- Embed fonts as base64 inside SVG exports for pixel-identical output across machines
- GIF and MP4 export for animation mode
- Shareable project links backed by Cloudflare KV
- More window chrome presets
- Plugin API for custom themes
Pull requests are welcome. Please read CONTRIBUTING.md first — the short version is: keep it dependency-free, keep it in one file, and test your change in both light and dark themes plus both languages.
MIT © Shayan (Cloner)
Try it live at code.clonerr.ir
If this project helps you, consider giving it a star.

