Slide module exports
Everything the runtime reads from a slides/<id>/index.tsx.
import type { DesignSystem, Page, SlideMeta, SlideTransition } from '@beem-slide/core';
const Cover: Page = () => <div>{/* … */}</div>;
const Agenda: Page = () => <div>{/* … */}</div>;
export const design: DesignSystem = {
palette: { bg: '#101014', text: '#f4f2ee', accent: '#d56b48' },
fonts: { display: 'Georgia, serif', body: 'system-ui, sans-serif' },
typeScale: { hero: 168, body: 36 },
radius: 6,
};
export const meta: SlideMeta = {
title: 'Q2 launch',
createdAt: '2026-08-20T09:00:00Z',
theme: 'ink-and-rule',
};
export const notes = ['Open with the analyst quote.', undefined];
export const transition: SlideTransition = {
duration: 480,
enter: { keyframes: { opacity: [0, 1] } },
};
export default [Cover, Agenda] satisfies Page[];default — required
An array of components in display order. Non-empty; anything else is not a deck.
type Page = ComponentType & { transition?: SlideTransition };Components take no props. Each fills its container, and the runtime renders one at a time onto the 1920 × 1080 canvas.
meta
type SlideMeta = {
/** Deck title, shown in the deck list and the header. Defaults to the directory name. */
title?: string;
/** Theme id — the file name under themes/ without its extension. */
theme?: string;
/** ISO 8601 timestamp, used to sort the deck list newest-first. */
createdAt?: string;
};theme is a theme id, not a light/dark switch: 'ink-and-rule' points at
themes/ink-and-rule.md. Setting it puts a chip on the deck's card and lists
the deck under "used by" on that theme's page.
theme and createdAt must be plain string literals. Both are read by a regex
at build time rather than by evaluating the module, so a computed value —
new Date().toISOString(), a constant imported from elsewhere — reads as
absent.
design
Typed tokens the runtime turns into CSS variables at the canvas root, and the Design panel edits live. Must be a literal object — no spreads, no helper calls — because the panel writes back to it through the AST. See Themes.
notes
Speaker notes, as an array aligned index-for-index with the page array. Use
undefined for a page with no note.
export const notes: (string | undefined)[] = [
'Open with the analyst quote.',
undefined,
'Pause here for questions.',
];The dev server reads notes from slides/<id>/notes.json instead, which is what
the in-app notes editor writes. This export is what a static build falls back
to. See Present mode.
transition
One transition for the whole deck. A single page can override it by assigning
transition to the component itself, which takes precedence over the module's.
What you can import
import {
CANVAS_WIDTH, // 1920
CANVAS_HEIGHT, // 1080
ImagePlaceholder, // see /docs/reference/image-placeholder
useSlidePageNumber, // { current, total } — for a footer or folio
} from '@beem-slide/core';
import type {
Page,
SlideMeta,
SlideModule,
SlideTransition,
DesignSystem,
ImagePlaceholderProps,
} from '@beem-slide/core';