A tiny Lit Web Components framework

Web slides
that stay alive.

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.

examples/rikiki-tour Open ↗
· auto-cycles · pauses on hover

01 Why

Three on-purpose constraints

01

Open index.html

No build, no dev server, no toolchain. A deck is a folder.

02

Alive in 2031

Web standards only · Custom Elements, Shadow DOM, ES Modules, CSS variables.

03

~12 KB gzip

Lit + 24 components. Anything bigger is opt-in.

02 Two products, one folder

Add three attributes. The deck becomes a carousel.

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.

A slide deck A carousel
<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.

As a slide deck

Drop the three attributes. Keep 2D nav, presenter window, speaker notes, step-reveal.

  • P presenter
  • O overview
  • . blank

As a carousel

Keep the three. Get touch swipe, autoplay pause on hover, end-wraps to start.

  • 60 px swipe
  • Hover-pause
  • Loop

03 Anatomy

A slide is just HTML

Source · index.html
<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>

Layouts

<deck-feature> and friends provide structure · title, lead, body.

Slots

slot="title", slot="lead", slot="left", slot="right".

Atoms

<deck-code>, <deck-md>, <deck-callout>, <deck-card>, <deck-mermaid>.

04 Library

Six layouts, six jobs

  • <deck-cover>

    Opening slide · XL title on dark, optional brand mark, meta block.

  • <deck-section>

    Chapter separator · number + centered title on dark.

  • <deck-feature>

    One focal block · code, table, mermaid, big stat.

  • <deck-split>

    Two or three columns · cols="1-1", "1-2", "3".

  • <deck-feature-cards>

    Hero on top, two detail cards below.

  • <deck-takeaway>

    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

Pick a look · one link, one swap

Live preview Click a theme above · the slide below re-renders.

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

A deck, end to end

my-talk/index.html
<!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 &lt;deck-*&gt; 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

Four opt-in modules. Nothing else loads.

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

  1. 01

    transitions deck-transition.js

    1.7 KB gz

    Slide-in / fade / zoom / flip · auto-directional. Cross-fades outgoing + incoming, no background flash.

    Activate transition="slide"

  2. 02

    presenter mode deck-presenter.js

    2.9 KB gz

    Popup window · current + next slide + speaker notes + timer. Syncs via BroadcastChannel.

    Activate press P

  3. 03

    syntax shiki-plugin.js

    0.6 KB gz

    Production-grade syntax for deck-code · TextMate grammars, JSX/TSX, template literals.

    Activate installShiki()

  4. 04

    speaker notes deck-notes

    0.4 KB gz

    Hidden slot surfaced in the presenter window. Free-form text, pre-wrap.

    Activate <deck-notes>

08 Comparison

Where Rikiki sits

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

Convinced? Try it in 60 seconds.

No build, no install · just drop one HTML file on a static host.

Read the 5-min start →

Honest limits

Not the right tool when…

Rikiki is opinionated. Here is what we deliberately didn't build, so you can decide in 60 seconds whether it fits.

FAQ

Common questions

Why "Lit Web Components" and not React / Vue / Svelte?
Lit compiles to standard Web Components, which the browser understands natively. The runtime is ~6 KB gz (vs ~50 KB for React + ReactDOM) and it does not need a build step on the consumer side. A deck stays a folder · open in 2031, it still runs.
Do I need to know Lit to write a deck?
No. You write HTML tags. Lit is what we used internally to build the components. The consumer surface is plain HTML and CSS custom properties · no decorators, no template literals, no class extending.
Can I print my deck to PDF?
Yes, via the browser. Chromium with print-backgrounds enabled gives the cleanest result. There is no dedicated CLI · slides are pure HTML, so the browser print pipeline does the job.
Is there a presenter mode with notes?
Yes. Wrap notes in <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.
How do I theme a deck for my brand?
Copy 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.
What happens if I want a fancy animation that is not in the box?
You can drop a <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.
Why do you also pitch carousels?
Because 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

Browse the docs

Six entry points into the full reference. Pick the one that matches what you came for.

The whole point

Source = output.

A deck is a folder · open it in 2031, edit one character, give it again.