Import PowerPoint (PPTX) presentations into IMG.LY's Creative Engine SDK. Platform-agnostic TypeScript library for converting PPTX slides to CE.SDK scenes.
A TypeScript library for importing PowerPoint (PPTX) presentations into IMG.LY's Creative Engine SDK. Converts PPTX slides into CE.SDK scenes with full support for text, shapes, images, and formatting.
- Text Elements: Full text formatting including font families, sizes, colors, bold, italic, character spacing, and line height
- Shapes: Rectangles, ellipses, and custom vector shapes with fills and strokes
- Gradient Fills: Linear and radial gradients on shapes (70% of presentations)
- Shadow Effects: Outer drop shadows with blur, offset, and transparency (60% of presentations)
- Gradient Backgrounds: Linear and radial gradients on slide backgrounds
- Images: Embedded images with proper positioning and dimensions
- Groups: Grouped elements with preserved hierarchy
- Layout: Accurate positioning, sizing, and rotation
- Z-Order: Maintains element stacking order from PowerPoint
- Theme Colors: Resolves PowerPoint theme color references
Works in both browser and Node.js environments:
- No file system dependencies
- Pure ArrayBuffer/Uint8Array handling
- Platform-neutral base64 encoding
- ESM module format
- TypeScript-first with full type definitions
- Comprehensive test suite with golden screenshot tests
- Visual regression testing with golden screenshots
- Font resolution via Google Fonts integration
- Error handling with detailed warnings for unsupported features
``bash`
npm install @imgly/pptx-importer
You'll need CE.SDK in your project:
`bashFor browser
npm install @cesdk/engine
Quick Start
$3
`typescript
import CreativeEngine from '@cesdk/engine';
import { PPTXParser } from '@imgly/pptx-importer';// Initialize CE.SDK engine
const config = {
license: 'your-license-key',
userId: 'your-user-id',
};
const engine = await CreativeEngine.init(config);
// Load PPTX file
const response = await fetch('presentation.pptx');
const arrayBuffer = await response.arrayBuffer();
// Parse PPTX and create CE.SDK scene (automatically parses all slides)
const parser = await PPTXParser.fromFile(engine, arrayBuffer);
const result = await parser.parse();
// Get created pages
const pages = engine.block.findByType('//ly.img.ubq/page');
console.log(
Imported ${pages.length} slides);// Check for any warnings
const messages = result.logger.getMessages();
const warnings = messages.filter(m => m.type === 'warning');
if (warnings.length > 0) {
console.warn('Unsupported features:', warnings);
}
// Export first slide
const blob = await engine.block.export(pages[0], 'image/png');
`$3
`typescript
import CreativeEngine from '@cesdk/node';
import { PPTXParser } from '@imgly/pptx-importer';
import { readFileSync } from 'fs';// Initialize CE.SDK engine
const engine = await CreativeEngine.init({
license: process.env.CESDK_LICENSE,
});
// Load PPTX file
const fileBuffer = readFileSync('presentation.pptx');
const arrayBuffer = fileBuffer.buffer.slice(
fileBuffer.byteOffset,
fileBuffer.byteOffset + fileBuffer.byteLength
);
// Parse PPTX (automatically parses all slides and attaches to scene)
const parser = await PPTXParser.fromFile(engine, arrayBuffer);
const result = await parser.parse();
// Get created pages
const pages = engine.block.findByType('//ly.img.ubq/page');
// Export first slide
const blob = await engine.block.export(pages[0], 'image/png');
`API Reference
$3
#### Static Methods
#####
PPTXParser.fromFile(engine, fileBuffer, options?)Creates a parser instance from a PPTX file.
Parameters:
-
engine: CreativeEngine - CE.SDK engine instance
- fileBuffer: ArrayBuffer - PPTX file as ArrayBuffer
- options?: Partial - Optional configurationReturns:
PromiseExample:
`typescript
const parser = await PPTXParser.fromFile(engine, arrayBuffer, {
tolerancePercent: 5,
logWarnings: true,
strictMode: false,
});
`#### Instance Methods
#####
parser.parse()Parses all slides in the PPTX file and automatically attaches them to the scene.
Parameters: None
Returns:
Promise - Contains logger with warnings and messagesExample:
`typescript
// Parse all slides
const result = await parser.parse();// Get created pages
const pages = engine.block.findByType('//ly.img.ubq/page');
console.log(
Imported ${pages.length} slides);// Access individual pages
pages.forEach((pageId, index) => {
console.log(
Slide ${index + 1}: block ID ${pageId});
});
`> Note: This API matches the PSD importer pattern for consistency across IMG.LY importers.
> All slides are parsed and attached to the scene automatically. Use
engine.block.findByType() to retrieve page block IDs.#####
parser.getSlideCount()Returns the total number of slides in the PPTX file.
Returns:
number$3
The result returned by
parser.parse() contains a logger with warnings and messages.Example:
`typescript
const result = await parser.parse();// Get all messages
const messages = result.logger.getMessages();
// Filter by type
const warnings = messages.filter(m => m.type === 'warning');
const errors = messages.filter(m => m.type === 'error');
warnings.forEach(w => {
console.log(
Warning: ${w.message});
});
`$3
Configuration options for the parser.
`typescript
interface PPTXParserOptions {
/**
* Tolerance percentage for numeric property validation in tests
* @default 5
*/
tolerancePercent?: number; /**
* Apply font metrics-based vertical position correction for text blocks
* @default true
*/
applyFontMetricsCorrection?: boolean;
/**
* Auto-correct text blocks that overflow their bounds
* @default true
*/
autoCorrectTextOverflow?: boolean;
}
`Supported Features
$3
- Text Blocks
- Font family, size, color
- Bold, italic formatting
- Character spacing
- Line height
- Multiple text runs with different formatting
- Vertical alignment
- Shapes
- Rectangles (with corner radius)
- Ellipses/circles
- Custom vector shapes (via SVG path conversion)
- Fill colors (solid, theme colors)
- Stroke colors and widths
- Images
- PNG, JPEG, GIF, BMP, WebP
- Embedded images
- Proper sizing and positioning
- Backgrounds
- Solid colors (RGB, theme colors)
- Linear and radial gradients
- Layout
- Absolute positioning
- Rotation
- Z-order preservation
- Groups and nested elements
$3
- Gradients
- ā
Linear gradients (fully supported)
- ā
Radial gradients (fully supported)
- ā ļø Path gradients (falls back to radial with warning)
- ā ļø Rectangular gradients (falls back to radial with warning)
- Shadow Effects
- ā
Outer drop shadows (fully supported)
- ā ļø Inner shadows (converted to outer shadows with warning)
- Colors
- ā
RGB colors
- ā
Theme colors (with fallback)
- ā ļø Transparency (basic support)
- Text
- ā
Basic formatting
- ā ļø Bullets and numbering (basic)
$3
- Tables (
) - Table content is skipped; workaround: ungroup table in PowerPoint before export
- Charts - Chart visualizations are not imported
- SmartArt - Diagram graphics are not imported
- Animations and transitions
- Slide masters and layouts
- Audio and video
- Comments and notes
- Background images (solid colors and gradients ARE supported)Unit System
PowerPoint uses EMUs (English Metric Units) for measurements:
- 1 inch = 914,400 EMUs
- 1 cm = 360,000 EMUs
CE.SDK scenes use Pixels at 96 DPI (standard screen resolution, matching Canva and PowerPoint). The importer automatically converts:
`typescript
// EMUs to CE.SDK pixels at 96 DPI
pixels = (emus / 914400) * 96
// Simplified: pixels = emus / 9525
`Font sizes use points (72 points = 1 inch), which are DPI-independent and don't require conversion.
Platform Compatibility
$3
- Modern browsers with ES2022 support
- Chrome 94+, Firefox 93+, Safari 15+, Edge 94+
$3
- Node.js 18+
- Works with Bun, Deno (with Node.js compatibility)
$3
The package is built with
platform: 'neutral' to work in any JavaScript environment.Development
$3
`bash
Clone repository
git clone https://github.com/your-org/pptx-importer.git
cd pptx-importerInstall dependencies
npm installSet up environment variables
cp .env.example .env
Edit .env and add your CESDK_LICENSE
`$3
`bash
Build the package
npm run buildType check
npm run typecheckClean build artifacts
npm run clean
`$3
The project uses a dual testing strategy:
#### Generated Tests (Unit/Integration)
Fast, deterministic tests using PptxGenJS to create PPTX files programmatically:
`bash
Run all tests
npm testRun generated tests only
npm run test:generatedWatch mode
npm run test:watch
`#### Golden Screenshot Tests (Visual Regression)
Compare rendered output against reference screenshots using real PPTX files:
`bash
Run golden tests
npm run test:goldenUpdate golden screenshots (after intentional changes)
npm run test:update-goldenExport scene archives for debugging
npm run test:golden:export-scenes
`$3
`
pptx-importer/
āāā src/
ā āāā entries/
ā ā āāā index.ts # Public API exports
ā āāā lib/
ā āāā pptx-parser/
ā āāā index.ts # Main PPTXParser class
ā āāā interfaces.ts # TypeScript interfaces
ā āāā converters/ # Unit & color conversion
ā āāā handlers/ # Element handlers (text, shape, image)
ā āāā parsers/ # PPTX XML parsers
ā āāā utils/ # Utilities & helpers
āāā test/
ā āāā generated/ # Generated PPTX tests
ā āāā golden/ # Golden screenshot tests
ā āāā fixtures/ # Test PPTX files
āāā dist/ # Build output (npm package)
āāā build.mjs # Build script
`$3
Debug PPTX files and CE.SDK scenes:
`bash
Inspect raw PPTX structure
npx tsx tools/inspect-pptx.ts ./path/to/file.pptxInspect CE.SDK blocks after parsing
npx tsx tools/inspect-cesdk.ts ./path/to/file.pptxInspect CE.SDK unit system
npx tsx tools/inspect-cesdk-units.ts
`Architecture
The importer follows a modular architecture:
1. PPTX Loader (
utils/pptx-loader.ts) - Unzips PPTX and parses XML using JSZip + fast-xml-parser
2. Parsers - Extract data from XML structures
- SlideParser - Slide dimensions and element lists
- ThemeParser - Theme color schemes
- ElementParser - Individual element properties
3. Handlers - Create CE.SDK blocks
- TextHandler - Text blocks with formatting
- GraphicHandler - Graphic blocks for shapes and images (fills/strokes)
- GroupHandler - Grouped elements
- PageHandler - Page blocks (slides)
4. Converters - Transform data formats
- UnitConverter - EMU to pixels
- ColorConverter - PPTX colors to RGBA
- VectorPathConverter - Custom geometry to SVG paths
- FontConverter - Font name resolutionContributing
Contributions are welcome! Please follow the development principles:
$3
1. TypeScript-First - All code must be strictly typed
2. Test-First Development - Write tests before implementation
3. Platform-Agnostic - No Node.js-specific APIs in library code
4. Dual Testing - Generated tests + golden screenshot tests
$3
1. Fork the repository
2. Create a feature branch
3. Write failing tests
4. Implement the feature
5. Ensure all tests pass
6. Add a changeset (see below)
7. Submit a pull request
$3
This project uses Changesets to manage versioning and changelogs.
#### When to Add a Changeset
Add a changeset when your PR includes changes that should be released to users:
- ā
Add a changeset for:
- New features
- Bug fixes
- Performance improvements
- Breaking changes
- Documentation improvements that affect users
- ā Skip changeset (add
no-changeset label to PR) for:
- Internal refactoring with no user impact
- Test updates
- CI/CD changes
- Development tooling updates#### How to Add a Changeset
After making your changes, run:
`bash
npm run changeset
`This will prompt you for:
1. Bump type - Choose the appropriate version bump:
-
major - Breaking changes (1.0.0 ā 2.0.0)
- minor - New features (1.0.0 ā 1.1.0)
- patch - Bug fixes (1.0.0 ā 1.0.1)2. Summary - Write a clear description of your changes:
- Use present tense ("Add gradient support" not "Added gradient support")
- Be specific and user-focused
- Mention breaking changes if applicable
This creates a changeset file in
.changeset/ that you should commit with your changes:`bash
git add .changeset/*.md
git commit -m "feat: add gradient fill support"
`#### Example Changeset
When you run
npm run changeset, it creates a file like .changeset/cool-pandas-smile.md:`md
---
"@imgly/pptx-importer": minor
---Add support for gradient fills on shapes and backgrounds. Linear and radial gradients are now fully supported.
`#### Release Process
The release process is automated via GitHub Actions:
1. PRs are merged to main with changesets
2. GitHub Action creates a "Version Packages" PR automatically
3. Maintainer reviews and merges the Version PR
4. Automatic release to npm happens on merge
#### Manual Versioning (for maintainers)
If needed, you can manually version and release:
`bash
Apply changesets and update versions
npm run versionCommit the changes
git add .
git commit -m "chore: version packages"
git pushPublish to npm
npm run release
`.changeset/CONTRIBUTING.md.See CLAUDE.md for detailed development guidance.
Troubleshooting
$3
`
Font 'CustomFont' substituted with 'Arial' for block 42
`The importer uses Google Fonts for font resolution. If a font isn't available, it falls back to a similar font. To add custom fonts:
`typescript
// Add custom font to CE.SDK asset library before parsing
await engine.asset.addAssetToSource('my-fonts', {
id: 'custom-font',
meta: { name: 'Custom Font' },
payload: {
typeface: {
name: 'Custom Font',
fonts: [{ uri: 'https://example.com/font.ttf' }]
}
}
});
`$3
`
Color scheme not found in theme XML
`Some PPTX files have corrupted or missing theme data. The parser falls back to default colors. To fix, re-save the PPTX in PowerPoint.
$3
Golden screenshot tests may show pixel differences due to:
- Font rendering differences across platforms
- CE.SDK version updates
- Intentional parser improvements
Update golden screenshots when differences are expected:
`bash
npm run test:update-golden
``- Gradients and Shadows - Implementation details for gradient fills, shadow effects, and gradient backgrounds
- Testing Strategy - Dual testing approach with generated and golden tests
- Feature Gap Analysis - Comprehensive analysis of supported and unsupported PPTX features
- CLAUDE.md - Development guide for working with this codebase
- STRUCTURE_GUIDE.md - PPTX internal structure and parsing guide
ISC
Built with:
- IMG.LY Creative Engine SDK
- JSZip - PPTX ZIP extraction
- fast-xml-parser - XML parsing
- PptxGenJS - Test PPTX generation
Inspired by the PSD Importer architecture.
- š Documentation
- š¬ Community Forum
- š Report Issues
- š§ Contact Support