npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@imgly/pptx-importer

v2.0.0-rc.1

Published

Import PowerPoint (PPTX) presentations into IMG.LY's Creative Engine SDK. Platform-agnostic TypeScript library for converting PPTX slides to CE.SDK scenes.

Downloads

27

Readme

PPTX Importer for CE.SDK

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.

Features

✨ Comprehensive PPTX Support

  • 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

🌐 Platform-Agnostic

Works in both browser and Node.js environments:

  • No file system dependencies
  • Pure ArrayBuffer/Uint8Array handling
  • Platform-neutral base64 encoding
  • ESM module format

🎯 Production-Ready

  • TypeScript-first with full type definitions
  • Comprehensive test suite with 80+ passing tests
  • Visual regression testing with golden screenshots
  • Font resolution via Google Fonts integration
  • Error handling with detailed warnings for unsupported features

Installation

npm install @imgly/pptx-importer

Peer Dependencies

You'll need CE.SDK in your project:

# For browser
npm install @cesdk/engine

# For Node.js
npm install @cesdk/node

Quick Start

Browser

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);
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 warnings = parser.getWarnings();
if (warnings.length > 0) {
  console.warn('Unsupported features:', warnings);
}

// Export first slide
const blob = await engine.block.export(pages[0], 'image/png');

Node.js

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);
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

PPTXParser

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<PPTXParserOptions> - Optional configuration

Returns: Promise<PPTXParser>

Example:

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<void>

Example:

// Parse all slides
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

parser.getWarnings()

Returns warnings about unsupported features encountered during parsing.

Returns: UnsupportedFeatureWarning[]

Example:

const warnings = parser.getWarnings();
warnings.forEach(w => {
  console.log(`Warning: ${w.feature} in ${w.pptxProperty}`);
});
parser.clearWarnings()

Clears all logged warnings.

PPTXParserOptions

Configuration options for the parser.

interface PPTXParserOptions {
  /**
   * Tolerance percentage for numeric property validation in tests
   * @default 5
   */
  tolerancePercent?: number;

  /**
   * Enable warning logs for unsupported PPTX features
   * @default true
   */
  logWarnings?: boolean;

  /**
   * Strict mode - throw errors for unsupported features
   * @default false
   */
  strictMode?: boolean;
}

Supported Features

✅ Fully Supported

  • 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
  • Layout

    • Absolute positioning
    • Rotation
    • Z-order preservation
    • Groups and nested elements

⚠️ Partially Supported

  • Colors

    • ✅ RGB colors
    • ✅ Theme colors (with fallback)
    • ⚠️ Gradients (not yet implemented)
    • ⚠️ Transparency (basic support)
  • Text

    • ✅ Basic formatting
    • ⚠️ Bullets and numbering (basic)
    • ⚠️ Tables (not yet implemented)

❌ Not Supported

  • Animations and transitions
  • Slide masters and layouts
  • Charts and SmartArt
  • Audio and video
  • Comments and notes
  • Slide backgrounds (partially)

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 300 DPI by default. The importer automatically converts:

// EMUs to CE.SDK pixels
pixels = (emus / 914400) * 300
// Simplified: pixels = emus / 3048

Font sizes use points (72 points = 1 inch), which are DPI-independent and don't require conversion.

Platform Compatibility

Browser Requirements

  • Modern browsers with ES2022 support
  • Chrome 94+, Firefox 93+, Safari 15+, Edge 94+

Node.js Requirements

  • Node.js 18+
  • Works with Bun, Deno (with Node.js compatibility)

Build Targets

The package is built with platform: 'neutral' to work in any JavaScript environment.

Development

Setup

# Clone repository
git clone https://github.com/your-org/pptx-importer.git
cd pptx-importer

# Install dependencies
npm install

# Set up environment variables
cp .env.example .env
# Edit .env and add your CESDK_LICENSE

Building

# Build the package
npm run build

# Type check
npm run typecheck

# Clean build artifacts
npm run clean

Testing

The project uses a dual testing strategy:

Generated Tests (Unit/Integration)

Fast, deterministic tests using PptxGenJS to create PPTX files programmatically:

# Run all tests
npm test

# Run generated tests only
npm run test:generated

# Watch mode
npm run test:watch

Golden Screenshot Tests (Visual Regression)

Compare rendered output against reference screenshots using real PPTX files:

# Run golden tests
npm run test:golden

# Update golden screenshots (after intentional changes)
npm run test:update-golden

# Export scene archives for debugging
npm run test:golden:export-scenes

Project Structure

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

Inspection Tools

Debug PPTX files and CE.SDK scenes:

# Inspect raw PPTX structure
npx tsx tools/inspect-pptx.ts ./path/to/file.pptx

# Inspect CE.SDK blocks after parsing
npx tsx tools/inspect-cesdk.ts ./path/to/file.pptx

# Inspect 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 + xml2js
  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
    • ShapeHandler - Graphic blocks with fills/strokes
    • ImageHandler - Image blocks with data URLs
    • 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 resolution

Contributing

Contributions are welcome! Please follow the development principles:

Core Principles

  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

Development Workflow

  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

Versioning with Changesets

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:

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:

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:

---
"@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:

# Apply changesets and update versions
npm run version

# Commit the changes
git add .
git commit -m "chore: version packages"
git push

# Publish to npm
npm run release

For more details, see .changeset/CONTRIBUTING.md.

See CLAUDE.md for detailed development guidance.

Troubleshooting

Font Substitution Warnings

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:

// 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' }]
    }
  }
});

Missing Theme Colors

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.

Visual Differences in Golden Tests

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:

npm run test:update-golden

Documentation

Feature-Specific Guides

Architecture Documentation

License

ISC

Credits

Built with:

Inspired by the PSD Importer architecture.

Support