Vibecode Snappify
track this build5 phases, 10 steps, beginner friendly0%Syntax highlighting is Shiki, the frame is CSS, the export is a canvas. Carbon and ray.so already do the image for free. The slides and video features are the paid product, and they are a real product.
You are building a lean indie version of Snappify. Create the following project files first, then implement the application by following them. Keep the files updated as decisions change. Do not collapse this into a single README or prompt. ===== README.md ===== # Snappify · indie build A code screenshot tool as one static page: paste code, Shiki highlights it, frame it with padding, corners, shadow and a background, export a sharp PNG or SVG, copy to clipboard in Safari and Chromium alike, and share a snap by URL with no server. Estimated effort: **one sitting**. Work `BUILD_PLAN.md` top to bottom · every phase ends in a check that has to pass before the next one starts. ## Stack | Part | Choice | Why | | --- | --- | --- | | Highlighting | Shiki as an ES module | TextMate grammars, accurate colours | | Everything else | One HTML file, vanilla JS, Canvas 2D | no server, nothing uploaded | ## Before you start Have every one of these ready. The plan assumes them from step one. - [ ] **A terminal and a code editor** · free - Why: Every step below is a command you type or a file you edit. - Get it: VS Code (code.visualstudio.com), Cursor or Zed. Open a folder for the project and use the editor's built-in terminal. - Verify: You can open a folder and run a command in its terminal - [ ] **Git** · free - Why: History for your code, and the way most hosts deploy. - Get it: Install from git-scm.com or with your package manager, then run git init in the project folder once it exists. - Verify: git --version prints a version - [ ] **A Chromium browser and Safari** · free - Why: Clipboard image copy differs; Phase 3 tests both. - Get it: Chrome or Edge plus Safari on a Mac. - [ ] **A static host (optional)** (optional) · free - Why: To share it. - Get it: Cloudflare Pages, Netlify or GitHub Pages. ## Quick start Follow Phase 1 in `BUILD_PLAN.md`; it creates the project. Then copy `.env.example` to `.env` and fill in the values it documents. ## Honest limits This build deliberately does not replace: - Animated transitions between code states and video export: the paid product, and hard. - presentations with animated transitions between code states - video export - the template library - cloud storage of snaps If one of those is essential to you, that is the reason to keep paying for Snappify, and the README should say so rather than pretend. ===== BRIEF.md ===== # Build brief · Snappify The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me a code screenshot tool like Snappify, as a single static page. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. ### Stack (fixed, do not substitute) - One HTML file, vanilla JS, Shiki loaded as an ES module for highlighting, Canvas 2D or an SVG-to-PNG step for export. No framework, no server, nothing uploaded. ### Phase 1 · Highlight Build: a textarea, a language selector, a theme selector, and live highlighted output via Shiki. Debounce input. Done when: JavaScript, Python and JSON all highlight correctly and switching themes updates live. Do not build yet: frame, export. ### Phase 2 · The frame Build: padding, corner radius, shadow, a window chrome toggle with a title, line numbers, and a background picker with ten presets. Everything live from one state object and one render function. Done when: every control updates within a frame and the frame matches what will export. ### Phase 3 · Export Build: PNG at 1x and 2x by rendering the frame to an offscreen canvas at scale, SVG export, and copy to clipboard. For clipboard always pass a Promise resolving to a Blob into ClipboardItem · Safari requires it and Chromium accepts it, so one code path works everywhere. Call it inside the click handler. Done when: the 2x export is exactly twice the pixels and sharp, SVG opens in a vector editor, and paste works in Safari and Chromium. ### Phase 4 · Share by URL Build: encode the code and settings into the URL hash (compressed) so a link reproduces the snap with no server. Done when: opening a shared link restores code, language, theme and frame exactly. ### Phase 5 · Polish Build: keyboard shortcuts, remembering settings in localStorage wrapped in try/catch, an empty state, and offline operation after first load. Done when: the page works with the network off. ### Out of scope (and why) - Animated transitions between code states and video export. That is the paid product, and it is hard. ### README must contain - One line: nothing is uploaded. ===== AGENTS.md ===== # Agent instructions · Snappify indie build - Read `README.md` and `BUILD_PLAN.md` before writing code. The stack is fixed: Shiki as an ES module, One HTML file, vanilla JS, Canvas 2D. Do not substitute. - Work one phase at a time, in order. Do not start a phase until every "Done when" item of the previous one passes. - Prefer the fewest moving parts that satisfy the step. No frameworks, services or dependencies the plan does not name. - Secrets live in `.env`, never in source or logs. Keep `.env.example` current when a variable is introduced. - Do not invent cryptography, security guarantees, APIs or compliance claims. - Add a focused test for every destructive, security-sensitive or data-loss path the plan names. - Run the project checks before declaring a phase complete, and record any deliberate shortcut in the README under "Tradeoffs". ===== BUILD_PLAN.md ===== # Build plan · Snappify A code screenshot tool as one static page: paste code, Shiki highlights it, frame it with padding, corners, shadow and a background, export a sharp PNG or SVG, copy to clipboard in Safari and Chromium alike, and share a snap by URL with no server. Phases are in dependency order. Each ends in a "Done when" list; treat an unticked item as a blocker, not a note. ## Phase 1 · Highlight Textarea in, highlighted code out, live. ### Steps 1. Create index.html loading Shiki from a pinned ES module CDN or a vendored bundle Vendor it into the repo so the page works offline later. Files: `index.html` 2. A language selector, a theme selector and a debounced re-render ### Done when - [ ] JavaScript, Python and JSON highlight correctly - [ ] Switching themes updates live ## Phase 2 · The frame Padding, radius, shadow, window chrome, line numbers, ten backgrounds, one render(). ### Steps 1. One state object and one render function drawing to the canvas 2. Controls for each property, live ### Done when - [ ] Every control updates within a frame - [ ] The preview matches what will export ## Phase 3 · Export PNG at 1x and 2x, SVG, and clipboard in both engines. ### Steps 1. Offscreen canvas at the target scale for PNG; an SVG serializer 2. ClipboardItem with a Promise-of-Blob inside the click handler Safari requires the promise form; Chromium accepts it. ### Done when - [ ] 2x is exactly twice the pixels and sharp - [ ] SVG opens in a vector editor - [ ] Paste works in Safari and Chromium ## Phase 4 · Share by URL Code and settings compressed into the hash. ### Steps 1. Encode state with CompressionStream into the URL fragment 2. Restore from the fragment on load ### Done when - [ ] A shared link restores code, language, theme and frame exactly ## Phase 5 · Polish Shortcuts, memory, empty state, offline. ### Steps 1. Keyboard shortcuts and localStorage settings in try/catch 2. Verify zero network requests after load with Shiki vendored ### Done when - [ ] Works with the network off - [ ] A first-time user knows what to do ## Not in this build - Animated transitions between code states and video export: the paid product, and hard. ## After v1, if you want it - Diff highlighting between two snippets - A VS Code extension that opens the page with the selection ===== .env.example ===== # This build needs no environment variables. Add one here the moment a # phase introduces it, with a comment saying where the value comes from.
You are building a lean indie version of Snappify. Create the following project files first, then implement the application by following them. Keep the files updated as decisions change. Do not collapse this into a single README or prompt. ===== README.md ===== # Snappify · indie build A code screenshot tool as one static page: paste code, Shiki highlights it, frame it with padding, corners, shadow and a background, export a sharp PNG or SVG, copy to clipboard in Safari and Chromium alike, and share a snap by URL with no server. Estimated effort: **one sitting**. Work `BUILD_PLAN.md` top to bottom · every phase ends in a check that has to pass before the next one starts. ## Stack | Part | Choice | Why | | --- | --- | --- | | Highlighting | Shiki as an ES module | TextMate grammars, accurate colours | | Everything else | One HTML file, vanilla JS, Canvas 2D | no server, nothing uploaded | ## Before you start Have every one of these ready. The plan assumes them from step one. - [ ] **A terminal and a code editor** · free - Why: Every step below is a command you type or a file you edit. - Get it: VS Code (code.visualstudio.com), Cursor or Zed. Open a folder for the project and use the editor's built-in terminal. - Verify: You can open a folder and run a command in its terminal - [ ] **Git** · free - Why: History for your code, and the way most hosts deploy. - Get it: Install from git-scm.com or with your package manager, then run git init in the project folder once it exists. - Verify: git --version prints a version - [ ] **A Chromium browser and Safari** · free - Why: Clipboard image copy differs; Phase 3 tests both. - Get it: Chrome or Edge plus Safari on a Mac. - [ ] **A static host (optional)** (optional) · free - Why: To share it. - Get it: Cloudflare Pages, Netlify or GitHub Pages. ## Quick start Follow Phase 1 in `BUILD_PLAN.md`; it creates the project. Then copy `.env.example` to `.env` and fill in the values it documents. ## Honest limits This build deliberately does not replace: - Animated transitions between code states and video export: the paid product, and hard. - presentations with animated transitions between code states - video export - the template library - cloud storage of snaps If one of those is essential to you, that is the reason to keep paying for Snappify, and the README should say so rather than pretend. ===== BRIEF.md ===== # Build brief · Snappify The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me a code screenshot tool like Snappify, as a single static page. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. ### Stack (fixed, do not substitute) - One HTML file, vanilla JS, Shiki loaded as an ES module for highlighting, Canvas 2D or an SVG-to-PNG step for export. No framework, no server, nothing uploaded. ### Phase 1 · Highlight Build: a textarea, a language selector, a theme selector, and live highlighted output via Shiki. Debounce input. Done when: JavaScript, Python and JSON all highlight correctly and switching themes updates live. Do not build yet: frame, export. ### Phase 2 · The frame Build: padding, corner radius, shadow, a window chrome toggle with a title, line numbers, and a background picker with ten presets. Everything live from one state object and one render function. Done when: every control updates within a frame and the frame matches what will export. ### Phase 3 · Export Build: PNG at 1x and 2x by rendering the frame to an offscreen canvas at scale, SVG export, and copy to clipboard. For clipboard always pass a Promise resolving to a Blob into ClipboardItem · Safari requires it and Chromium accepts it, so one code path works everywhere. Call it inside the click handler. Done when: the 2x export is exactly twice the pixels and sharp, SVG opens in a vector editor, and paste works in Safari and Chromium. ### Phase 4 · Share by URL Build: encode the code and settings into the URL hash (compressed) so a link reproduces the snap with no server. Done when: opening a shared link restores code, language, theme and frame exactly. ### Phase 5 · Polish Build: keyboard shortcuts, remembering settings in localStorage wrapped in try/catch, an empty state, and offline operation after first load. Done when: the page works with the network off. ### Out of scope (and why) - Animated transitions between code states and video export. That is the paid product, and it is hard. ### README must contain - One line: nothing is uploaded. ===== AGENTS.md ===== # Agent instructions · Snappify indie build - Read `README.md` and `BUILD_PLAN.md` before writing code. The stack is fixed: Shiki as an ES module, One HTML file, vanilla JS, Canvas 2D. Do not substitute. - Work one phase at a time, in order. Do not start a phase until every "Done when" item of the previous one passes. - Prefer the fewest moving parts that satisfy the step. No frameworks, services or dependencies the plan does not name. - Secrets live in `.env`, never in source or logs. Keep `.env.example` current when a variable is introduced. - Do not invent cryptography, security guarantees, APIs or compliance claims. - Add a focused test for every destructive, security-sensitive or data-loss path the plan names. - Run the project checks before declaring a phase complete, and record any deliberate shortcut in the README under "Tradeoffs". ===== BUILD_PLAN.md ===== # Build plan · Snappify A code screenshot tool as one static page: paste code, Shiki highlights it, frame it with padding, corners, shadow and a background, export a sharp PNG or SVG, copy to clipboard in Safari and Chromium alike, and share a snap by URL with no server. Phases are in dependency order. Each ends in a "Done when" list; treat an unticked item as a blocker, not a note. ## Phase 1 · Highlight Textarea in, highlighted code out, live. ### Steps 1. Create index.html loading Shiki from a pinned ES module CDN or a vendored bundle Vendor it into the repo so the page works offline later. Files: `index.html` 2. A language selector, a theme selector and a debounced re-render ### Done when - [ ] JavaScript, Python and JSON highlight correctly - [ ] Switching themes updates live ## Phase 2 · The frame Padding, radius, shadow, window chrome, line numbers, ten backgrounds, one render(). ### Steps 1. One state object and one render function drawing to the canvas 2. Controls for each property, live ### Done when - [ ] Every control updates within a frame - [ ] The preview matches what will export ## Phase 3 · Export PNG at 1x and 2x, SVG, and clipboard in both engines. ### Steps 1. Offscreen canvas at the target scale for PNG; an SVG serializer 2. ClipboardItem with a Promise-of-Blob inside the click handler Safari requires the promise form; Chromium accepts it. ### Done when - [ ] 2x is exactly twice the pixels and sharp - [ ] SVG opens in a vector editor - [ ] Paste works in Safari and Chromium ## Phase 4 · Share by URL Code and settings compressed into the hash. ### Steps 1. Encode state with CompressionStream into the URL fragment 2. Restore from the fragment on load ### Done when - [ ] A shared link restores code, language, theme and frame exactly ## Phase 5 · Polish Shortcuts, memory, empty state, offline. ### Steps 1. Keyboard shortcuts and localStorage settings in try/catch 2. Verify zero network requests after load with Shiki vendored ### Done when - [ ] Works with the network off - [ ] A first-time user knows what to do ## Not in this build - Animated transitions between code states and video export: the paid product, and hard. ## After v1, if you want it - Diff highlighting between two snippets - A VS Code extension that opens the page with the selection ===== .env.example ===== # This build needs no environment variables. Add one here the moment a # phase introduces it, with a comment saying where the value comes from.
You are building a production product version of Snappify. Create the following project files first, then implement the application by following them. Keep the files updated as decisions change. Do not collapse this into a single README or prompt. ===== PRODUCT.md ===== # Snappify · product brief ## Problem Syntax highlighting is Shiki, the frame is CSS, the export is a canvas. Carbon and ray.so already do the image for free. The slides and video features are the paid product, and they are a real product. ## Product outcome A code image tool that is private by construction and shareable by URL. ## Target user A builder who needs a maintainable product foundation, not a one-off demo. ## Required capabilities - nothing · one static page ## Explicit non-goals for v1 - Animated transitions between code states and video export: the paid product, and hard. - presentations with animated transitions between code states - video export - the template library - cloud storage of snaps ## Success criteria - Zero network requests after load - Clipboard verified in both engines ===== BRIEF.md ===== # Build brief · Snappify The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me a code screenshot tool like Snappify, as a single static page. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. ### Stack (fixed, do not substitute) - One HTML file, vanilla JS, Shiki loaded as an ES module for highlighting, Canvas 2D or an SVG-to-PNG step for export. No framework, no server, nothing uploaded. ### Phase 1 · Highlight Build: a textarea, a language selector, a theme selector, and live highlighted output via Shiki. Debounce input. Done when: JavaScript, Python and JSON all highlight correctly and switching themes updates live. Do not build yet: frame, export. ### Phase 2 · The frame Build: padding, corner radius, shadow, a window chrome toggle with a title, line numbers, and a background picker with ten presets. Everything live from one state object and one render function. Done when: every control updates within a frame and the frame matches what will export. ### Phase 3 · Export Build: PNG at 1x and 2x by rendering the frame to an offscreen canvas at scale, SVG export, and copy to clipboard. For clipboard always pass a Promise resolving to a Blob into ClipboardItem · Safari requires it and Chromium accepts it, so one code path works everywhere. Call it inside the click handler. Done when: the 2x export is exactly twice the pixels and sharp, SVG opens in a vector editor, and paste works in Safari and Chromium. ### Phase 4 · Share by URL Build: encode the code and settings into the URL hash (compressed) so a link reproduces the snap with no server. Done when: opening a shared link restores code, language, theme and frame exactly. ### Phase 5 · Polish Build: keyboard shortcuts, remembering settings in localStorage wrapped in try/catch, an empty state, and offline operation after first load. Done when: the page works with the network off. ### Out of scope (and why) - Animated transitions between code states and video export. That is the paid product, and it is hard. ### README must contain - One line: nothing is uploaded. ===== ARCHITECTURE.md ===== # Architecture · Snappify ## Stack | Part | Choice | Why | | --- | --- | --- | | Highlighting | Shiki as an ES module | TextMate grammars, accurate colours | | Everything else | One HTML file, vanilla JS, Canvas 2D | no server, nothing uploaded | ## Modules Each module has one owner concern and a documented way to replace it. | Module | Owns | How to replace it | | --- | --- | --- | | Highlighter | Shiki | Prism, with lower fidelity | | Frame | state and render() | Keep it one file | | Share | hash encoding | Optional server-side short links | ## Configuration Every runtime setting is an environment variable documented in `.env.example`, validated at startup, with a safe local default wherever one exists. - No environment variables are needed for this build. ## Production baseline - Security: least privilege, input validation at every boundary, secret redaction in logs, rate limits on abuse-prone paths, no invented security primitives. - Data: explicit schema and migrations, transactional writes where integrity matters, backup and restore procedures that have been exercised. - Integrations: adapters around third-party providers, idempotent webhook or job processing, bounded retries, timeouts. - Observability: structured logs with request or operation ids, an error-tracking hook, and health and readiness checks where a server exists. - Quality: unit tests for domain rules, integration tests at module boundaries, one end-to-end test of the critical path. ## Decision records For each dependency in the stack table, keep a short note: why it was chosen, its failure mode, and how it is replaced. Do not add infrastructure until a requirement in `PRODUCT.md` justifies it. ===== AGENTS.md ===== # Agent instructions · Snappify product build - Read `PRODUCT.md` and `ARCHITECTURE.md` before changing code. The stack is fixed: Shiki as an ES module, One HTML file, vanilla JS, Canvas 2D. - Implement milestone by milestone from `MILESTONES.md`; keep each change reviewable and leave the application runnable at every commit. - Treat authentication, payments, encryption, imports, webhooks and destructive actions as high-risk boundaries when present. - Never invent cryptography or silently weaken a requirement to make a check pass. - Put every external service behind an interface with a deterministic fake for tests. - Add migrations and rollback or recovery notes for every persistent data change. - Log useful operational context without credentials, tokens, passwords or personal data. - Update documentation and run every check before completing a milestone. ===== MILESTONES.md ===== # Delivery milestones · Snappify Estimated effort: **one sitting** for the indie phases; the production-only milestones add the trust and operability layer. ## M1 · Highlight Textarea in, highlighted code out, live. ### Steps 1. Create index.html loading Shiki from a pinned ES module CDN or a vendored bundle Vendor it into the repo so the page works offline later. Files: `index.html` 2. A language selector, a theme selector and a debounced re-render ### Done when - [ ] JavaScript, Python and JSON highlight correctly - [ ] Switching themes updates live ## M2 · The frame Padding, radius, shadow, window chrome, line numbers, ten backgrounds, one render(). ### Steps 1. One state object and one render function drawing to the canvas 2. Controls for each property, live ### Done when - [ ] Every control updates within a frame - [ ] The preview matches what will export ## M3 · Export PNG at 1x and 2x, SVG, and clipboard in both engines. ### Steps 1. Offscreen canvas at the target scale for PNG; an SVG serializer 2. ClipboardItem with a Promise-of-Blob inside the click handler Safari requires the promise form; Chromium accepts it. ### Done when - [ ] 2x is exactly twice the pixels and sharp - [ ] SVG opens in a vector editor - [ ] Paste works in Safari and Chromium ## M4 · Share by URL Code and settings compressed into the hash. ### Steps 1. Encode state with CompressionStream into the URL fragment 2. Restore from the fragment on load ### Done when - [ ] A shared link restores code, language, theme and frame exactly ## M5 · Polish Shortcuts, memory, empty state, offline. ### Steps 1. Keyboard shortcuts and localStorage settings in try/catch 2. Verify zero network requests after load with Shiki vendored ### Done when - [ ] Works with the network off - [ ] A first-time user knows what to do ## M6 · Ship it as an app (production only) Installable and offline with a privacy line. ### Steps 1. Manifest and a service worker caching the files Files: `manifest.webmanifest`, `sw.js` 2. Deploy on a custom domain with the nothing-is-uploaded note ### Done when - [ ] Installs as an app and opens offline ===== OPERATIONS.md ===== # Operations · Snappify ## Backup The repo. ## Restore Redeploy. Do a restore drill before the first real user, and write the date here when it passes. ## Monitoring Uptime. ## Incident checklist Revert. 1. Contain the issue without destroying evidence or user data. 2. Record the timeline and affected scope. 3. Rotate exposed secrets and revoke compromised sessions or credentials. 4. Restore from a verified backup when needed. 5. Document the root cause, the remediation and the regression test. ## Release gate - [ ] Zero network requests after load - [ ] Clipboard verified in both engines ## Launch constraint Do not market omitted Snappify capabilities as implemented. The non-goals in `PRODUCT.md` remain user-visible limitations until they are deliberately delivered. ===== .env.example ===== # This build needs no environment variables. Add one here the moment a # phase introduces it, with a comment saying where the value comes from.
# Snappify · indie build A code screenshot tool as one static page: paste code, Shiki highlights it, frame it with padding, corners, shadow and a background, export a sharp PNG or SVG, copy to clipboard in Safari and Chromium alike, and share a snap by URL with no server. Estimated effort: **one sitting**. Work `BUILD_PLAN.md` top to bottom · every phase ends in a check that has to pass before the next one starts. ## Stack | Part | Choice | Why | | --- | --- | --- | | Highlighting | Shiki as an ES module | TextMate grammars, accurate colours | | Everything else | One HTML file, vanilla JS, Canvas 2D | no server, nothing uploaded | ## Before you start Have every one of these ready. The plan assumes them from step one. - [ ] **A terminal and a code editor** · free - Why: Every step below is a command you type or a file you edit. - Get it: VS Code (code.visualstudio.com), Cursor or Zed. Open a folder for the project and use the editor's built-in terminal. - Verify: You can open a folder and run a command in its terminal - [ ] **Git** · free - Why: History for your code, and the way most hosts deploy. - Get it: Install from git-scm.com or with your package manager, then run git init in the project folder once it exists. - Verify: git --version prints a version - [ ] **A Chromium browser and Safari** · free - Why: Clipboard image copy differs; Phase 3 tests both. - Get it: Chrome or Edge plus Safari on a Mac. - [ ] **A static host (optional)** (optional) · free - Why: To share it. - Get it: Cloudflare Pages, Netlify or GitHub Pages. ## Quick start Follow Phase 1 in `BUILD_PLAN.md`; it creates the project. Then copy `.env.example` to `.env` and fill in the values it documents. ## Honest limits This build deliberately does not replace: - Animated transitions between code states and video export: the paid product, and hard. - presentations with animated transitions between code states - video export - the template library - cloud storage of snaps If one of those is essential to you, that is the reason to keep paying for Snappify, and the README should say so rather than pretend.
# Build brief · Snappify The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me a code screenshot tool like Snappify, as a single static page. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. ### Stack (fixed, do not substitute) - One HTML file, vanilla JS, Shiki loaded as an ES module for highlighting, Canvas 2D or an SVG-to-PNG step for export. No framework, no server, nothing uploaded. ### Phase 1 · Highlight Build: a textarea, a language selector, a theme selector, and live highlighted output via Shiki. Debounce input. Done when: JavaScript, Python and JSON all highlight correctly and switching themes updates live. Do not build yet: frame, export. ### Phase 2 · The frame Build: padding, corner radius, shadow, a window chrome toggle with a title, line numbers, and a background picker with ten presets. Everything live from one state object and one render function. Done when: every control updates within a frame and the frame matches what will export. ### Phase 3 · Export Build: PNG at 1x and 2x by rendering the frame to an offscreen canvas at scale, SVG export, and copy to clipboard. For clipboard always pass a Promise resolving to a Blob into ClipboardItem · Safari requires it and Chromium accepts it, so one code path works everywhere. Call it inside the click handler. Done when: the 2x export is exactly twice the pixels and sharp, SVG opens in a vector editor, and paste works in Safari and Chromium. ### Phase 4 · Share by URL Build: encode the code and settings into the URL hash (compressed) so a link reproduces the snap with no server. Done when: opening a shared link restores code, language, theme and frame exactly. ### Phase 5 · Polish Build: keyboard shortcuts, remembering settings in localStorage wrapped in try/catch, an empty state, and offline operation after first load. Done when: the page works with the network off. ### Out of scope (and why) - Animated transitions between code states and video export. That is the paid product, and it is hard. ### README must contain - One line: nothing is uploaded.
# Agent instructions · Snappify indie build - Read `README.md` and `BUILD_PLAN.md` before writing code. The stack is fixed: Shiki as an ES module, One HTML file, vanilla JS, Canvas 2D. Do not substitute. - Work one phase at a time, in order. Do not start a phase until every "Done when" item of the previous one passes. - Prefer the fewest moving parts that satisfy the step. No frameworks, services or dependencies the plan does not name. - Secrets live in `.env`, never in source or logs. Keep `.env.example` current when a variable is introduced. - Do not invent cryptography, security guarantees, APIs or compliance claims. - Add a focused test for every destructive, security-sensitive or data-loss path the plan names. - Run the project checks before declaring a phase complete, and record any deliberate shortcut in the README under "Tradeoffs".
# Build plan · Snappify A code screenshot tool as one static page: paste code, Shiki highlights it, frame it with padding, corners, shadow and a background, export a sharp PNG or SVG, copy to clipboard in Safari and Chromium alike, and share a snap by URL with no server. Phases are in dependency order. Each ends in a "Done when" list; treat an unticked item as a blocker, not a note. ## Phase 1 · Highlight Textarea in, highlighted code out, live. ### Steps 1. Create index.html loading Shiki from a pinned ES module CDN or a vendored bundle Vendor it into the repo so the page works offline later. Files: `index.html` 2. A language selector, a theme selector and a debounced re-render ### Done when - [ ] JavaScript, Python and JSON highlight correctly - [ ] Switching themes updates live ## Phase 2 · The frame Padding, radius, shadow, window chrome, line numbers, ten backgrounds, one render(). ### Steps 1. One state object and one render function drawing to the canvas 2. Controls for each property, live ### Done when - [ ] Every control updates within a frame - [ ] The preview matches what will export ## Phase 3 · Export PNG at 1x and 2x, SVG, and clipboard in both engines. ### Steps 1. Offscreen canvas at the target scale for PNG; an SVG serializer 2. ClipboardItem with a Promise-of-Blob inside the click handler Safari requires the promise form; Chromium accepts it. ### Done when - [ ] 2x is exactly twice the pixels and sharp - [ ] SVG opens in a vector editor - [ ] Paste works in Safari and Chromium ## Phase 4 · Share by URL Code and settings compressed into the hash. ### Steps 1. Encode state with CompressionStream into the URL fragment 2. Restore from the fragment on load ### Done when - [ ] A shared link restores code, language, theme and frame exactly ## Phase 5 · Polish Shortcuts, memory, empty state, offline. ### Steps 1. Keyboard shortcuts and localStorage settings in try/catch 2. Verify zero network requests after load with Shiki vendored ### Done when - [ ] Works with the network off - [ ] A first-time user knows what to do ## Not in this build - Animated transitions between code states and video export: the paid product, and hard. ## After v1, if you want it - Diff highlighting between two snippets - A VS Code extension that opens the page with the selection
# This build needs no environment variables. Add one here the moment a # phase introduces it, with a comment saying where the value comes from.
# Snappify · product brief ## Problem Syntax highlighting is Shiki, the frame is CSS, the export is a canvas. Carbon and ray.so already do the image for free. The slides and video features are the paid product, and they are a real product. ## Product outcome A code image tool that is private by construction and shareable by URL. ## Target user A builder who needs a maintainable product foundation, not a one-off demo. ## Required capabilities - nothing · one static page ## Explicit non-goals for v1 - Animated transitions between code states and video export: the paid product, and hard. - presentations with animated transitions between code states - video export - the template library - cloud storage of snaps ## Success criteria - Zero network requests after load - Clipboard verified in both engines
# Build brief · Snappify The one-shot brief this plan expands. `BUILD_PLAN.md` (or `MILESTONES.md`) is the same sequence broken into steps and checks; where the two disagree, the plan wins. Build me a code screenshot tool like Snappify, as a single static page. Build it in phases, in the order below. Do not write the whole thing in one pass. Finish a phase, run its "Done when" check, fix what fails, and only then start the next phase. ### Stack (fixed, do not substitute) - One HTML file, vanilla JS, Shiki loaded as an ES module for highlighting, Canvas 2D or an SVG-to-PNG step for export. No framework, no server, nothing uploaded. ### Phase 1 · Highlight Build: a textarea, a language selector, a theme selector, and live highlighted output via Shiki. Debounce input. Done when: JavaScript, Python and JSON all highlight correctly and switching themes updates live. Do not build yet: frame, export. ### Phase 2 · The frame Build: padding, corner radius, shadow, a window chrome toggle with a title, line numbers, and a background picker with ten presets. Everything live from one state object and one render function. Done when: every control updates within a frame and the frame matches what will export. ### Phase 3 · Export Build: PNG at 1x and 2x by rendering the frame to an offscreen canvas at scale, SVG export, and copy to clipboard. For clipboard always pass a Promise resolving to a Blob into ClipboardItem · Safari requires it and Chromium accepts it, so one code path works everywhere. Call it inside the click handler. Done when: the 2x export is exactly twice the pixels and sharp, SVG opens in a vector editor, and paste works in Safari and Chromium. ### Phase 4 · Share by URL Build: encode the code and settings into the URL hash (compressed) so a link reproduces the snap with no server. Done when: opening a shared link restores code, language, theme and frame exactly. ### Phase 5 · Polish Build: keyboard shortcuts, remembering settings in localStorage wrapped in try/catch, an empty state, and offline operation after first load. Done when: the page works with the network off. ### Out of scope (and why) - Animated transitions between code states and video export. That is the paid product, and it is hard. ### README must contain - One line: nothing is uploaded.
# Architecture · Snappify ## Stack | Part | Choice | Why | | --- | --- | --- | | Highlighting | Shiki as an ES module | TextMate grammars, accurate colours | | Everything else | One HTML file, vanilla JS, Canvas 2D | no server, nothing uploaded | ## Modules Each module has one owner concern and a documented way to replace it. | Module | Owns | How to replace it | | --- | --- | --- | | Highlighter | Shiki | Prism, with lower fidelity | | Frame | state and render() | Keep it one file | | Share | hash encoding | Optional server-side short links | ## Configuration Every runtime setting is an environment variable documented in `.env.example`, validated at startup, with a safe local default wherever one exists. - No environment variables are needed for this build. ## Production baseline - Security: least privilege, input validation at every boundary, secret redaction in logs, rate limits on abuse-prone paths, no invented security primitives. - Data: explicit schema and migrations, transactional writes where integrity matters, backup and restore procedures that have been exercised. - Integrations: adapters around third-party providers, idempotent webhook or job processing, bounded retries, timeouts. - Observability: structured logs with request or operation ids, an error-tracking hook, and health and readiness checks where a server exists. - Quality: unit tests for domain rules, integration tests at module boundaries, one end-to-end test of the critical path. ## Decision records For each dependency in the stack table, keep a short note: why it was chosen, its failure mode, and how it is replaced. Do not add infrastructure until a requirement in `PRODUCT.md` justifies it.
# Agent instructions · Snappify product build - Read `PRODUCT.md` and `ARCHITECTURE.md` before changing code. The stack is fixed: Shiki as an ES module, One HTML file, vanilla JS, Canvas 2D. - Implement milestone by milestone from `MILESTONES.md`; keep each change reviewable and leave the application runnable at every commit. - Treat authentication, payments, encryption, imports, webhooks and destructive actions as high-risk boundaries when present. - Never invent cryptography or silently weaken a requirement to make a check pass. - Put every external service behind an interface with a deterministic fake for tests. - Add migrations and rollback or recovery notes for every persistent data change. - Log useful operational context without credentials, tokens, passwords or personal data. - Update documentation and run every check before completing a milestone.
# Delivery milestones · Snappify Estimated effort: **one sitting** for the indie phases; the production-only milestones add the trust and operability layer. ## M1 · Highlight Textarea in, highlighted code out, live. ### Steps 1. Create index.html loading Shiki from a pinned ES module CDN or a vendored bundle Vendor it into the repo so the page works offline later. Files: `index.html` 2. A language selector, a theme selector and a debounced re-render ### Done when - [ ] JavaScript, Python and JSON highlight correctly - [ ] Switching themes updates live ## M2 · The frame Padding, radius, shadow, window chrome, line numbers, ten backgrounds, one render(). ### Steps 1. One state object and one render function drawing to the canvas 2. Controls for each property, live ### Done when - [ ] Every control updates within a frame - [ ] The preview matches what will export ## M3 · Export PNG at 1x and 2x, SVG, and clipboard in both engines. ### Steps 1. Offscreen canvas at the target scale for PNG; an SVG serializer 2. ClipboardItem with a Promise-of-Blob inside the click handler Safari requires the promise form; Chromium accepts it. ### Done when - [ ] 2x is exactly twice the pixels and sharp - [ ] SVG opens in a vector editor - [ ] Paste works in Safari and Chromium ## M4 · Share by URL Code and settings compressed into the hash. ### Steps 1. Encode state with CompressionStream into the URL fragment 2. Restore from the fragment on load ### Done when - [ ] A shared link restores code, language, theme and frame exactly ## M5 · Polish Shortcuts, memory, empty state, offline. ### Steps 1. Keyboard shortcuts and localStorage settings in try/catch 2. Verify zero network requests after load with Shiki vendored ### Done when - [ ] Works with the network off - [ ] A first-time user knows what to do ## M6 · Ship it as an app (production only) Installable and offline with a privacy line. ### Steps 1. Manifest and a service worker caching the files Files: `manifest.webmanifest`, `sw.js` 2. Deploy on a custom domain with the nothing-is-uploaded note ### Done when - [ ] Installs as an app and opens offline
# Operations · Snappify ## Backup The repo. ## Restore Redeploy. Do a restore drill before the first real user, and write the date here when it passes. ## Monitoring Uptime. ## Incident checklist Revert. 1. Contain the issue without destroying evidence or user data. 2. Record the timeline and affected scope. 3. Rotate exposed secrets and revoke compromised sessions or credentials. 4. Restore from a verified backup when needed. 5. Document the root cause, the remediation and the regression test. ## Release gate - [ ] Zero network requests after load - [ ] Clipboard verified in both engines ## Launch constraint Do not market omitted Snappify capabilities as implemented. The non-goals in `PRODUCT.md` remain user-visible limitations until they are deliberately delivered.
# This build needs no environment variables. Add one here the moment a # phase introduces it, with a comment saying where the value comes from.
$ choose a build depth, inspect the files, then open the complete pack in your agent
Teachers and creators pay for the animated diff between two code states and the video export. The static image was always free.
xpresentations with animated transitions between code states
xvideo export
xthe template library
xcloud storage of snaps
Snappify pricing
starter$5/mo · monthly, billed yearly · $60/yr
free tierThe free plan renders code images with a watermark and stores three snaps.
verified 2026-09-04 · source ↗
Is Snappify free?
The free plan renders code images with a watermark and stores three snaps. Paid is Starter at $5/mo (checked 2026-09-04).
Vibecode Snappify
Yes. A competent AI coding agent (Claude Code, Codex, Cursor) can build a usable personal Snappify replacement in one session with the prompt on this page. It runs on your own machine or server with no subscription.
How much does Snappify cost?
Snappify costs about $5/month (Starter, checked 2026-09-04), which is $60 per year. That's what you save by replacing it with one prompt.
What do I lose by replacing Snappify?
Honestly: presentations with animated transitions between code states; video export; the template library; cloud storage of snaps. If any of those are load-bearing for you, keep paying.
Is there an open-source alternative to Snappify?
Yes: Shiki (syntax highlighter using TextMate grammars), Carbon (open-source code image generator). Using prior art is also vibecoding; the prompt is for when you want it exactly your way.