Introduction
A low-level, high-performance PowerPoint OpenXML templating engine for Node.js. It generates and edits PPTX files directly through structured XML manipulation, avoiding fragile regex replacements and eliminating standard "Repair Mode" issues.
Features At A Glance
π¦ Structured XML Parsing
Every file modification uses a fast, reliable DOM-like abstraction instead of raw text replacement.
π In-Memory Manifests
Guards packaging integrity via atomic serialization of relationships and content types.
π Deep Slide Imports
Clones slides across templates, preserving all associated layouts, charts, links, and styling.
π Accurate Chart Updates
Synchronizes chart XML and underlying data caches directly inside embedded Excel sheets.
Installation
Install the library via npm. Make sure you meet the requirement of having Node.js version 18.0.0 or higher.
npm install node-pptx-templater
System Requirements
- Node.js: >= 18.0.0
- Module system: ES Modules (
"type": "module"in package.json)
Quick Start
Get up and running in under 60 seconds with this simple template rendering example.
import { PPTXTemplater } from 'node-pptx-templater';
// Load the source template
const ppt = await PPTXTemplater.load('template.pptx');
// Select slide 1 and execute operations
ppt.useSlide(1);
// Safely replace text placeholders
ppt.replaceText({
'{{title}}': 'Quarterly Earnings Report',
'{{date}}': 'May 2026'
});
// Update an interactive bar chart
ppt.updateChart('sales-chart', {
categories: ['Q1', 'Q2', 'Q3', 'Q4'],
series: [
{ name: 'Revenue ($M)', values: [120, 145, 170, 210] }
]
});
// Save non-corrupted PPTX to disk
await ppt.saveToFile('./output/annual_report.pptx');
Slide Import Engine
The Slide Import engine allows robust deep copying of individual slides from one template into another.
Unlike basic copy implementations, importSlideFrom performs an exhaustive search and deep-copy of all associated relationships, slide layouts, embedded media, and chart workbooks, remapping them into the new presentation's namespace.
Example: Merging Slide Decks
import { PPTXTemplater } from 'node-pptx-templater';
const master = await PPTXTemplater.load('master_template.pptx');
const source = await PPTXTemplater.load('department_results.pptx');
// Deep-copy slide 2 from department_results into master template
await master.importSlideFrom(source, 2);
// Save the combined deck
await master.saveToFile('merged_presentation.pptx');
ContentTypesManager
Every single file inside an OpenXML ZIP package must have its type registered inside the centralized manifest [Content_Types].xml.
Our centralized ContentTypesManager replaces standard fragile string replacements with a parsed in-memory node-tree representation of the manifest. Changes are flushed only during the final package writing step to completely eliminate race conditions.
API Reference
// Inside PPTXTemplater lifecycle:
const contentTypes = ppt.contentTypesManager;
// Override registration for new slide XML
contentTypes.addOverride('/ppt/slides/slide3.xml', 'application/vnd.openxmlformats-officedocument.presentationml.slide+xml');
// Default MIME registration
contentTypes.addDefault('webp', 'image/webp');
RelationshipManager
Relationships define how slides link to layouts, masters, charts, and media assets. Standard regex tools corrupt relationship chains if IDs are not fully unique.
The RelationshipManager provides bulletproof remapping and creation of relative relationship paths inside standard .rels files.
Usage Example
const rels = ppt.relationshipManager;
// Add a safe relationship to slides/slide1.xml
const rId = rels.addRelationship(
'ppt/slides/slide1.xml',
'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',
'../media/image10.png'
);
// Returns unique ID (e.g. 'rId5')
PPTXTemplater
The main class exposed by the library to load, select, modify, and save presentation templates.
Properties & Getters
| Property | Type | Description |
|---|---|---|
slideCount |
number |
Returns the total count of active slides in the loaded deck. |
relationshipManager |
RelationshipManager |
Access direct relationship operations. |
contentTypesManager |
ContentTypesManager |
Access manifest definitions. |
Main Methods
| Method | Arguments | Returns | Description |
|---|---|---|---|
useSlide |
(slideNumberOrTag) |
PPTXTemplater |
Restricts text, table, and chart updates to only target specific slides. |
replaceText |
(replacements) |
PPTXTemplater |
Performs structured substitution on text, handles run fragmentation cleanly. |
saveToFile |
(filePath) |
Promise<void> |
Saves all dirty cached XML parts and updates metadata counts before writing. |
Chart Engine
PowerPoint charts are structured via complex pairings of a Chart XML part and an embedded Excel Worksheet binary containing matching row/column data cells.
Our Chart Engine automatically updates the underlying series formulas, Category axis values, and regenerates both strCache and numCache so Google Slides and LibreOffice display charts instantly without requiring user-refresh triggers.
Updating Chart Data
ppt.updateChart('revenue-chart', {
categories: ['Q1', 'Q2', 'Q3', 'Q4'],
series: [
{ name: 'Target', values: [100, 120, 140, 160] },
{ name: 'Actual', values: [105, 118, 145, 172] }
]
});
Table Engine
Dynamically scale template tables. The Table Engine lets you replace placeholder rows while fully preserving the styles, fonts, backgrounds, and cell heights of the original template row.
Example Table Feeding
ppt.updateTable('team-roster', [
['Name', 'Title', 'Location'],
['Elena', 'Lead Designer', 'Milan'],
['Keigo', 'Research Engineer', 'Tokyo'],
['Tariq', 'Product Manager', 'Cairo']
]);
OpenXML Architecture
An inside look at how files are packaged and managed within the PPTX OpenXML structure.
βββββββββββββββββββββββββββββββββββββββββββββββββ
β PPTXTemplater β
β (Public API) β
ββββββββββ¬βββββββββββββββββββββββββββββββ¬ββββββββ
β β
ββββββββββΌβββββββββ ββββββββββΌβββββββββ
β SlideManager β β ChartManager β
β (discovery & β β (Excel & cacheβ
β slide CRUD) β β synchronizer)β
ββββββββββ¬βββββββββ ββββββββββ¬βββββββββ
β β
ββββββββββΌβββββββββββββββββββββββββββββββΌβββββββββ
β XMLParser β
β (fast-xml-parser parsing tree) β
ββββββββββ¬βββββββββββββββββββββββββββββββ¬ββββββββ
β β
ββββββββββΌβββββββββ ββββββββββΌβββββββββ
β ContentTypesMgr β β RelationshipMgr β
β (Overrides list)β β (.rels mapper) β
ββββββββββ¬βββββββββ ββββββββββ¬βββββββββ
β β
ββββββββββΌβββββββββββββββββββββββββββββββΌβββββββββ
β ZipManager β
β (JSZip raw serialization) β
βββββββββββββββββββββββββββββββββββββββββββββββββ
Troubleshooting
My presentation shows "PowerPoint found a problem with content..."
This is commonly caused by out-of-sync slide count metadata in docProps/app.xml or an override registration missing from [Content_Types].xml.
ppt.saveToFile() or ppt.toBuffer(), which automatically run metadata-synchronization passes and flush all manifest changes.
My placeholders aren't replacing!
PowerPoint split-runs break placeholders like {{placeholder}} into multiple separate <a:t> tags. Enable logging output to identify where fragmentation occurs:
PPTX_LOG_LEVEL=debug node script.js