DEV Community

jake
jake

Posted on • Originally published at paperjsx.com

PptxGenJS gotchas that silently break your PowerPoint: the complete guide

PptxGenJS has 1.27 million weekly downloads and is the most popular JavaScript library for PowerPoint generation. It is also full of silent failure modes — bugs that produce corrupted output without throwing errors. Option objects get mutated in-place. Combo charts trigger repair dialogs. Uppercase image paths break files. This guide documents every known gotcha with the broken code and the fix, sourced from GitHub issues, production debugging, and Anthropic's OOXML skills documentation.

Gotcha 1: option object mutation

Silent corruption — second shape gets wrong dimensions

According to Anthropic's PptxGenJS reference: "NEVER reuse option objects across calls — PptxGenJS mutates objects in-place (e.g. converting shadow values to EMU). Sharing one object between multiple calls corrupts the second shape."

const shadow = {
  type: "outer", blur: 6, offset: 2,
  color: "000000", opacity: 0.15
};

slide.addShape(pres.shapes.RECTANGLE, { shadow, x: 1, y: 1 });
// ❌ shadow object is now mutated (values converted to EMU)
slide.addShape(pres.shapes.RECTANGLE, { shadow, x: 3, y: 1 });
Enter fullscreen mode Exit fullscreen mode

Fix — factory function

const makeShadow = () => ({
  type: "outer", blur: 6, offset: 2,
  color: "000000", opacity: 0.15
});

slide.addShape(pres.shapes.RECTANGLE, { shadow: makeShadow() });
// ✅ fresh object — no mutation problem
slide.addShape(pres.shapes.RECTANGLE, { shadow: makeShadow() });
Enter fullscreen mode Exit fullscreen mode

This is the most common silent failure in PptxGenJS. The first shape renders correctly; the second shape has wrong dimensions, wrong shadow size, or missing formatting. There is no error, no warning, no repair dialog — just visually wrong output that passes through code review because the code looks correct.

Gotcha 2: combo charts trigger repair dialog

PowerPoint repair — "found a problem with content"

According to PptxGenJS release notes, issue #1013 documented that "chart with lines and bars produces repair file dialog in PowerPoint." The fix was released in v4.0.1 (June 2025), but combo charts with secondaryValAxis and secondaryCatAxis can still produce repair dialogs when the options are inconsistent.

const chartTypes = [
  { type: pres.charts.BAR, data: barData },
  { type: pres.charts.BAR, data: avgData,
    options: {
      secondaryValAxis: true,
      secondaryCatAxis: true,  // ❌ causes repair on Windows Office
    }
  }
];
slide.addChart(chartTypes, opts);
Enter fullscreen mode Exit fullscreen mode

Fix — hide secondary category axis

const opts = {
  valAxes: [
    { showValAxisTitle: true, valGridLine: "solid" },
    { valAxisHidden: true, valGridLine: "none" }  // ✅ hide secondary
  ],
};
slide.addChart(chartTypes, opts);
Enter fullscreen mode Exit fullscreen mode

This issue was platform-specific — files opened correctly in LibreOffice on macOS but triggered repair on Windows Office. Always test PptxGenJS output on Windows PowerPoint, not just macOS or web viewers. For the full OOXML explanation of why this happens, see why PPTX triggers repair dialogs.

Gotcha 3: uppercase image paths

Repair dialog — image path case sensitivity

According to PptxGenJS v4.0.1 release notes, issue #860 documented that "using addImage() with uppercase path prop causes needs to repair presentation." OOXML relationship targets are case-sensitive inside the ZIP archive.

slide.addImage({ path: "./images/logo.PNG" }); // ❌ .PNG (uppercase)
Enter fullscreen mode Exit fullscreen mode

Fix — lowercase paths

slide.addImage({ path: "./images/logo.png" }); // ✅ .png (lowercase)

