A lightweight PPTX viewer for the browser with minimal dependencies
npm install pptx-viewer


A lightweight, dependency-minimal library for viewing PowerPoint (PPTX) files in the browser.
- Lightweight - Only one dependency (fflate for ZIP decompression, ~8KB gzipped)
- No server required - Runs entirely in the browser
- TypeScript - Full type definitions included
- Flexible API - Use the full viewer or just the parser/renderer
- Presentation mode - Fullscreen support with keyboard navigation
- Good fidelity - Renders shapes, text, images, and basic styling
``bash`
npm install pptx-viewer
`typescript
import { PPTXViewer } from 'pptx-viewer';
const viewer = new PPTXViewer('#container');
await viewer.load(file);
viewer.next();
viewer.previous();
viewer.goToSlide(2);
viewer.enterFullscreen();
`
`typescript
import { loadPresentation, renderSlideToElement } from 'pptx-viewer';
// Load the presentation
const presentation = await loadPresentation(file);
// Render a specific slide to your container
const container = document.getElementById('my-slide');
renderSlideToElement(presentation, 0, container);
// Navigate by rendering different slides
function goToSlide(index: number) {
renderSlideToElement(presentation, index, container);
}
// Clean up when done
presentation.cleanup();
`
`typescript
import { loadPresentation, getThumbnails } from 'pptx-viewer';
const presentation = await loadPresentation(file);
const thumbnails = getThumbnails(presentation, 200); // 200px wide
thumbnails.forEach((svg, index) => {
svg.onclick = () => goToSlide(index);
sidebar.appendChild(svg);
});
`
`html
`
`typescript`
const viewer = new PPTXViewer('#viewer');
await viewer.load('/presentations/demo.pptx');
`typescriptNow on slide ${index + 1}
const viewer = new PPTXViewer('#viewer', {
initialSlide: 0, // Start at first slide
showControls: true, // Show navigation controls
keyboardNavigation: true, // Enable keyboard shortcuts
onSlideChange: (index) => {
console.log();Loaded ${presentation.slides.length} slides
},
onLoad: (presentation) => {
console.log();`
},
onError: (error) => {
console.error('Failed to load:', error);
},
});
#### Constructor
`typescript`
new PPTXViewer(container: string | HTMLElement, options?: ViewerOptions)
| Parameter | Type | Description |
|-----------|------|-------------|
| container | string \| HTMLElement | CSS selector or element to render into |options
| | ViewerOptions | Optional configuration |
#### Methods
| Method | Returns | Description |
|--------|---------|-------------|
| load(source) | Promise | Load a PPTX file (File, ArrayBuffer, or URL) |next()
| | number | Go to next slide, returns new index or -1 |previous()
| | number | Go to previous slide, returns new index or -1 |goToSlide(index)
| | boolean | Go to specific slide (0-based index) |getCurrentSlide()
| | number | Get current slide index |getSlideCount()
| | number | Get total number of slides |getPresentation()
| | Presentation \| null | Get parsed presentation data |enterFullscreen()
| | Promise | Enter fullscreen mode |exitFullscreen()
| | Promise | Exit fullscreen mode |toggleFullscreen()
| | Promise | Toggle fullscreen mode |on(event, listener)
| | void | Add event listener |off(event, listener)
| | void | Remove event listener |destroy()
| | void | Clean up and release resources |
#### Events
`typescript`
viewer.on('slidechange', (index: number) => { });
viewer.on('load', (presentation: Presentation) => { });
viewer.on('error', (error: Error) => { });
viewer.on('fullscreenchange', (isFullscreen: boolean) => { });
`typescript`
interface ViewerOptions {
initialSlide?: number; // Default: 0
keyboardNavigation?: boolean; // Default: true
showControls?: boolean; // Default: true
width?: number; // Custom width
height?: number; // Custom height
onSlideChange?: (index: number) => void;
onLoad?: (presentation: Presentation) => void;
onError?: (error: Error) => void;
}
| Key | Action |
|-----|--------|
| → ↓ Space PageDown | Next slide |←
| ↑ PageUp | Previous slide |Home
| | First slide |End
| | Last slide |F
| | Toggle fullscreen |Escape
| | Exit fullscreen |
For more control, you can use the parser and renderer separately:
`typescript
import { extractPPTX, parsePPTX, renderSlide } from 'pptx-viewer';
// Extract the PPTX archive
const archive = await extractPPTX(file);
// Parse into a Presentation object
const presentation = await parsePPTX(archive);
// Render a specific slide
const svg = renderSlide(
presentation.slides[0],
presentation.slideSize,
{ width: 800 }
);
document.body.appendChild(svg);
// Clean up when done
archive.cleanup();
`
`typescript
const viewer = new PPTXViewer('#viewer');
await viewer.load(file);
const presentation = viewer.getPresentation();
// Access metadata
console.log(presentation.metadata.title);
console.log(presentation.metadata.author);
// Access theme
console.log(presentation.theme.colors);
console.log(presentation.theme.fonts);
// Access slides
presentation.slides.forEach((slide, index) => {
console.log(Slide ${index + 1}: ${slide.elements.length} elements);`
});
- Slide masters & layouts - Background and element inheritance from masters and layouts
- Tables - Full table rendering with cell styling, borders, and text formatting
- 50+ shape types - Rectangles, ellipses, triangles, stars (4-12 points), arrows (all directions), callouts, hearts, clouds, and more
- Text with formatting - Font family, size, color, bold, italic, underline, strikethrough, subscript, superscript, highlight, outline
- Text effects - Glow and reflection effects on text
- Element opacity - Transparency support for images and other elements
- Character spacing & capitalization - Letter-spacing, all caps, and small caps
- Text autofit - Automatic font scaling to fit text in containers
- Bullet and numbered lists - Multiple formats (arabic, alpha, roman) with proper indentation
- Shadow effects - Outer and inner shadows on shapes, images, and text boxes
- Line arrow heads - Triangle, stealth, diamond, oval, and arrow markers
- Connector lines - Straight, bent (elbow), and curved connectors with flip support
- Shape adjustments - Custom corner radius, snip sizes, star point depths, and more
- Hyperlinks - Clickable links in text
- Images - PNG, JPEG, GIF with cropping support
- Solid, gradient, and pattern fills - Linear/radial gradients, 40+ pattern types, theme and preset colors
- Stroke/outline styles - Color, width, dash patterns
- Grouped shapes - Nested groups supported
- Theme colors and fonts - Full theme support
- Slide backgrounds - Solid and gradient
- Charts - Native SVG rendering for bar, column, stacked column, pie, doughnut, line, area, and scatter charts
- SmartArt diagrams - Native rendering using pre-computed DrawingML shapes, with fallback to embedded images
- Embedded fonts - Automatic extraction and injection of fonts embedded in PPTX files (including obfuscated ODTTF fonts)
- Animations and transitions
- Videos and audio
- 3D effects
- Interactive elements
- Chrome 80+
- Firefox 75+
- Safari 13+
- Edge 80+
Requires support for:
- ES2020
- SVG foreignObject
- Fullscreen API
`bashInstall dependencies
npm install
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
1. Fork the repository
2. Create your feature branch (
git checkout -b feature/amazing-feature)
3. Commit your changes (git commit -m 'Add some amazing feature')
4. Push to the branch (git push origin feature/amazing-feature`)- Performance optimizations
- Animation and transition support
- Video and audio playback
MIT - see LICENSE for details.