Open index.html
No build, no dev server, no toolchain. A deck is a folder.
A tiny Lit Web Components framework
Lit Web Components for talk decks · and product carousels · ~12 KB gzip · zero build
Write a deck as plain HTML. Open index.html in a browser. No build step,
no toolchain, no node_modules to resurrect five years from now.
01 Why
index.htmlNo build, no dev server, no toolchain. A deck is a folder.
Web standards only · Custom Elements, Shadow DOM, ES Modules, CSS variables.
Lit + 24 components. Anything bigger is opt-in.
02 Two products, one folder
Same components. Same theming. Same 12 KB bundle. The dual-use isn't a marketing accident · it's a side-effect of building the deck engine on Web Components and CSS custom properties.
<deck-root autoplay="4000" loop swipe transition="slide"> <deck-cover>...</deck-cover> <deck-feature>...</deck-feature> <deck-feature>...</deck-feature> </deck-root>
Three attributes. The whole change. Same markup as any other deck · the engine just stops asking the human and starts auto-advancing with touch swipe.
Drop the three attributes. Keep 2D nav, presenter window, speaker notes, step-reveal.
Keep the three. Get touch swipe, autoplay pause on hover, end-wraps to start.
03 Anatomy
<deck-feature eyebrow="Module">
<h1 slot="title">Side effects</h1>
<p slot="lead" class="lead">
A module can act on import.
</p>
<deck-code lang="ts" hero>
import './polyfill';
</deck-code>
</deck-feature> <deck-feature> and friends provide structure · title, lead, body.
slot="title", slot="lead", slot="left", slot="right".
<deck-code>, <deck-md>, <deck-callout>, <deck-card>, <deck-mermaid>.
04 Library
Opening slide · XL title on dark, optional brand mark, meta block.
Chapter separator · number + centered title on dark.
One focal block · code, table, mermaid, big stat.
Two or three columns · cols="1-1", "1-2", "3".
Hero on top, two detail cards below.
Centered punchline on dark · the take-home line.
Plus 18 atoms · md, code, callout,
card, mermaid, stat, badge,
metric, tier-list, step-list,
kicker, stack, grid, punch,
shortcut, kbd, punch.
05 Two themes
Every component reads its colors, type and spacing from CSS custom
properties. To make a third theme, copy themes/rikiki.css,
change the values, ship it.
06 60 seconds, no install
<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="rikiki/tokens.css">
<script type="module" src="rikiki/dist/index.js"></script>
</head>
<body>
<deck-root>
<deck-cover brand="my-talk">
<h1>Hello, <span class="accent">world</span>.</h1>
</deck-cover>
<deck-feature eyebrow="One slide">
<h1 slot="title">That's all you need.</h1>
<deck-md>Write **markdown**, drop <deck-*> blocks, navigate with arrows.</deck-md>
</deck-feature>
</deck-root>
</body>
</html>
Drop this file on any static host · GitHub Pages, S3, Netlify, your local
python -m http.server. No build, no environment.
Want a more guided walk-through? → Your first deck in 5 components.
07 Plugin shelf
The 12 KB core ships none of these. Each one fetches on first use, so a deck that doesn't need a feature never pays for it.
Total if you enable everything · ~5.6 KB gzip on top of core
deck-transition.js Slide-in / fade / zoom / flip · auto-directional. Cross-fades outgoing + incoming, no background flash.
Activate transition="slide"
deck-presenter.js Popup window · current + next slide + speaker notes + timer. Syncs via BroadcastChannel.
Activate press P
shiki-plugin.js Production-grade syntax for deck-code · TextMate grammars, JSX/TSX, template literals.
Activate installShiki()
deck-notes Hidden slot surfaced in the presenter window. Free-form text, pre-wrap.
Activate <deck-notes>
08 Comparison
Read this fairly: Slidev, reveal.js, Marp and Spectacle are all excellent. Rikiki is for the specific case where you want to open a folder five years from now and still give the talk · or, lately, embed a touch-friendly carousel on your landing page. That single constraint explains every column below.
| Rikiki our case | Slidev | reveal.js | Marp | Spectacle | |
|---|---|---|---|---|---|
| Source format | HTML | Markdown + Vue | HTML + JS | Markdown | JSX |
| Build step | ✓ no | × yes (Vite) | ~ optional | × yes (CLI) | × yes (webpack) |
| Runtime bundle (gz) | ~12 KB | ~600 KB | ~80 KB | ~50 KB | ~250 KB |
| Per-deck deps | 1 CSS + 1 JS | package.json | reveal.js dir | marp-cli | package.json |
| Works in 5 years | ✓ yes | ~ depends on Vue | ✓ yes | ~ depends on CLI | ~ depends on JSX |
Honest limits
Rikiki is opinionated. Here is what we deliberately didn't build, so you can decide in 60 seconds whether it fits.
.pptx output is not on the roadmap.
You can browser-print to PDF (we recommend Chromium with print backgrounds on).
FAQ
<deck-notes> inside any slide, then press P during the talk · a popup window opens with current + next slide, the notes, a timer, and slide counter. Sync is BroadcastChannel-based; no network call.themes/rikiki.css, change the values, link it instead of the default. ~140 CSS custom properties, organised in two layers (palette / semantic). For a single instance, override the --deck-*-* tokens inline on the element.<script> inside any slide and run whatever JS you want · the slide is just an HTML host. For most needs, the four built-in transitions (slide / fade / zoom / flip) are enough; for one-off effects, GSAP and friends are a script tag away.autoplay loop swipe on <deck-root> turns the same engine into a touch-friendly carousel. Same components, same theming, same 12 KB bundle. The dual-use is a side-effect of building on web standards.Documentation
Six entry points into the full reference. Pick the one that matches what you came for.
Three install paths · CDN, npm, git clone. First slide in one minute.
Read →How layouts, slots and atoms compose. Read this before writing.
Read →Every <deck-*> element · attributes, slots, tokens, one example each.
Read →2D keyboard model, overview mode, help overlay, route-state.
Read →~140 CSS variables, BEM naming, palette + semantic layers.
Read →Concrete patterns · code-on-left, big-number cover, side-by-side comparison.
Read →The whole point
Source = output.
A deck is a folder · open it in 2031, edit one character, give it again.