deckforge
v0.3.0
Published
Convert HTML pages to PPTX presentations using a Chromium-based pipeline
Maintainers
Readme
deckforge
A TypeScript library that converts HTML pages into PowerPoint (PPTX) presentations. It uses a Chromium-based pipeline via Playwright to render HTML, then extracts all visual content — text, images, tables, charts, canvases, iframes — and reconstructs them as native PPTX elements.
Published on npm as
deckforge.
Features
- Pixel-perfect conversion — renders HTML in headless Chromium, capturing the exact visual output
- Native PPTX elements — text boxes, tables, and images are converted to editable PowerPoint objects (not just screenshots)
- Smart text extraction — inline-flow text merging, character-type segmentation (Latin/CJK/emoji/math), and per-character font resolution
- Font embedding — 128 bundled Google Font families automatically embedded for cross-system consistency
- Table support — HTML tables converted to native PPTX tables with cell styles, borders, and padding
- Chart.js detection — automatically detects and captures Chart.js charts
- Canvas & iframe support — extracts content from
<canvas>elements and iframes - Configurable viewport — default 1280×720 (16:9), fully customizable
Installation
npm install deckforgeQuick Start
import { convertToPptx } from 'deckforge';
import { writeFile } from 'fs/promises';
const pptxBuffer = await convertToPptx([
'/path/to/slide1.html',
'/path/to/slide2.html',
]);
await writeFile('presentation.pptx', pptxBuffer);API
convertToPptx(htmlPaths, options?)
Converts one or more HTML files into a single PPTX file. Each HTML file becomes one slide.
Parameters:
| Parameter | Type | Description |
|-----------|------|-------------|
| htmlPaths | string[] | Array of absolute paths to HTML files |
| options | ConvertOptions | Optional configuration |
Options:
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| viewportWidth | number | 1280 | Browser viewport width in pixels |
| viewportHeight | number | 720 | Browser viewport height in pixels |
| waitTime | number | 100 | Milliseconds to wait after DOM changes |
| fontsDir | string | Built-in fonts | Path to custom fonts directory |
Returns: Promise<Buffer> — the generated PPTX file as a buffer.
How It Works
The conversion follows a 3-phase pipeline:
Phase 1: Extraction
- Launches headless Chromium and navigates to each HTML file
- Captures a DOM snapshot via Chrome DevTools Protocol (CDP)
- Extracts content in parallel:
- Text — extracted from the DOM snapshot, merged by inline flow context, platform fonts resolved via CDP
- Layers — compositing layers captured as PNG screenshots via the LayerTree API
- Tables — structure, text, and styles extracted via JS injection
- Charts — Chart.js instances detected and captured
- Canvases — non-chart
<canvas>elements captured viatoDataURL - Iframes — content extracted with coordinate transformation
Phase 2: Rendering
All extracted items are sorted by paint order and rendered to PPTX via pptxgenjs:
- Layer/canvas images become positioned PPTX images
- Text is segmented by character type, with per-segment font selection and formatting
- Tables become native PPTX tables with full styling
- Charts are captured as high-quality screenshots
Phase 3: Font Embedding
- Collects all font names used during rendering
- Matches against the bundled font directory (128 Google Font families)
- Embeds matching fonts directly into the PPTX ZIP structure
Project Structure
deckforge/
├── src/
│ ├── index.ts # Public API: convertToPptx()
│ ├── types.ts # TypeScript interfaces
│ ├── constants.ts # Viewport, units, CSS constants
│ ├── extraction/ # Phase 1: DOM/CDP content extraction
│ │ ├── snapshot.ts # DOM snapshot capture
│ │ ├── layer.ts # Compositing layer extraction
│ │ ├── text.ts # Text extraction & hiding
│ │ ├── text-merging.ts # Inline flow text merging
│ │ ├── font-resolve.ts # Platform font resolution
│ │ ├── chart.ts # Chart.js detection
│ │ ├── canvas.ts # Canvas screenshots
│ │ ├── table.ts # Table extraction
│ │ └── iframe.ts # Iframe content extraction
│ ├── rendering/ # Phase 2: PPTX generation
│ │ ├── renderer.ts # Main PptxRenderer
│ │ ├── text-renderer.ts # Text → PPTX text boxes
│ │ ├── layer-renderer.ts # Layers → PPTX images
│ │ ├── chart-renderer.ts # Charts → PPTX
│ │ └── table-renderer.ts # Tables → PPTX tables
│ ├── fonts/ # Phase 3: Font management
│ │ ├── font-decide.ts # Per-character font selection
│ │ ├── font-utils.ts # Font directory scanning
│ │ ├── font-embedding.ts # PPTX font embedding
│ │ └── pptx-package.ts # PPTX ZIP manipulation
│ └── utils/ # Shared utilities
│ ├── units.ts # Unit conversions
│ ├── color.ts # Color parsing
│ └── emoji.ts # Emoji/CJK/math detection
├── fonts/ # 128 bundled Google Font families
├── scripts/
│ └── convert-test.ts # Manual test script
└── test/
├── unit/ # Unit tests
└── e2e/ # End-to-end testsDevelopment
Prerequisites
- Node.js >= 18.0.0
- Chromium (installed via Playwright)
Setup
npm installScripts
# Build
npm run build
# Run tests
npm test
# Manual conversion test
npm run convertTesting
# Run all tests
npx vitest
# Run unit tests only
npx vitest test/unit
# Run e2e tests only
npx vitest test/e2eBundled Fonts
The library includes 128 Google Font families in .fntdata format, automatically embedded into generated PPTX files. This ensures consistent typography across different systems without requiring fonts to be installed locally.
Each font family includes up to 4 variants: regular, bold, italic, and bold_italic.
License
MIT
