Edit HTML slide decks like PowerPoint — 100% local. No cloud, no sign-up, no upload.
▶ Try it live · ⬇ Download (1 file) · Italiano
demo-dark.mp4
▶ Try it live · Download the demo
You ask an AI to "make me a slide deck" and it hands you a single .html file.
It looks great — until you need to fix a typo, move a box, or export a clean PDF.
Your options today are: re-prompt the AI and hope, or hand-edit raw HTML.
Slidewright is the missing visual editor for those decks. Open the .html,
drag things around like in PowerPoint, type over the text, export a pristine
HTML or a pixel-perfect 16:9 PDF. Everything runs in your browser, on your
machine — the deck never leaves your laptop.
- 🔒 Local-first. No server, no account, no telemetry, no Google Fonts. The file stays with you.
- 🪶 Zero runtime dependencies. One self-contained HTML file (~140 KB). Double-click and go.
- 🎯 Real editing, not a viewer. Move/resize/rotate, recolor, crop images to shapes, undo/redo.
- 🖨 Clean export. Standalone navigable HTML + dependency-free PDF (1 slide = 1 page, true 16:9).
- 🤝 Two shells, one engine. Runs as a web app and as a VS Code extension.
- Open the live editor (nothing is uploaded — it runs in your tab), or
- Download
slidewright.htmland double-click it — it runs straight fromfile://.
Drag a deck.html onto the window (or hit Open) and start editing.
npm install
npm run dev # http://localhost:5173npm run build:single # → dist/index.html standalone (JS+CSS inlined)Open dist/index.html with a double-click: the editor runs from file://.
npm run build instead produces the multi-file output in dist/ (for debugging).
The same editor also runs as a VS Code extension (same core/ui, different
shell). Open an .html file with "Open With… → Slidewright" (opt-in: the text
editor stays the default). Saving = a VS Code document (native dirty/⌘S/undo); the
agent chat uses Copilot via vscode.lm (no keys, no CORS) with a fallback to
openai-compatible providers called from the extension host.
npm run build:vscode # bundles the webview into extension/media/
cd extension
npx @vscode/vsce package --no-dependencies # → slidewright-<version>.vsix
code --install-extension slidewright-0.1.0.vsix| Layer | Feature |
|---|---|
| L1 — Reorder | Sidebar thumbnails, drag & drop (SortableJS), duplicate / delete / new |
| L2 — Text | Double-click an element → inline contenteditable |
| L3 — Graphics | Click → selection with move/resize/rotate handles; properties panel (font, size, weight, colour, alignment, background, radius, opacity, padding, z-index); add text / shapes / icons / image (crop to shape); undo/redo; nudge with arrow keys |
| Open / Save | Open an .html file and save straight back to it (File System Access API, Chromium) with autosave; ⌘S. Download fallback on Firefox/Safari |
| Clipboard | ⌘C / ⌘V / ⌘D copy / paste / duplicate element; format painter |
| Theme | Light/dark toggle (☾/☀), remembered; the canvas shows the deck with its own style |
| Export HTML | Clean, standalone, navigable deck (arrows/click), re-openable from the editor and from an AI |
| Export PDF | Browser print with @page 16:9 (960×540pt) → 1 slide = 1 page, identical format |
| Import | Drop a deck.html (or "Open"): parses <style> + <section class="slide"> |
| AI chat (optional) | Provider-neutral agent (OpenAI-compatible: Mistral / OpenRouter / Ollama / LM Studio…; Copilot in VS Code) that edits the deck via tool calls |
bash tests/run.sh # core module regression (python3 + Chrome, no npm deps)
bash tests/run-webview.sh # VS Code shell smoke test: simulates the webview (real CSP +
# acquireVsCodeApi mock) and validates rendering + document cycleVanilla web (ES modules), no framework. The same core/ui runs in two shells
thanks to a platform layer (host adapter): web (browser) and vscode (the
extension webview). Built with Vite + vite-plugin-singlefile.
src/
core/
model.js Deck/Slide data model (intermediate JSON) + default theme
store.js Central state + undo/redo history (snapshots) + pub/sub
import.js deck.html → model
export-html.js model → clean HTML (strips editor attributes + runtime nav)
export-pdf.js model → @page 16:9 print (PDF from the browser)
sanitize.js · assets.js · agent.js · llm.js security, image pool, agent
platform/
index.js Platform contract (host adapter): file/export/llm/storage/confirm
web.js Browser impl: File System Access, LLM fetch, window.print, localStorage
vscode.js Webview impl: postMessage RPC to the extension host; storage = webview state
ui/
app.js Orchestrator (host-agnostic: uses only `platform`)
layout.js SHARED workspace markup for web + webview (no duplication)
stage.js <iframe> canvas (isolates the deck's styles), scaling, text editing
sidebar.js · selection.js · inspector.js · chat.js
util/ dom, id
styles/ tokens.css + editor.css ("Atelier drafting-cockpit")
apps/
vscode/index.html Webview entry (shell that mounts `layout` + the vscode platform)
extension/ VS Code extension (Node): Custom Editor + vscode.lm + messaging
extension.js · package.json (manifest) · media/ (webview bundle, generated)
- Fixed logical canvas 1280×720 (16:9), scaled to screen: dragging in absolute coordinates is safe.
- JSON model as the source of truth; the DOM in the iframe is the editing view. It is serialized back to the model on every commit → robust undo/redo and export.
- Snapshot undo/redo of the model (cap 120).
- "Free" elements: an in-flow element is converted to
position:absoluteby freezing its current geometry on the first move/resize (or via "Make free"), enabling manual positioning without breaking the imported layout. - Inline base64 images → a self-contained deck in a single file.
- Dependency-free PDF: the browser's print engine (no Puppeteer/weasyprint). Enable "Background graphics" in the print dialog for backgrounds.
- The editor's internal attributes (
data-ss-eid,contenteditable,ss-*classes) are removed on export: the output HTML is clean. - Primary target: decks (
<section class="slide">). Long HTML documents are a secondary case (imported as a single slide).
MIT © Valerio Dolci
