Slides as light, LLM-friendly text.
A whole slide is ~60 tokens, not the ~10,000 a PowerPoint slide costs an LLM to read or write.
Home · Launch the app → · Format spec · Benchmark
Write a deck in an extended-markdown .slide format, see it live in a browser
editor, edit it visually, and export a self-contained HTML deck, a PDF, or an
editable PowerPoint.
The bet: the format is the product. Decks are plain text — tiny, diffable, and reliably read/written by an LLM — because content is markdown, layout is a small closed vocabulary, and there is no raw-HTML escape hatch. That's why a slide is ~60 tokens instead of ~10,000, and why an LLM can generate one without producing a corrupt file (see the benchmark).
Why it's different from Marp/Slidev: the grammar is closed and validatable. An agent can generate → validate → repair a deck with no human in the loop, and a malformed deck degrades gracefully instead of failing to open.
npm install
npm run dev # editor + live preview at http://localhost:5173
npm run build # type-check + production build
npm test # unit tests (parser, renderer, export) via Vitest
npm run test:e2e # end-to-end: render a deck to screenshots via Playwrightdeckware is designed so an LLM can author a deck reliably. Paste the prompt
below into any assistant (Claude, ChatGPT, …), fill in the last two lines, and
open the resulting .slide/.md file with the Open button.
You are generating a deck in the `.slide` format for deckware. Output ONLY the
raw .slide file content — no prose, no surrounding code fences.
# File shape
- Front matter (key: value lines) at the top, then a line with only `---`.
- Slides are separated by a line containing only `---`.
# Front matter keys
- title: <deck title>
- theme: one of minimal | ink | indigo
- aspect: 16:9
- Optional: bg, bg-fit (cover|contain), bg-dim (0–1) for a deck-wide background.
# A slide
Markdown, optionally preceded by a fenced layout block:
```layout
name: <layout>
align: top | center | bottom (optional)
bg: <background> (optional)
bg-dim: 0.5 (optional, for image backgrounds)
```
# Layouts (the only valid names)
- default — auto-flow content (headings, bullets). No layout block needed.
- title — centered title slide: one big `#` heading + optional `##` subtitle.
- section — section divider: one big centered heading. Pair with a bold bg.
- two-up — two columns. Tag the block that goes right with {.right}.
- quote — one large centered quotation (`>`).
# Backgrounds (bg:)
- Hex: `bg: #00003b`
- Palette token: `bg: accent` (also primary, success, warning, danger)
- Named colour: `bg: white`
- Image: `bg: image(path-or-url)` — add `bg-dim: 0.5` so text stays readable.
# Content + hints
Content flows top-to-bottom. Append `{.hint}` after a block to nudge it.
Hints (the COMPLETE list — never invent others):
- Size: small | large | huge
- Placement: left | right | center
- Width: half | third | two-thirds | full
- Colour: muted | accent | primary | success | warning | danger
- Flow: fill
Per-bullet hints work: `- shipped {.success}` colours just that item.
Colours resolve to the theme palette — do NOT use raw hex in hints.
# Columns
A line of exactly `:::` splits a slide into side-by-side columns (use 2 or 3).
Content before the first `:::` spans full width (e.g. a heading); each chunk
after it is one column. Great for comparisons / before-after.
## Build vs Buy
:::
### Build
- Full control
:::
### Buy
- Fast to launch {.success}
# Icons
Write `:name:` in text; it becomes an inline icon matching text colour/size.
Valid names ONLY: cloud, server, database, network, lock, shield, rocket,
target, zap, check, check-circle, x, alert-triangle, clock, calendar, users,
user, briefcase, trending-up, bar-chart, dollar-sign, code, cpu, box, layers,
git, settings, lightbulb, star, flag, globe, arrow-right, mail, search, coffee,
feather.
# Speaker notes
A line starting with `???` adds speaker notes (not shown on the slide).
# Rules
- NO raw HTML. NO CSS. NO hints/layouts/icons outside the lists above.
- Keep bullets short (max ~4–6 per slide). Lead bullets with an icon where useful.
- Use `title` for slide 1, `section` dividers between parts, `quote` for punchy
statements, and a `title` slide at the end for contact/close.
# Task
Create a deck about: <DESCRIBE TOPIC, AUDIENCE, KEY POINTS>
Use the <THEME> theme. Aim for <N> slides.
.slide source ◀──────────────────────────┐
│ src/core/parse.ts │ serialize (src/core/serialize.ts)
▼ │
Deck IR (src/core/ir.ts) │
│ │
├─ src/core/render.ts → live preview / export-html.ts → self-contained .html
└─ src/core/edits.ts → inspector edits ─┘ (mutate IR, write back to text)
The text file is the single source of truth. The visual inspector doesn't
edit a separate document — it mutates the IR and serializes back to .slide
text, so editing in the UI and editing the text are the same thing
(round-trippable: parse → serialize → parse is stable).
One renderer feeds the live preview, the exported HTML, and the PDF, so they
can never drift. src/core/validate.ts mechanically checks a deck against the
closed grammar, so a generate → validate → repair loop needs no human.
- Click a block in the preview to select it; edit size, alignment, width, colour, order, layout, theme, and background in the inspector — every control writes back into the source text.
- Drag blocks in the preview to reorder them within a slide.
- The preview is a scrolling column of all slides kept in sync with the editor caret (scroll ↔ cursor, both ways).
- Backgrounds: per-slide (or deck-wide) solid colour (palette token or any hex) or a referenced image (URL, path, or a locally-chosen file) with fit + dim overlay. Text contrast auto-adjusts.
- Open / Save: load a
.slide/.mdfile from disk (with live-reload when the file changes on disk, where the browser supports it), or save the source. - Icons:
:icon-name:expands to an inline SVG that inherits text colour. - Per-item hints:
- text {.danger}styles that single list item.
.slide and .md are interchangeable — a .slide file is valid Markdown; the
extension just signals deck intent and enables tooling.
Layouts: default · title · section · two-up · quote.
Hints (the whole vocabulary): size small/large/huge, placement
left/right/center, width half/third/two-thirds/full, role
muted/accent/primary/success/warning/danger, flow fill.
Themes are config files, not code: each is a *.theme.json file in
src/themes/. To add one, drop in a new mybrand.theme.json — no code change,
no registry edit (they're auto-discovered at build time).
{
"name": "mybrand",
"label": "My Brand",
"extends": "minimal",
"googleFonts": ["Inter"],
"vars": {
"--color-accent": "#3949d1",
"--color-heading": "#3949d1",
"--font-body": "'Inter', system-ui, sans-serif"
}
}A theme is a bag of CSS custom properties (+ optional Google Fonts). Use
extends to inherit another theme's vars and override only what changes.
Built-in: minimal, ink (dark), indigo (branded example).
- HTML — one self-contained file that plays like slides.
- PDF — the HTML printed (one slide per page).
- PPTX — a real, editable PowerPoint via
pptxgenjs, applying the theme's fonts/colours and backgrounds (a mapping, not pixel-identical to the HTML).
Pushing a semver tag (v1.2.3) builds the app and publishes it to GitHub Pages
via .github/workflows/deploy.yml. See that workflow for details.
MIT.