LLM-friendly JSON-based presentation engine that renders beautiful, interactive presentations using Reveal.js.
Enable AI agents and LLMs to create professional presentations by generating simple JSON files. The engine handles all the complexity of rendering, styling, animations, and interactivity.
npm install
npm run devThen open http://localhost:3000.
No install needed? Try the hosted online viewer -- paste JSON or upload a file and present directly from your browser.
The root page includes a deck loader:
- choose the folder that contains your presentation JSON and its assets
- pick the JSON file if the folder has more than one deck
- relative
image.srcandslide.backgroundpaths are resolved against that JSON file automatically
Built-in example:
http://localhost:3000/?presentation=./examples/hello-world.json
If you want a URL-backed launch flow from the terminal, use the CLI:
npm run present -- ~/slides/demo.jsonThat prints a browser URL and keeps companion presenter/audience windows available.
The engine ships an apb command (see the bin field in package.json), so it can be run
straight from this repository with bunx/npx, pinned to a release tag for reproducibility:
# Validate a deck against the JSON schema
bunx github:neuromechanist/agentic-presentation-builder#v0.1.6 validate deck.json --json
# Serve the deck on a local presentation server
bunx github:neuromechanist/agentic-presentation-builder#v0.1.6 present deck.json --open
# Export the deck (pdf default; pptx/native available)
bunx github:neuromechanist/agentic-presentation-builder#v0.1.6 export deck.json --format pdfnpx github:neuromechanist/agentic-presentation-builder#v0.1.6 <command> works the same way.
The three subcommands (validate, present, export) are the same code paths as the
bun run <name> scripts; apb <command> --help prints each command's full option list. For
repeated authoring, clone once and run bun run validate|present|export to avoid re-resolving
the git package on every call.
Export a deck directly from the terminal:
npm run export -- examples/hello-world.json
npm run export -- examples/hello-world.json --format pptx
npm run export -- examples/hello-world.json --format pptx --pptx-mode=imagepdfis the default format and preserves the rendered deck through headless Chrome print exportpptx(default mode: native) converts each slide to real PowerPoint objects: editable text, bullets with nesting, images, callout shapes, code blocks, tables, and speaker notes. Mermaid diagrams are rendered to PNG via headless Chrome and embedded as images. Font sizes scale proportionally to available space so content does not overflow--pptx-mode=imagefalls back to the legacy screenshot-based export (one rendered PNG per slide)--output <path>chooses the destination file--chrome-path <path>points to a non-standard Chrome or Edge binary
Native ODP export is not implemented yet. The practical path today is JSON -> PPTX -> ODP using LibreOffice or another office suite that imports PowerPoint decks.
Limitations of native PPTX mode:
- Reveal.js fragment animations are not yet mapped to PowerPoint entrance effects (planned for a future release)
- Mermaid diagrams require a Chrome-compatible browser for rendering; without one they appear as source code placeholders
- Custom theme fonts are not embedded in the PPTX; the viewer machine needs the fonts installed
This repository now ships a full MkDocs Material documentation site under docs/.
# Preview the docs locally with uv
npm run docs:serve
# Build the docs site
npm run docs:buildKey pages:
docs/index.mdfor the product overviewdocs/getting-started.mdfor first-run setupdocs/local-decks.mdfor opening decks directly from your computerdocs/json-authoring.mdfor the JSON contract and authoring patternsdocs/agent-workflow.mdfor validation, warnings, audit, and browser automationdocs/presenting.mdfor presentation, presenter, and audience modesdocs/schema-reference.mdfor field-level reference
Use the repository in two passes when an agent is iterating on a deck:
npm run validate -- examples/image-demo.json --jsonThis returns machine-readable schema errors and author warnings with code, path, message, and suggestion.
Then open the deck in a browser and read:
window.__presentationValidationfor the same validation payload available from the CLIwindow.__presentationAuditfor rendered slide-fit findingswindow.__presentationAgentReportfor both in one object
The browser audit contains per-slide fitScore, fitSeverity, layoutFindings, authorWarnings, and recommendations based on the actual rendered layout at presentation size.
7 Element Types: Text • Bullets • Images • Mermaid Diagrams • Callouts • Code Blocks • Tables
Layouts: 4 layout types (single-column, two-column, title, blank) with flexible positioning
Animations: Progressive reveal system with 5 animation types + fragment ordering
Transitions: 5 slide transitions (slide, fade, convex, concave, zoom)
Themes: 5 built-in + custom themes with colors and fonts
Navigation: Keyboard, touch, overview mode (Escape), presenter view (S)
Single slide presentation:
{
"presentation": {
"metadata": {
"title": "Hello World",
"theme": "default"
},
"slides": [
{
"title": "Welcome",
"layout": "title",
"elements": [
{
"type": "text",
"content": "# Hello World\nWelcome to Agentic Presentation Builder",
"style": { "fontSize": "xxl", "alignment": "center" },
"position": { "area": "center" }
}
]
}
]
}
}View it in one of two ways:
- open
http://localhost:3000and use the local deck loader - or use
http://localhost:3000/?presentation=./examples/your-file.jsonfor URL-backed decks
- Arrow keys / Space: Navigate slides
- Escape: Toggle overview mode (grid view with slide titles)
- S: Open presenter view
- F: Fullscreen
examples/hello-world.json- Minimal structureexamples/advanced-features-demo.json- All features showcase
{
"type": "text",
"content": "# Heading\nThis is **bold** and *italic* text",
"style": {
"fontSize": "large",
"alignment": "center",
"color": "#1E293B",
"fontWeight": "bold"
},
"position": {
"area": "header",
"order": 0
},
"animation": {
"fragment": true,
"type": "fade",
"index": 0
}
}Font Sizes: small, medium, large, xl, xxl
Alignment: left, center, right, justify
Font Weight: normal, bold, light
{
"type": "bullets",
"items": [
{
"text": "First reveal",
"animation": { "fragment": true, "type": "fade", "index": 0 }
},
{
"text": "Parent item",
"animation": { "fragment": true, "type": "slide-up", "index": 1 },
"children": ["Nested item 1", "Nested item 2"]
}
],
"bulletStyle": "disc",
"style": { "fontSize": "medium" }
}Bullet Styles: disc, circle, square, number, none
Bullet Item Animation: object items can also include animation for per-item fragments
{
"type": "image",
"src": "./images/diagram.png",
"alt": "System architecture diagram",
"width": "50%",
"height": "auto",
"caption": "**Figure 1:** System Architecture",
"position": { "area": "content" },
"animation": { "fragment": true, "type": "zoom" }
}Width/Height: Percentage (50%), pixels (400px), or auto
{
"type": "mermaid",
"diagram": "graph TD\n A[Start] --> B[Process]\n B --> C[End]",
"theme": "default",
"position": { "area": "content" }
}Themes: default, dark, forest, neutral
Diagram Types: flowcharts, sequence, Gantt, git graphs, state diagrams
{
"type": "callout",
"calloutType": "tip",
"title": "Pro Tip",
"content": "Use **keyboard shortcuts** for faster navigation",
"position": { "area": "content" },
"animation": { "fragment": true, "type": "fade" }
}Types: tip (green), warning (yellow), important (red), note (blue), info (gray)
{
"type": "code",
"code": "function hello() {\n console.log('Hello, World!');\n}",
"language": "javascript",
"caption": "example.js",
"lineNumbers": true,
"position": { "area": "content" }
}Languages: javascript, typescript, python, java, go, rust, html, css, json
{
"type": "table",
"headers": ["Name", "Age", "City"],
"rows": [
["Alice", "30", "NYC"],
["Bob", "25", "LA"]
],
"caption": "**Table 1:** User Data",
"position": { "area": "content" }
}{
"id": "unique-slide-id",
"title": "Slide Title (shown in overview)",
"layout": "single-column",
"background": "#F8FAFC",
"transition": "fade",
"speakerNotes": "Remember to emphasize key points",
"elements": [...]
}Layouts:
single-column- Standard vertical layouttwo-column- Side-by-side with left/right areastitle- Centered content for title slidesblank- Custom positioning
Transitions: slide, fade, convex, concave, zoom
Position Areas:
header,content,footer(all layouts)left,right(two-column only)center(title layout)
{
"presentation": {
"metadata": {
"title": "Presentation Title",
"author": "Author Name",
"description": "Brief description",
"theme": "default",
"aspectRatio": "16:9",
"controls": {
"slideNumbers": true,
"progress": true,
"showNotes": false
},
"customTheme": {
"colors": {
"primary": "#2563EB",
"background": "#FFFFFF",
"text": "#1E293B",
"accent": "#10B981"
},
"fonts": {
"heading": "Inter, sans-serif",
"body": "Inter, sans-serif"
}
}
},
"slides": [...]
}
}Built-in Themes: default, light, dark, academic, minimal
Aspect Ratios: 16:9, 4:3
{
"elements": [
{
"type": "text",
"content": "First (appears immediately)",
"animation": { "fragment": false }
},
{
"type": "bullets",
"items": ["Second (appears on click)"],
"animation": {
"fragment": true,
"type": "fade",
"index": 0
}
},
{
"type": "text",
"content": "Third (appears after bullets)",
"animation": {
"fragment": true,
"type": "slide-up",
"index": 1
}
}
]
}Supported Fragment Targets:
- whole
text,bullets,image,mermaid,callout,code, andtableelements - individual bullet items via object entries in
bullets.items
Animation Types:
fade- Fade inslide-up- Slide up from bottomslide-down- Slide down from topzoom- Zoom innone- No animation
Fragment Rules:
fragment: false→ appears immediatelyfragment: true→ appears on click/spaceindexcontrols order (0, 1, 2, ...)- Multiple elements can share same index (appear together)
code,callout, and individual bullet items support fragment animation
Per-Item Bullet Example:
{
"type": "bullets",
"items": [
{ "text": "Step 1", "animation": { "fragment": true, "index": 0 } },
{ "text": "Step 2", "animation": { "fragment": true, "index": 1 } }
]
}# Validate a specific file
node scripts/validate.js examples/your-presentation.json
# Or use npm command
npm run validate examples/your-presentation.jsonMissing Required Fields:
Error: Missing required field: title
Fix: Add "title" to metadata
Invalid Enum Value:
Error: Invalid value. Must be one of: fade, slide, convex, concave, zoom
Fix: Use one of the allowed transition types
Type Mismatch:
Error: Expected boolean but got string
Fix: Change "slideNumbers": "true" to "slideNumbers": true
Invalid Color Format:
Error: Value does not match required format (e.g., hex color: #FFFFFF)
Fix: Use proper hex format: "#1E293B" not "blue"
Required Fields:
- ✅
presentation.metadata.titleexists - ✅
presentation.slidesarray has ≥ 1 slide - ✅ Each slide has
elementsarray - ✅ Each element has
typeand required fields
Valid Values:
- ✅ Theme:
default,light,dark,academic,minimal - ✅ Layout:
single-column,two-column,title,blank - ✅ Transition:
slide,fade,convex,concave,zoom - ✅ Colors: hex format
#RRGGBBor#RGB - ✅ Font sizes:
small,medium,large,xl,xxl
Element-Specific:
- ✅ Text/Bullets:
content/itemsnot empty - ✅ Image:
srcis valid path/URL - ✅ Code:
codenot empty,languagesupported - ✅ Table:
headersandrowsnot empty - ✅ Mermaid:
diagramhas valid syntax
Animation:
- ✅ Fragment indices are integers ≥ 0
- ✅ Animation type is valid
import {
validatePresentation,
getValidationReport,
} from "./src/validator/index.js";
const presentation = {
/* your JSON */
};
// Get validation result
const result = validatePresentation(presentation);
if (result.valid) {
console.log("Valid!");
} else {
console.error("Errors:", result.errors);
}
// Get human-readable report
console.log(getValidationReport(presentation));Schema Location: schema/presentation.schema.json (JSON Schema Draft-07 with Ajv validation)
npm install # Install dependencies
npm run dev # Start dev server (http://localhost:3000)
npm run build # Build for production
npm test # Run tests
npm run validate # Validate presentation file
npm run present # Serve a deck on a local presentation server
npm run export # Export a deck (pdf/pptx)The same validate / present / export commands are exposed as the apb CLI for
bunx/npx use without a clone (see Quick Start).
bin/apb.js dispatches to the main() exported from scripts/{validate,present,export}.js,
so both invocation styles share one code path.
agent-presentation/
├── src/
│ ├── parser/ # JSON to structured data
│ ├── renderer/ # Structured data to HTML
│ ├── validator/ # JSON schema validation
│ ├── utils/ # Markdown, theme utilities
│ ├── app.js # Client-side application
│ └── styles.css # Custom styles
├── examples/ # Example presentations
├── schema/ # JSON schema definition
├── scripts/ # Validation scripts
└── index.html # HTML template
- Chrome/Edge 90+
- Firefox 88+
- Safari 14+
- Mobile browsers with touch support
- Reveal.js - Presentation framework
- Mermaid.js - Diagram rendering
- Prism.js - Syntax highlighting
- Marked.js - Markdown parsing
- Ajv - JSON schema validation
- Vite - Build tool and dev server
This project follows atomic commit practices:
- Each commit = single logical change
- Clear, descriptive commit messages
- Test changes before committing
- See
.rules/git.mdfor guidelines
This project is licensed under the BSD 3-Clause License. See LICENSE for the full text.