@paperjsx/json-to-pptx
v0.2.4
Published
Generate PowerPoint files from JSON (free, Apache-2.0)
Maintainers
Readme
@paperjsx/json-to-pptx
Generate native PowerPoint .pptx files from JSON or TypeScript. No browser, no headless Chromium, no conversion from HTML — real OOXML straight to a buffer.
npm install @paperjsx/json-to-pptxRequires Node.js >=20. ESM only.
Quick Start
import { PaperEngine } from "@paperjsx/json-to-pptx";
import { writeFileSync } from "node:fs";
const buffer = await PaperEngine.render({
type: "Document",
meta: { title: "Quarterly Update" },
slides: [
{
type: "Slide",
style: { padding: 40, backgroundColor: "#FFFFFF" },
children: [
{
type: "Text",
content: "Quarterly Update",
style: { fontSize: 28, fontWeight: "bold", color: "#1E293B" },
},
{
type: "Text",
content: "Revenue grew 28% year over year.",
style: { marginTop: 12, fontSize: 18, color: "#334155" },
},
],
},
],
});
writeFileSync("deck.pptx", buffer);Output opens natively in PowerPoint, Keynote, Google Slides, and LibreOffice Impress — no compatibility layer.
Fonts and Layout Drift
Embed your fonts or accept metric drift.
PowerPoint layouts depend on text metrics. If your render environment measures one font and the viewer substitutes another, line wraps, chart labels, and card copy can shift. The reliable path is to load or embed the exact fonts you plan to ship.
import { PaperEngine, loadFont } from "@paperjsx/json-to-pptx";
import { readFileSync, writeFileSync } from "node:fs";
loadFont("Inter", readFileSync("./fonts/Inter-Regular.ttf"));
const doc = {
type: "Document",
meta: { title: "Font-safe deck" },
slides: [
{
type: "Slide",
children: [
{
type: "Text",
content: "Measured with Inter",
style: { fontFamily: "Inter", fontSize: 28, color: "#0F172A" },
},
],
},
],
};
const buffer = await PaperEngine.render(doc);
writeFileSync("font-safe-deck.pptx", buffer);If you are drafting quickly and do not want to ship custom font files, prefer Liberation Sans or DejaVu Sans. They are the safest no-embed choices for LibreOffice-heavy CI and Linux preview environments.
What You Get
- Native PPTX output — real ECMA-376 OOXML, not an image export or HTML conversion.
- Flexbox layout — Yoga-powered layout engine for rows, columns, gaps, padding, and alignment. Write layout with familiar flex primitives.
- Editable charts — bar, line, pie, scatter, area, combo. Rendered as real chart XML with embedded Excel data, so users can edit the underlying values in PowerPoint.
- 40+ shapes — rectangles, ellipses, arrows, callouts, flowchart primitives, stars, connectors, custom geometry.
- Tables — header rows, cell spans, per-cell styling, row/column sizing.
- Typography — fontkit-based text measurement, line breaking, bullet lists, multi-run paragraphs, tab stops.
- Diagrams — cycle, hierarchy, matrix, process, list, venn (SmartArt-style, 6 generator types).
- Semantic compiler — high-level
AgentDocumentschema (KPIs, data series, slide patterns) that compiles to the full layout engine — a fast path for LLM agents. - Deterministic output — same input, identical bytes. Safe for content-addressable caching and visual regression.
Feature Matrix
| Capability | Free (json-to-pptx) | Pro (json-to-pptx-pro) |
| --------------------------- | :-------------------: | :----------------------: |
| Document generation | ✔ | ✔ |
| 40+ shapes | ✔ | ✔ |
| 140+ shapes | | ✔ |
| 6 basic chart types | ✔ | ✔ |
| 9 advanced chart types | | ✔ |
| Flexbox layout (Yoga) | ✔ | ✔ |
| Text measurement (fontkit) | ✔ | ✔ |
| Complex text shaping (HarfBuzz, RTL, emoji) | | ✔ |
| .potx template ingestion | | ✔ |
| Canvas preview renderer | | ✔ |
| Semantic interpreter | ✔ | ✔ |
| Tables, diagrams, animations | ✔ | ✔ |
| Production / self-hosted commercial license | | ✔ |
See paperjsx.com/pricing for Pro licensing and hosted usage.
Verified Schema
The canonical PPTX input surfaces are generated from the exported Zod schemas instead of being maintained by hand:
- Schema reference:
docs/schema-reference.md - Verified examples:
docs/examples.md
The generated reference covers both the full PaperDocument AST and the higher-level AgentDocument fast path. Every element still uses a type discriminator such as View, Text, Image, Table, Chart, Shape, Group, Connector, Video, or Audio, and styles follow flexbox semantics (flexDirection, gap, padding, alignItems, justifyContent).
Validate untrusted input against the Zod schema before rendering:
import { PaperDocumentSchema } from "@paperjsx/json-to-pptx";
const parsed = PaperDocumentSchema.parse(inputJson);
const buffer = await PaperEngine.render(parsed);Charts
{
type: "Chart",
style: { width: 720, height: 360 },
chartData: {
chartType: "bar",
series: [
{ name: "2025", values: [120, 140, 180, 210] },
{ name: "2026", values: [160, 185, 235, 280] },
],
categories: ["Q1", "Q2", "Q3", "Q4"],
axes: { x: { title: "Quarter" }, y: { title: "Revenue ($K)" } },
},
}Supported types (free tier): bar, line, pie, scatter, area, combo. Output is editable in PowerPoint with the source data in an embedded workbook.
Agent Mode
The semantic compiler accepts a compact AgentDocument — ideal when an LLM is producing the content:
import {
compileAgentDocument,
PaperEngine,
} from "@paperjsx/json-to-pptx";
const agentDoc = {
type: "presentation",
version: "1.0",
presentationTitle: "Revenue Dashboard",
companyName: "Acme Cloud",
theme: "editorial-serif",
designTokens: {
colors: { accent: "#C2410C" },
typography: { heroTitleSize: 40 },
},
slides: [
{
pattern: "title",
content: {
title: "Revenue Dashboard",
subtitle: "Board update for Q2",
},
},
{
pattern: "dashboard",
content: {
title: "Key Metrics",
subtitle: "Quarter to date",
kpis: [
{ label: "ARR", value: "$12.4M", trend: "up", sublabel: "+41% YoY" },
{ label: "NRR", value: "118%", trend: "up", sublabel: "+4 pts" },
],
chart: {
type: "bar",
title: "MRR by quarter",
series: [
{
name: "MRR",
dataPoints: [
{ category: "Q1", value: 820 },
{ category: "Q2", value: 880 },
{ category: "Q3", value: 940 },
{ category: "Q4", value: 1020 },
],
},
],
},
},
},
],
};
const paperDoc = compileAgentDocument(agentDoc);
const buffer = await PaperEngine.render(paperDoc);Built-in presets: default-navy, editorial-serif, monochrome, dark-punch, midnight, terminal, editorial-wide.
designTokens is optional and can partially override colors, typography, layout, or effect tokens on top of a preset.
For broader visual steering, use the top-level coupled controls designTokens.scale, designTokens.density, and designTokens.shape before reaching for individual atomic overrides.
compileAgentDocument(agentDoc, { layoutValidation: "warn" | "error" | "off" }) adds a synchronous sanity pass for obvious overflow, clipping, and collision risk. Use "error" in CI when you want risky decks to fail before render.
Slide patterns: title, statement, dashboard, comparison, chart-focus, bullets.
For a modern starting point, use one of the three modern presets — midnight, terminal, or editorial-wide — with the same minimal three-token surface:
import {
compileAgentDocument,
PaperEngine,
} from "@paperjsx/json-to-pptx";
const buffer = await PaperEngine.render(
compileAgentDocument({
type: "presentation",
version: "1.0",
presentationTitle: "Midnight Brief",
theme: "midnight",
designTokens: {
scale: "lg",
density: "spacious",
shape: "round",
},
slides: [
{
pattern: "title",
content: {
title: "Midnight Brief",
subtitle: "Modern preset baseline",
},
},
],
}),
);Agent Font Strategy
Agent mode can bias toward safe system fonts when you want drafts to survive cross-viewer rendering without bundling font files:
import {
compileAgentDocument,
PaperEngine,
} from "@paperjsx/json-to-pptx";
const agentDoc = {
type: "presentation",
version: "1.0",
presentationTitle: "System-safe Draft",
designTokens: {
typography: {
fontStrategy: "system-safe",
},
},
slides: [
{
pattern: "title",
content: {
title: "System-safe Draft",
subtitle: "Uses Liberation Sans with deterministic fallbacks",
},
},
],
};
const buffer = await PaperEngine.render(compileAgentDocument(agentDoc));Public API (selected)
// Engine
PaperEngine.render(doc, options?) // Uint8Array
RenderContext, withContext // AsyncLocalStorage-based per-request isolation
// Validation
PaperDocumentSchema, PaperSlideSchema, PaperNodeSchema // Zod schemas
AgentDocumentSchema, AgentSlideSchema
AgentThemePresetSchema, DesignTokensSchema
// Layout
runLayout(node, containerSize) // flex layout pass
calculateTextMetrics(text, style) // width/height for a run
// Semantic compilation
compileAgentDocument(agentDoc, options?)
compileAgentSlide(agentSlide)
validateAgentDocumentLayout(paperDoc)
applyElasticPagination(slide)
DEFAULT_AGENT_DESIGN_TOKENS
getAgentThemePresetTokens(theme)
resolveAgentDesignTokens(theme, accentColor, overrides)
// Diagrams
generateDiagram({ type: "cycle" | "hierarchy" | "matrix" | "process" | "list" | "venn", items })
// Fonts
loadFont(family, buffer)
autoLoadDocumentFonts(doc)
clearFontCache()
// Determinism + logging
setDeterministicMode(true)
setLogger({ debug, info, warn, error })
// Errors
PaperError, PaperJSXFeatureError, SchemaValidationError, PaperErrorCodeFull type surface in dist-lite/index.d.ts — every runtime export has a matching TypeScript definition.
Determinism
import { setDeterministicMode } from "@paperjsx/json-to-pptx";
setDeterministicMode(true);Freezes timestamps, rIDs, and any other sources of nondeterminism. Use in CI for byte-stable snapshot testing.
Error Handling
Rendering throws PaperError (with .code and .phase) for known failure modes and PaperJSXFeatureError when a pro-only feature is requested on the free build. Validation throws SchemaValidationError with the offending Zod path.
import { PaperError, PaperJSXFeatureError } from "@paperjsx/json-to-pptx";
try {
await PaperEngine.render(doc);
} catch (err) {
if (err instanceof PaperJSXFeatureError) {
// Feature requires @paperjsx/json-to-pptx-pro
} else if (err instanceof PaperError) {
console.error(err.code, err.phase, err.message);
}
throw err;
}Upgrade to Pro
Use @paperjsx/json-to-pptx-pro when you need:
- commercial / self-hosted production licensing
- 140+ shapes, 9 additional chart types
.potxtemplate ingestion and mutation- HarfBuzz text shaping (complex scripts, RTL, emoji)
- canvas preview rendering (PNG thumbnails)
The API is identical — swap the import and provide a license key.
Links
- Docs: paperjsx.com/docs
- Playground: paperjsx.com/playground
- Pricing: paperjsx.com/pricing
License
Apache-2.0. See LICENSE.
