Reference
Plugins
Optional add-ons · activated by an attribute on deck-root or an explicit import. None of them are in the core bundle · they fetch on first use only.
The four plugins
Rikiki ships four optional modules. The core (dist/index.js,
~12 KB gzip) doesn't load any of them. Each one fetches separately the
first time it's needed, so a deck that doesn't use a plugin pays nothing
for it.
| Plugin | Size (gz) | Activated by | Use-case |
|---|---|---|---|
deck-transition | ~1.7 KB | transition="..." attr on deck-root | Slide-in / fade / zoom / flip animations between slides |
deck-presenter | ~2.9 KB | Press P | Speaker window with notes + next-slide preview + timer |
shiki-plugin | ~0.6 KB + Shiki from CDN | Explicit import + installShiki() | Production-grade syntax highlighting for deck-code |
deck-notes | ~0.4 KB (auto-loaded with core) | Use the deck-notes element | Speaker notes (read by deck-presenter) |
deck-transition · animations between slides
Setting a transition attribute on deck-root
triggers a lazy import of the plugin on first navigation. The plugin then
cross-fades both the outgoing and incoming slides on every navigation
(no background flash regardless of slide colors).
<!-- Set on deck-root · the entire deck animates -->
<deck-root transition="slide">
<deck-cover>...</deck-cover>
<deck-section>...</deck-section>
<deck-feature>...</deck-feature>
</deck-root> Available transitions
| Value | Effect | Default duration |
|---|---|---|
slide | Auto-directional horizontal. Forward enters from the right, backward from the left. | 560 ms |
slide-right | Same as slide but starts in the left-to-right direction (still auto-flips on backward nav). | 560 ms |
slide-up | Auto-directional vertical. Forward enters from below, backward from above. | 520 ms |
slide-down | Mirror of slide-up. | 520 ms |
fade | Soft scale-up · the default if no value matches. | 480 ms |
zoom | Aggressive scale-up with spring ease (good for hooks/punchlines). | 520 ms |
flip | 3D rotateY · subtle card-flip feel. | 560 ms |
Per-slide override
Set data-transition on any slide host to override the
deck-wide default for that slide only.
<!-- Per-slide override · data-transition wins over the parent attribute -->
<deck-root transition="fade">
<deck-cover>...</deck-cover>
<deck-section data-transition="zoom">...</deck-section>
<deck-takeaway data-transition="flip">...</deck-takeaway>
</deck-root>
All transitions are transform-only · no opacity, no background animation,
no flashing. Honours prefers-reduced-motion: reduce (animations
disable cleanly).
deck-presenter · speaker window
Press P during the talk · a popup window opens (you'll need to allow popups for the deck's origin). The window shows:
- Current slide · live mirror of what the audience sees
- Next slide · preview of what's coming
- Speaker notes · the text content of
deck-notesinside the current slide - Timer · auto-starts, pause / resume / reset buttons
- Slide counter · current / total
The popup syncs with the main deck via BroadcastChannel · no
localStorage races, no postMessage ceremony. Forward keyboard input from
the popup also drives the main deck, so you can use one laptop with the
second screen mirroring the audience view.
Speaker notes · the deck-notes element
Add deck-notes inside any slide host. The element is hidden
in the audience view (:host { display: none }) and read by
the presenter window via textContent. Free-form text · use
markdown-style bullets if you want, but it's rendered as
white-space: pre-wrap.
<deck-root>
<deck-cover>
<h1>Hello</h1>
</deck-cover>
<deck-feature>
<h1 slot="title">My slide</h1>
<p slot="lead">Audience sees this.</p>
<deck-notes>
Speaker-only text. Only visible in the presenter window.
- Bullet point one
- Pause for laughter
- Mention the rollout date
</deck-notes>
</deck-feature>
</deck-root> shiki-plugin · production code highlighting
The default deck-code highlighter is a hand-rolled regex pass
(~10 keywords per language, no template literal awareness, no JSX). Good
enough for blog snippets, brittle for serious prod code.
Opt in to Shiki when you
need real syntax highlighting · TextMate grammars, full theme set, JSX/TSX,
template literal interpolation. Shiki itself is ~300 KB · the plugin
fetches it from esm.sh on first use, so the cost is paid only
if you opt in.
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="rikiki/themes/rikiki.css">
<script type="module" src="rikiki/dist/index.js"></script>
<!-- Opt-in Shiki highlighter · pulls Shiki from esm.sh on first highlight -->
<script type="module">
import { installShiki } from './rikiki/dist/shiki-plugin.js';
await installShiki({
theme: 'one-dark-pro',
langs: ['ts', 'tsx', 'html', 'css', 'json'],
});
</script>
</head>
<body>
<deck-root>
<deck-feature>
<h1 slot="title">Real syntax</h1>
<deck-code lang="ts" hero>
const fn = <T,>(x: T): T => x;
</deck-code>
</deck-feature>
</deck-root>
</body>
</html>
After install, every existing and future deck-code instance
re-renders through Shiki. Languages that aren't loaded fall back to the
regex highlighter so the deck never breaks.
Cost model
Plugin costs are paid only when you opt in:
- A deck without
transitionon its root never fetchesdeck-transition.js. - A deck without an
installShiki()call never fetches Shiki. - Speaker who never presses P never fetches
deck-presenter.js. deck-notesships with the core (0.4 KB) but if you don't use the element, it's just one unused custom-element registration.
Core (dist/index.js) stays at ~12 KB gzip regardless of which
plugins your deck eventually uses.