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 🙏

© 2026 – Pkg Stats / Ryan Hefner

pptx-fix

v0.4.0

Published

Fix PowerPoint files that render incorrectly on macOS QuickLook and iOS. Built on quicklook-pptx-renderer for font metrics, text measurement, and issue detection. Resolves missing table borders, invisible shapes, flattened gradients, font reflow, and opaq

Readme

pptx-fix

Fix PowerPoint files that render incorrectly on macOS QuickLook and iOS. Rewrites PPTX internals so tables, shapes, gradients, and effects display correctly on Apple devices — no manual editing needed.

If your .pptx looks perfect in PowerPoint but looks wrong when someone opens it on a Mac or iPhone, this tool fixes it.


The Problem

Apple's QuickLook (macOS Finder spacebar preview), iOS Files app, and iPadOS use a private rendering engine called OfficeImport.framework — a completely independent OOXML parser that renders slides differently than Microsoft PowerPoint. Presentations created by python-pptx, PptxGenJS, Google Slides, Canva, LibreOffice, Pandoc, and other tools contain patterns that PowerPoint handles fine but OfficeImport renders incorrectly.

Common artifacts:

  • Table borders vanish — generators set a table style reference, but OfficeImport only reads explicit border properties
  • Shapes disappear — ~120 preset geometries (heart, cloud, lightningBolt, sun, moon...) are silently dropped
  • Gradients become flat colors — 3+ color stops are averaged to a single solid color
  • Drop shadows become opaque blocks — shapes with effects render as opaque PDF images that cover content behind them
  • Fonts shift and text reflows — Calibri becomes Helvetica Neue, Arial becomes Helvetica, with different metrics
  • Embedded fonts ignored — custom fonts embedded in the PPTX are completely ignored by QuickLook, falling back to system substitutes

pptx-fix rewrites the OOXML XML inside the PPTX ZIP to work around these OfficeImport quirks. The output is a valid .pptx that looks correct in both PowerPoint and Apple's preview.


Install

npm install pptx-fix

Usage

CLI

# Fix a PPTX file
npx pptx-fix input.pptx -o output.pptx

# Apply only specific transforms
npx pptx-fix input.pptx -o output.pptx --only table-styles,gradients,fonts

# See what was changed
npx pptx-fix input.pptx -o output.pptx --report

# Analyze without fixing (dry run)
npx pptx-fix analyze input.pptx

As a Library

import { fix } from "pptx-fix";
import { readFileSync, writeFileSync } from "fs";

const input = readFileSync("presentation.pptx");
const result = await fix(input, { report: true });

writeFileSync("fixed.pptx", result.buffer);
console.log(result.report);

Analyze Only

import { analyze } from "pptx-fix";

const issues = await analyze(pptxBuffer);
for (const issue of issues) {
  console.log(`[${issue.severity}] Slide ${issue.slide}: ${issue.description}`);
}

Transforms

| Transform | Status | What it fixes | |-----------|--------|--------------| | table-styles | Done | Resolves tableStyleId references and inlines explicit <a:lnL/R/T/B> borders on every cell. Handles firstRow, lastRow, bandRow conditional formatting. Only adds borders where none are explicitly defined. | | geometries | Done | Replaces unsupported <a:prstGeom> presets (~120 shapes not in OfficeImport's supported set) with the visually-closest supported alternative (e.g. heart→ellipse, cloud→cloudCallout) so shapes are visible instead of invisible. | | gradients | Done | Collapses 3+ stop gradients to 2-stop (first + last color) so QuickLook renders a gradient instead of a flat color. | | effects | Done | Strips <effectLst> and <effectDag> (drop shadow, glow, reflection) from shape properties to prevent opaque PDF block rendering. | | fonts | Done | Replaces high-risk Windows fonts (Calibri +14.4%, Segoe UI +14%, Corbel +18.8%, etc.) with metrically-closest Apple system font (from 29 fonts preinstalled on both macOS and iOS). Prefers narrower substitutes to avoid text overflow. Also fixes fonts in theme XML. | | groups | Done | Ungroups shape groups so children render individually instead of being merged into a single opaque PDF block. Transforms child coordinates from group-space to slide-space. Skips rotated groups. | | embedded-fonts | Done | Strips embedded font data (ignored by QuickLook) and replaces font references with the metrically-closest Apple system font. E.g. Montserrat → DIN Alternate (-4.3% width). Reduces file size and ensures consistent rendering. | | text-fit | Done | Measures actual rendered text using canvas with macOS system fonts. Detects text that overflows its box or overlaps adjacent text after font replacement, and shrinks font sizes by the exact amount needed to fit. | | chart-fallbacks | Done | Renders charts to PNG and embeds as fallback images so QuickLook displays charts instead of blank rectangles. Requires Playwright (optional — skips silently if not installed). |

All issue detection, font metrics, and text measurement are provided by quicklook-pptx-renderer. Run pptx-fix analyze to see all issues, or use the renderer's linter directly in CI.


Which Tools Produce Affected Files

| Tool | Primary issue on Mac/iPhone | |------|---| | python-pptx | Tables render without borders — the #1 reported issue. Style references not resolved by OfficeImport. | | PptxGenJS | Missing thumbnails, shape rendering differences, effect artifacts | | Google Slides export | Font substitution, formatting shifts, missing content types | | Canva export | Fonts substituted, layout differences, animation artifacts | | LibreOffice Impress | Table styles unresolved, gradient rendering differences | | Pandoc / Quarto | Content type corruption, missing shapes, "PowerPoint found a problem with content" errors | | Apache POI | Content type errors (InvalidFormatException: Package should contain a content type part [M1.13]) | | Aspose.Slides | Missing thumbnail if refresh_thumbnail not called | | Open XML SDK | Repair errors, missing relationships |


How It Works

Built on top of quicklook-pptx-renderer — an open-source rendering engine that replicates Apple's QuickLook PPTX output pixel for pixel. The renderer provides the font metrics database, macOS font substitution maps, text measurement via canvas, and a linter that detects every class of issue this tool fixes. It runs on Linux/Docker without a Mac.

PPTX (ZIP) → extract XML → parse → apply transforms → measure text → serialize → repack ZIP
  1. Extract — JSZip opens the PPTX ZIP archive
  2. Parse — fast-xml-parser converts slide XML to objects, preserving all unknown elements
  3. Transform — each transform mutates the XML to work around OfficeImport quirks, using font metrics and substitution data from the renderer
  4. Measure — the text-fit transform measures actual rendered text with canvas using macOS system fonts, verifying that post-transform text still fits
  5. Serialize — XMLBuilder converts back to XML, JSZip produces a new valid PPTX
# Analyze issues without fixing (uses the renderer's linter)
npx pptx-fix analyze presentation.pptx

# Lint directly with the renderer (JSON output for CI)
npx quicklook-pptx lint presentation.pptx --json

# Render slides as PNG (see exactly what Mac users see)
npx quicklook-pptx render presentation.pptx --out ./slides/

Dependencies

| Package | Purpose | |---------|---------| | quicklook-pptx-renderer | Font metrics, font substitution maps, text measurement, and issue detection — all transforms depend on its data | | @napi-rs/canvas | Canvas-based text measurement with macOS system fonts for text-fit transform | | jszip | ZIP extraction/repacking | | fast-xml-parser | OOXML XML parsing and serialization |

License

MIT