Version: 0.1.0 (Draft) Date: 2026-03-13 Status: Specification
ReefDeck is a developer-first, professional-grade slide deck engine that renders presentations from structured configuration (YAML frontmatter or JSON). Built with Bun + React, it offers a CLI workflow, live preview, advanced animations, and export to static HTML, PDF, and Google Slides.
Unique differentiators:
- Dual config format (YAML frontmatter + JSON)
- MCP tool integration for AI-assisted deck creation
- Google Slides export via Workspace API
- Professional light/dark themes with full customisation
- Agent guide exposed as MCP tool for LLM discoverability
| Framework | Language | Config | Themes | Export | Agent Support |
|---|---|---|---|---|---|
| Reveal.js | JS | HTML/Markdown | ✅ | HTML/PDF | ❌ |
| Slidev | Vue | Markdown/YAML | ✅ | HTML/PDF/SPA | ❌ |
| MDX Deck | React | MDX | HTML | ❌ | |
| Spectacle | React | JSX | HTML | ❌ | |
| Marp | JS | Markdown | ✅ | HTML/PDF/PPTX | ❌ |
| Fusuma | React | MDX | HTML/PDF | ❌ | |
| ReefDeck | React/Bun | YAML/JSON | ✅ Full | HTML/PDF/GSlides | ✅ MCP |
Unoccupied niche: No framework combines React + JSON/frontmatter config + professional theming + Google Slides export + MCP agent discoverability.
Patterns extracted from IndyDevDan's presentations (Agentic Engineer course, conference talks):
| Pattern | Description |
|---|---|
| Hero Title | Full-bleed title slide with gradient background, large typography, subtle particle animation |
| Code Walkthrough | Side-by-side code + explanation, syntax highlighting, line-by-line reveal |
| Comparison Table | 2-3 column feature comparison with checkmarks/crosses, animated row reveals |
| Architecture Diagram | Box-and-arrow diagrams with animated connection lines |
| Terminal Demo | Fake terminal with typed commands and output reveal |
| Exponential Curve | Animated chart showing growth/scaling curves |
| Directory Tree | Animated file tree expansion showing project structure |
| Quote Highlight | Large quote with attribution, fade-in animation |
| Stats Dashboard | Key metrics in large numbers with count-up animation |
| Before/After | Split-screen comparison with slide-in transition |
| Timeline | Horizontal/vertical timeline with milestone markers |
| Video Embed | Inline video with custom controls and chapter markers |
| Icon Grid | Grid of icons with labels, staggered fade-in |
| Bullet Cascade | Progressive bullet reveal with slide-from-left animation |
| Call to Action | Final slide with prominent CTA button/link, QR code support |
| Layer | Technology |
|---|---|
| Runtime | Bun |
| UI Framework | React 19 |
| Styling | Tailwind CSS 4 + CSS custom properties |
| Bundler | Bun bundler |
| Animations | Framer Motion + CSS animations |
| Charts | D3.js / Recharts |
| Syntax Highlighting | Shiki |
| CLI | Commander.js |
| MCP Server | @modelcontextprotocol/sdk |
| Google Slides | Google Workspace API (slides/v1) |
reefdeck/
├── src/
│ ├── cli/ # CLI commands
│ │ ├── index.ts # Entry point
│ │ ├── init.ts # Project scaffolding
│ │ ├── dev.ts # Dev server with HMR
│ │ ├── present.ts # Presentation mode
│ │ ├── build.ts # Static export
│ │ └── export.ts # Google Slides export
│ ├── core/
│ │ ├── parser.ts # YAML/JSON config parser
│ │ ├── schema.ts # Zod validation schemas
│ │ ├── deck.ts # Deck model
│ │ └── slide.ts # Slide model
│ ├── components/
│ │ ├── Deck.tsx # Root deck component
│ │ ├── Slide.tsx # Slide container
│ │ ├── slides/ # Slide type components
│ │ │ ├── HeroSlide.tsx
│ │ │ ├── CodeSlide.tsx
│ │ │ ├── ComparisonSlide.tsx
│ │ │ ├── DiagramSlide.tsx
│ │ │ ├── TerminalSlide.tsx
│ │ │ ├── ChartSlide.tsx
│ │ │ ├── TimelineSlide.tsx
│ │ │ ├── QuoteSlide.tsx
│ │ │ ├── StatsSlide.tsx
│ │ │ ├── SplitSlide.tsx
│ │ │ ├── GridSlide.tsx
│ │ │ ├── MediaSlide.tsx
│ │ │ └── CTASlide.tsx
│ │ ├── animations/ # Animation components
│ │ │ ├── FadeIn.tsx
│ │ │ ├── SlideIn.tsx
│ │ │ ├── TypeWriter.tsx
│ │ │ ├── CountUp.tsx
│ │ │ ├── DrawLine.tsx
│ │ │ ├── Cascade.tsx
│ │ │ ├── Morph.tsx
│ │ │ └── Particles.tsx
│ │ ├── layout/ # Layout primitives
│ │ │ ├── Stack.tsx
│ │ │ ├── Split.tsx
│ │ │ ├── Grid.tsx
│ │ │ ├── Center.tsx
│ │ │ ├── Cover.tsx
│ │ │ └── Sidebar.tsx
│ │ ├── data/ # Data visualisation
│ │ │ ├── BarChart.tsx
│ │ │ ├── LineChart.tsx
│ │ │ ├── PieChart.tsx
│ │ │ ├── TreeMap.tsx
│ │ │ ├── Table.tsx
│ │ │ └── DirectoryTree.tsx
│ │ └── media/ # Media components
│ │ ├── CodeBlock.tsx
│ │ ├── Image.tsx
│ │ ├── Video.tsx
│ │ ├── QRCode.tsx
│ │ ├── Icon.tsx
│ │ └── Terminal.tsx
│ ├── themes/
│ │ ├── base.ts # Base theme tokens
│ │ ├── light.ts # Professional light theme
│ │ ├── dark.ts # Professional dark theme
│ │ └── custom.ts # Custom theme loader
│ ├── export/
│ │ ├── html.ts # Static HTML export
│ │ ├── pdf.ts # PDF export (via Puppeteer)
│ │ └── google-slides.ts # Google Slides API export
│ ├── mcp/
│ │ ├── server.ts # MCP server
│ │ └── agent-guide.ts # Agent guide tool
│ └── utils/
│ ├── transitions.ts # Slide transitions
│ ├── shortcuts.ts # Keyboard shortcuts
│ └── notes.ts # Speaker notes
├── templates/ # Starter templates
│ ├── minimal/
│ ├── tech-talk/
│ ├── pitch-deck/
│ └── workshop/
├── docs/
│ ├── user-guide.md # User documentation
│ └── agent-guide.md # Agent/LLM documentation
├── package.json
├── bunfig.toml
└── tsconfig.json
---
title: "My Presentation"
author: "Jane Doe"
date: "2026-03-13"
theme: dark
aspectRatio: "16:9"
transition: slide
fonts:
heading: "Inter"
body: "Inter"
code: "JetBrains Mono"
colors:
primary: "#6366f1"
secondary: "#8b5cf6"
accent: "#06b6d4"
---
# Welcome to ReefDeck
<!-- slide: hero -->
<!-- animation: fadeIn -->
<!-- background: gradient(135deg, #1e1b4b, #312e81) -->
---
## Architecture Overview
<!-- slide: diagram -->
<!-- animation: drawLine -->
```mermaid
graph LR
A[Config] --> B[Parser]
B --> C[Renderer]
C --> D[Output]| Metric | Value |
|---|---|
| Build Time | 1.2s |
| Bundle Size | 45KB |
| Lighthouse | 100 |
### 4.2 JSON Configuration
```json
{
"meta": {
"title": "My Presentation",
"author": "Jane Doe",
"theme": "dark",
"aspectRatio": "16:9",
"transition": "slide"
},
"theme": {
"fonts": {
"heading": "Inter",
"body": "Inter",
"code": "JetBrains Mono"
},
"colors": {
"primary": "#6366f1",
"secondary": "#8b5cf6",
"accent": "#06b6d4"
}
},
"slides": [
{
"type": "hero",
"title": "Welcome to ReefDeck",
"subtitle": "Professional slide decks, engineered.",
"animation": "fadeIn",
"background": {
"type": "gradient",
"value": "135deg, #1e1b4b, #312e81"
}
},
{
"type": "code",
"title": "Quick Start",
"language": "bash",
"code": "bunx reefdeck init my-deck\ncd my-deck\nbunx reefdeck dev",
"animation": "typeWriter",
"highlights": [1, 3]
},
{
"type": "comparison",
"title": "ReefDeck vs Others",
"columns": [
{ "header": "Feature", "items": ["React", "Themes", "GSlides Export", "MCP"] },
{ "header": "ReefDeck", "items": ["✅", "✅", "✅", "✅"] },
{ "header": "Slidev", "items": ["❌ (Vue)", "✅", "❌", "❌"] },
{ "header": "Reveal.js", "items": ["❌", "✅", "❌", "❌"] }
],
"animation": "cascade"
},
{
"type": "chart",
"title": "Adoption Growth",
"chartType": "line",
"data": {
"labels": ["Jan", "Feb", "Mar", "Apr"],
"datasets": [{ "label": "Users", "values": [100, 450, 1200, 3500] }]
},
"animation": "drawLine"
},
{
"type": "cta",
"title": "Get Started Today",
"buttons": [
{ "label": "GitHub", "url": "https://github.com/reefdeck" },
{ "label": "Docs", "url": "https://reefdeck.dev/docs" }
],
"qrCode": "https://reefdeck.dev"
}
]
}
| Type | Description | Key Props |
|---|---|---|
hero |
Full-bleed title slide | title, subtitle, background, logo |
content |
Standard content slide | title, body (markdown), columns |
code |
Code showcase with highlighting | language, code, highlights, lineNumbers |
comparison |
Multi-column comparison table | columns[], highlightColumn |
diagram |
Architecture/flow diagrams | mermaid or nodes[] + edges[] |
terminal |
Simulated terminal | commands[], prompt, outputDelay |
chart |
Data visualisation | chartType, data, options |
timeline |
Event timeline | events[], orientation |
quote |
Highlighted quotation | quote, author, role, avatar |
stats |
Key metrics dashboard | metrics[] (label + value + delta) |
split |
Two-pane layout | left, right, ratio |
grid |
Icon/card grid | items[], columns, gap |
media |
Image/video showcase | src, type, caption, fit |
cta |
Call to action | buttons[], qrCode, links[] |
| Animation | Description | Props |
|---|---|---|
fadeIn |
Opacity transition | duration, delay, direction |
slideIn |
Directional slide entry | from (left/right/top/bottom), duration |
typeWriter |
Character-by-character reveal | speed, cursor, startDelay |
countUp |
Numeric count animation | from, to, duration, format |
drawLine |
SVG path drawing | duration, strokeWidth, color |
cascade |
Staggered child reveals | stagger, direction, animation |
morph |
Shape/text morphing between slides | targets[] |
particles |
Background particle system | count, speed, color, shape |
| Layout | Description |
|---|---|
Stack |
Vertical stack with gap |
Split |
Horizontal split with ratio |
Grid |
CSS grid with columns/rows |
Center |
Centered content (horizontal + vertical) |
Cover |
Full-bleed background with overlay |
Sidebar |
Content + sidebar layout |
| Component | Description |
|---|---|
BarChart |
Horizontal/vertical bar charts |
LineChart |
Line/area charts with interpolation |
PieChart |
Pie/donut charts |
TreeMap |
Hierarchical treemap |
Table |
Styled data tables with sorting |
DirectoryTree |
Animated file/folder tree |
| Component | Description |
|---|---|
CodeBlock |
Syntax-highlighted code with Shiki |
Image |
Responsive images with fit modes |
Video |
Inline video with custom controls |
QRCode |
Generated QR codes |
Icon |
Icon library (Lucide/Heroicons) |
Terminal |
Terminal emulator with typed output |
interface ThemeTokens {
colors: {
primary: string;
secondary: string;
accent: string;
background: string;
surface: string;
text: string;
textMuted: string;
border: string;
error: string;
success: string;
warning: string;
};
fonts: {
heading: string;
body: string;
code: string;
};
fontSizes: {
xs: string; sm: string; md: string;
lg: string; xl: string; '2xl': string;
'3xl': string; '4xl': string; '5xl': string;
};
spacing: Record<string, string>;
radii: Record<string, string>;
shadows: Record<string, string>;
transitions: {
default: string;
fast: string;
slow: string;
};
}Light Theme: Clean white background, subtle shadows, dark text, blue-indigo accent palette.
Dark Theme: Deep navy/slate background, subtle borders, light text, indigo-violet accent palette.
Users can extend or fully override themes via:
- Inline config: Override tokens in deck YAML/JSON
- Theme file:
theme.tsexportingThemeTokens - CSS custom properties: Override
--rd-*variables
reefdeck <command> [options]
Commands:
init <name> Scaffold a new deck project
dev Start dev server with HMR (default: port 3000)
present Launch presentation mode (fullscreen, speaker notes)
build Export to static HTML
export <format> Export to format (html | pdf | gslides)
Options:
--port <number> Dev server port (default: 3000)
--theme <name> Override theme (light | dark | <custom>)
--config <path> Config file path (default: ./deck.yaml or ./deck.json)
--output <dir> Output directory (default: ./dist)
--watch Watch for changes (dev mode)
Examples:
bunx reefdeck init my-talk
bunx reefdeck dev --port 8080
bunx reefdeck build --output ./public
bunx reefdeck export pdf --output ./my-talk.pdf
bunx reefdeck export gslides --credentials ./gcloud-creds.json
| Key | Action |
|---|---|
→ / Space |
Next slide |
← / Backspace |
Previous slide |
f |
Toggle fullscreen |
s |
Toggle speaker notes |
o |
Slide overview grid |
d |
Toggle dark/light theme |
g + number |
Go to slide N |
Escape |
Exit presentation mode |
- Self-contained single HTML file with inlined CSS/JS
- All assets base64-encoded or bundled
- Keyboard navigation preserved
- Progressive enhancement (works without JS for basic viewing)
- Via Puppeteer headless rendering
- Each slide = one page
- Preserves layout, fonts, colours
- Animations rendered as final state
- Via Google Slides API (slides/v1)
- Maps slide types to Google Slides layouts
- Preserves text, colours, basic shapes
- Charts exported as images
- Requires OAuth2 credentials
Mapping strategy:
| ReefDeck | Google Slides |
|---|---|
hero |
Title Slide layout |
content |
Title and Body layout |
code |
Blank + text box (monospace) |
comparison |
Table element |
chart |
Embedded image |
quote |
Blank + styled text boxes |
split |
Two Content layout |
media |
Blank + image element |
The MCP server exposes a reefdeck_guide tool that returns comprehensive documentation for AI agents, enabling them to create decks programmatically.
// MCP tool registration
{
name: "reefdeck_guide",
description: "Returns the ReefDeck agent guide with schema documentation, slide types, animation options, and example configurations for creating professional slide decks.",
inputSchema: {
type: "object",
properties: {
section: {
type: "string",
enum: ["overview", "slide-types", "animations", "themes", "examples", "full"],
description: "Which section of the guide to return"
}
}
}
}You have access to ReefDeck for creating professional slide decks.
Use the reefdeck_guide tool to learn the configuration schema.
To create a deck:
1. Call reefdeck_guide with section="full" to learn available options
2. Generate a valid deck configuration (YAML or JSON)
3. Write the config to a .yaml or .json file
4. The user can render it with `bunx reefdeck dev`
Key principles:
- Each slide needs a `type` (hero, code, comparison, chart, etc.)
- Animations are optional but enhance engagement
- Use the theme system for consistent branding
- Keep slides focused — one idea per slide
# Install
bun add -g reefdeck
# Create a new deck
bunx reefdeck init my-presentation
cd my-presentation
# Start dev server
bunx reefdeck dev
# Build for production
bunx reefdeck buildmy-presentation/
├── deck.yaml # or deck.json — slide configuration
├── theme.ts # optional custom theme
├── assets/ # images, videos, etc.
└── dist/ # build output
Add notes below each slide separator:
---
# Slide Title
Content here
<!-- notes: Remember to demo the live preview feature -->
---- Project scaffolding (Bun + React + Tailwind)
- Config parser (YAML + JSON, Zod validation)
- Core slide types: hero, content, code, comparison, split
- Base theme system (light + dark)
- CLI:
init,dev(with HMR) - Keyboard navigation + fullscreen
- Remaining slide types: diagram, terminal, chart, timeline, quote, stats, grid, media, cta
- All 8 animation components
- Chart integration (Recharts/D3)
- Terminal emulator component
- Mermaid diagram rendering
- Speaker notes + presenter view
- Custom theme loader
- CLI:
present,build
- Static HTML export (self-contained)
- PDF export via Puppeteer
- Google Slides API integration
- MCP server + agent guide tool
- Starter templates (minimal, tech-talk, pitch-deck, workshop)
- Documentation (user guide + agent guide)
- npm package publishing
- Mermaid support: Bundle mermaid.js or render server-side to SVG?
- Plugin system: Should ReefDeck support custom slide type plugins?
- Collaborative editing: Real-time collaboration via WebSocket?
- Version control: Git-friendly diffing of deck configs?
- Presenter remote: Mobile device as presentation remote?
| Metric | Target |
|---|---|
| Cold start (dev server) | < 500ms |
| HMR update | < 100ms |
| Static HTML bundle size | < 100KB (base) |
| Google Slides export fidelity | > 85% visual match |
| Lighthouse score (exported HTML) | 95+ |
| Time to first deck (new user) | < 5 minutes |
Specification prepared by J.A.R.V.I.S. — 2026-03-13 Based on competitive analysis of 12 frameworks and pattern extraction from IndyDevDan presentations