npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@paperjsx/json-to-pptx

v0.2.4

Published

Generate PowerPoint files from JSON (free, Apache-2.0)

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 license

npm install @paperjsx/json-to-pptx

Requires 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 AgentDocument schema (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:

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, PaperErrorCode

Full 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
  • .potx template 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

License

Apache-2.0. See LICENSE.