// Or normalize programmatically:
const safePath = imagePath.toLowerCase();
slide.addImage({ path: safePath });
Enter fullscreen mode Exit fullscreen mode

Gotcha 4: "Edit Data in Excel" broken on charts

Charts not editable — embedded workbook corrupt

According to the PptxGenJS v4.0.1 release notes, "several issues with charts embedded Excel sheets that prevented Edit Data in Excel from working" were fixed. If you are on an older version, chart data cannot be edited by the recipient — clicking "Edit Data" in PowerPoint either does nothing or shows an error.

Fix — upgrade to v4.0.1+

npm install pptxgenjs@latest
Enter fullscreen mode Exit fullscreen mode

If upgrading is not possible, the chart data is still correct — only the "Edit Data in Excel" feature is broken. The chart displays correctly; it just cannot be modified by the recipient.

Gotcha 5: ROUNDED_RECTANGLE with accent borders

Visual bug — rectangular overlay bars on rounded corners

According to Anthropic's reference: "Don't use ROUNDED_RECTANGLE with accent borders — rectangular overlay bars won't cover rounded corners."

Fix — use RECTANGLE instead

// ❌ ROUNDED_RECTANGLE + colored border = visual artifact
slide.addShape(pres.shapes.ROUNDED_RECTANGLE, {
  rectRadius: 0.1,
  line: { color: "4580B0", width: 2 }
});

// ✅ Use RECTANGLE — clean border rendering
slide.addShape(pres.shapes.RECTANGLE, {
  line: { color: "4580B0", width: 2 }
});
Enter fullscreen mode Exit fullscreen mode

Gotcha 6: single-series bar chart with chartColors

Visual bug — chart renders broken with color array

According to issue #285, providing a chartColors array to a bar chart with a single data series causes the chart to render incorrectly. The legend shows all category labels as separate entries, and the bars display wrong colors.

Fix — single-element color array

// ❌ Array of colors with single series = broken rendering
slide.addChart(pres.charts.BAR, data, {
  chartColors: ["4580B0", "C4453A", "B58215"]
});

// ✅ Single-element array for single series
slide.addChart(pres.charts.BAR, data, {
  chartColors: ["4580B0"]
});
Enter fullscreen mode Exit fullscreen mode

Gotcha 7: table auto-paging with complex text

Content overflow — text runs break pagination

According to the PptxGenJS release notes, table auto-paging was "completely re-written from scratch" in v3.12 to handle complex text (text runs with mixed formatting). If you are on an older version, tables with styled text runs (bold + italic + links in the same cell) may overflow the slide without creating a new page.

Fix — upgrade to v3.12+ and use autoPageRepeatHeader

slide.addTable(rows, {
  autoPage: true,
  autoPageRepeatHeader: true,
  autoPageLineWeight: 0.5,  // reduce for tighter fits
  autoPageCharWeight: 0.5,   // reduce for more chars/line
});
Enter fullscreen mode Exit fullscreen mode

The autoPageLineWeight and autoPageCharWeight options control how aggressively the auto-pager breaks content. Lower values fit more content per slide at the cost of tighter spacing. Test with your actual data — the defaults may over-paginate.

The alternative: skip OOXML entirely

Every gotcha above stems from the same root cause: PptxGenJS generates raw OOXML, and OOXML has strict element ordering, relationship ID, and content type requirements that are easy to violate. The JSON layer pattern avoids these issues entirely — you define the document as JSON, and a rendering engine handles OOXML compliance.

PaperJSX's free PPTX engine (MIT-licensed) generates valid OOXML from JSON schemas. No option object mutation, no relationship ID management, no element ordering concerns. The same JSON produces PPTX, PDF, DOCX, and XLSX. For the free PPTX quickstart, see Generate PPTX from JSON. For a migration path from PptxGenJS, see the three-way comparison.

Avoid OOXML gotchas entirely — generate PPTX from JSON with PaperJSX (MIT-licensed), or see the PptxGenJS comparison.

Top comments (0)