@petepetepete/pptxviewjs
v1.3.0
Published
A JavaScript library for viewing PowerPoint presentations in web browsers using Canvas rendering
Maintainers
Readme
PptxViewJS
PowerPoint presentations, rendered in the browser.
PptxViewJS is a client-side JavaScript library that parses .pptx files and renders slides using HTML5 Canvas — no server, no file uploads, no conversion services required.
👉 Product page · Interactive Demo · All demos
Fork Notice
This package is a fork of gptsci/pptxviewjs, published as @petepetepete/pptxviewjs.
This fork has been refactored from a dist-only layout into a source-driven, rebuildable project:
- Recovered and restored the
src/codebase from shipped source maps - Recreated a reproducible Rollup build pipeline for
dist/outputs - Added smoke-test and maintainer workflow documentation for ongoing changes
The canonical source of truth in this fork is now src/; dist/ is generated.
🎮 Interactive Demo — PptxGenJS + PptxViewJS
The interactive demo showcases the full client-side presentation round-trip:
- Generate — pick a template (charts, tables, shapes, text, full deck) and click Run. PptxGenJS builds the
.pptxfile entirely in the browser. - Render — PptxViewJS instantly renders the generated presentation on an HTML5 Canvas.
- Download — save the
.pptxfile at any time.
The live code panel shows the exact PptxGenJS source used to generate each slide. No server involved at any step.
Available templates: Bar/Line/Pie/Area charts · Sales & comparison tables · Shapes · Text formatting · Full multi-slide deck (~18 slides)
🌐 All Demos
| Demo | Description | |---|---| | 🎮 Interactive Demo | Generate with PptxGenJS → render with PptxViewJS, live in the browser | | 📄 Simple Viewer | Minimal drag-and-drop viewer — perfect starting point | | 🖥️ Full Featured UI | Office Online–style: thumbnails, zoom, fullscreen, keyboard shortcuts | | 📚 Embedded Layout | Split view with thumbnail sidebar for docs portals and LMS platforms |
🚀 Features
- ✅ Zero server dependencies — all processing runs client-side
- ✅ Canvas rendering — pixel-accurate slide display
- ✅ Charts — bar, line, pie, area, doughnut via Chart.js (optional peer dep)
- ✅ Tables — merged cells, borders, shading, complex headers
- ✅ Media & SVG — embedded images and vector graphics
- ✅ Framework ready — React, Vue, Svelte, Vite, Electron, Streamlit
- ✅ TypeScript — full type definitions included
- ✅ Multiple formats — ESM, CJS, and minified UMD builds
📦 Installation
Choose your preferred method to install PptxViewJS:
Quick Install (Node-based)
npm install @petepetepete/pptxviewjsyarn add @petepetepete/pptxviewjsCDN (Browser Usage)
Use the UMD build via jsDelivr. Include JSZip (required) before the library. Include Chart.js (optional) if you need chart rendering:
<!-- Required: JSZip -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jszip.min.js"></script>
<!-- Optional: Chart.js (only if your presentations contain charts) -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/chart.umd.min.js"></script>
<!-- PptxViewJS UMD build exposes global `PptxViewJS` -->
<script src="https://cdn.jsdelivr.net/npm/@petepetepete/pptxviewjs/dist/PptxViewJS.min.js"></script>Note: JSZip is required for PPTX (ZIP) parsing. Chart.js is optional and only needed when rendering charts.
Peer Dependencies (Node/bundlers)
Install JSZip (required). Install Chart.js if your presentations include charts:
npm install jszip
# Optional (for charts)
npm install chart.jsTypography: Calibri Substitution
Decks authored in PowerPoint overwhelmingly use Calibri. Because Calibri is not installed on most macOS, Linux, and many Windows-without-Office machines, browsers silently fall back to a different font with different glyph widths. That causes titles and bullets to wrap at the wrong points compared to PowerPoint and Google Slides.
PptxViewJS bundles Carlito, Google's open-source, metric-compatible substitute for Calibri (SIL OFL 1.1). It has identical per-character widths, so wrapping matches PowerPoint regardless of the viewer's host OS.
How it works:
- The viewer registers Carlito at construction time under a library-scoped font family name (
PptxViewJS-Calibri), not the literalCalibri. Your app's otherfont-family: Calibriusages are unaffected. - The rendering code prepends the scoped name to the canvas font stack only for runs that declare
Calibri. So measurement and drawing both use Carlito metrics. - The woff2 files are served from a pinned jsDelivr CDN URL by default, so it works out of the box in any browser-based setup (React, Next.js, Vite, Webpack, UMD via CDN) without consumer asset configuration.
Configuration:
new PPTXViewer({
canvas,
// Defaults:
substituteCalibri: true, // Disable by passing `false`.
fontBaseUrl: undefined, // Override default jsDelivr URL. Accepts absolute
// URLs or site-relative paths ("/fonts/").
});When to override fontBaseUrl:
- Strict CSP (no external fonts): copy
node_modules/@petepetepete/pptxviewjs/fonts/into your public/static directory and passfontBaseUrl: '/fonts/'. - Offline / airgapped deployments: same as above.
- Vendoring on your own CDN: pass the absolute URL.
When to disable entirely (substituteCalibri: false):
- Your application already loads real Calibri (licensed).
- Your deck does not use Calibri.
- You want the absolute smallest possible behavior surface.
🧪 Local Harness (Manual Testing)
This fork includes a local manual test harness with hot reload for render debugging and regression checks.
Start it with:
npm run harness:devThen open:
http://localhost:3000/harness/
Harness capabilities:
- Upload a local
.pptxfile (no remote upload path) - Navigate slides with Previous / Next
- See
Slide X / Ystatus and active runtime - Enter and exit fullscreen mode for the viewer canvas
- Switch runtime mode between:
- Source (
src/index.js) - Dist (
dist/PptxViewJS.es.js)
- Source (
When switching runtime mode, the harness re-initializes the viewer and reloads the currently selected file (if one is already loaded) so source-vs-dist comparisons are deterministic.
🚀 Universal Compatibility
PptxViewJS works seamlessly in modern web and Node environments, thanks to dual ESM and CJS builds and zero runtime dependencies. Whether you're building a web app, an Electron viewer, or a presentation platform, the library adapts automatically to your stack.
Supported Platforms
- React / Angular / Vue / Vite / Webpack – just import and go, no config required
- Electron – build native presentation viewers with full filesystem access
- Browser (Vanilla JS) – embed in web apps with direct file handling
- Node.js – experimental; requires a Canvas polyfill (e.g.,
canvas) for rendering - Serverless / Edge Functions – use in AWS Lambda, Vercel, Cloudflare Workers, etc.
Builds Provided
- CommonJS:
dist/PptxViewJS.cjs.js - ES Module:
dist/PptxViewJS.es.js - Minified UMD:
dist/PptxViewJS.min.js
📖 Documentation
Quick Start Guide
PptxViewJS presentations are viewed via JavaScript by following 3 basic steps:
React/TypeScript
import { PPTXViewer } from "@petepetepete/pptxviewjs";
// 1. Create a new Viewer
let viewer = new PPTXViewer({
canvas: document.getElementById('myCanvas')
});
// 2. Load a Presentation
await viewer.loadFile(presentationFile);
// 3. Render the first slide
await viewer.render();Script/Web Browser
<canvas id="myCanvas"></canvas>
<input id="pptx-input" type="file" accept=".pptx" />
<button id="prev">Prev</button>
<button id="next">Next</button>
<div id="status"></div>
<script src="PptxViewJS.min.js"></script>
<script>
const { mountSimpleViewer } = window.PptxViewJS;
mountSimpleViewer({
canvas: document.getElementById('myCanvas'),
fileInput: document.getElementById('pptx-input'),
prevBtn: document.getElementById('prev'),
nextBtn: document.getElementById('next'),
statusEl: document.getElementById('status')
});
</script>Need finer control? You can still instantiate new PptxViewJS.PPTXViewer() manually and use the same APIs shown above.
That's really all there is to it!
🎮 Navigation & Interaction
Navigate through presentations with simple, chainable methods:
// Navigate through slides
await viewer.nextSlide(); // Go to next slide
await viewer.previousSlide(); // Go to previous slide
await viewer.goToSlide(5); // Jump to slide 5
// Get information
const currentSlide = viewer.getCurrentSlideIndex();
const totalSlides = viewer.getSlideCount();📊 Event System
Listen to presentation events for custom interactions:
// Listen to events
viewer.on('loadStart', () => console.log('Loading started...'));
viewer.on('loadComplete', (data) => console.log(`Loaded ${data.slideCount} slides`));
viewer.on('renderComplete', (slideIndex) => console.log(`Rendered slide ${slideIndex}`));
viewer.on('slideChanged', (slideIndex) => console.log(`Now viewing slide ${slideIndex}`));🙏 Contributors
Thank you to everyone for the contributions and suggestions! ❤️
Special Thanks:
- Alex Wong - Original author and maintainer
- gptsci.com - Project sponsorship and development
🛠️ Maintainer Workflow (Fork)
This fork includes a recovered src/ tree and a rebuildable Rollup pipeline. For source-of-truth and release workflow details, see MAINTAINERS.md.
🌟 Support the Open Source Community
If you find this library useful, consider contributing to open-source projects, or sharing your knowledge on the open social web. Together, we can build free tools and resources that empower everyone.
📜 License
Copyright © 2025 Alex Wong
