Releases: shbernal/PptxGenJS
v6.0.0
This major release introduces the new pptxgenjs/read subsystem — a separate, lossless read/edit/round-trip layer for existing decks — alongside radial gradient fills and image-in-shape composition. The new public ./read subpath export and its substantial API surface motivate the major version bump.
Added
- New
pptxgenjs/readsubsystem (@shbernal/pptxgenjs/read): open an existing.pptx, navigate and edit it, and save it back losslessly (untouched parts stay byte-for-byte identical).- OPC layer (
OpcPackage): parts, content types, relationships, writable parts, losslesssave(). - Navigable read model:
Presentation → slides → shapes → text frame → paragraphs → runs, incl. tables, charts (read-only), connectors, nested groups. - Typed edits over the live DOM: run text & character formatting, shape position/size, fill/line colour,
Slide.hidden,Picture.setImage,Slide.addPicture. - Structural edits: add/remove shapes, add pictures, edit table cell text, slide cloning.
- Cross-package composition:
Presentation.importSlide(theme: 'preserve' | 'restyle',carryMasterGraphics, placeholder geometry/run-size baking) andimportShape/importShapes. - Loader hardening: PowerPoint
[trash]parts dropped on load.
- OPC layer (
- Radial gradient fills:
RadialGradientFillProps(kind: 'radial', optionalcenter/rotateWithShape) serialized as<a:gradFill>with<a:path path="circle">+<a:fillToRect>. - Image embedded in a shape:
addImage({ points })clips a picture to acustGeompath (or presetshape/rounding); withsizing: { type: 'cover' }it center-crops to fill the clip.
Changed
- Image
sizingnow emits an explicit<a:fillRect/>inside<a:stretch>(canonical PowerPoint form) instead of an empty self-closing<a:stretch/>.
See CHANGELOG.md for full details.
v5.4.0
Added
slide.addConnector(...)— real PowerPoint connector shapes (<p:cxnSp>) with straight/elbow/curved geometries, flip derivation, and line styling/arrowheads (upstream gitbrent#1059).ThemeProps.colorSchemeto configure a presentation's theme color scheme (upstream gitbrent#1243).- Table
autoPagePlaceholderto carry placeholders onto auto-paged overflow slides (upstream gitbrent#1136). - Image
lineborder outline (<a:ln>on the picture), pairing with the existingshadow(upstream gitbrent#986). - Pie/doughnut data-label leader-line styling via
leaderLineColor/leaderLineSize(upstream gitbrent#1376). bullet.fontFaceandbullet.sizefor custom symbol/numbered bullet glyphs (upstream gitbrent#800, gitbrent#743).- Actionable media-load errors with an opt-in placeholder fallback (upstream gitbrent#1310).
Changed
- BREAKING: exported
.pptxpackages are now DEFLATE-compressed by default on every export path (previously STORE), producing much smaller files. Passcompression: falseto restore the old uncompressed behavior (upstream gitbrent#1268).
Fixed
sizing: 'cover' | 'contain'is now aspect-correct for SVG images (intrinsic size read from<svg>width/height/viewBox instead of stretching).defineSlideMasterpasses rich-text arrays through master text objects unchanged (upstream gitbrent#962).- Table
autoPageno longer crashes (addTable: Array expected) or emits empty overflow pages whenh+y/margins leave no usable height. - Tables honor
data-pptx-widthand no longer computeNaNcolumn widths for hidden tables (upstream gitbrent#1157).
v5.3.0
Added
addImageinfers an image's natural size whenw/hare omitted. For base64
dataimages the intrinsic pixel size is read synchronously from the header
(PNG/JPEG/GIF/BMP/WebP) and applied at 96 DPI; when only one ofw/his
given, the other is derived from the natural aspect ratio. Previously a
dimensionless image collapsed to a 1in square.pathand SVG images (not
synchronously measurable) keep the 1in fallback.- Explicit coordinate unit suffixes on any
Coord(x/y/w/h):"<n>in"
(inches),"<n>pt"(points), and"<n>emu"(raw EMU) — alongside the existing
bare number (inches) and"<n>%". Example:{ x: '72pt', w: '914400emu' }. - Exported branded
Emutype andcoordToEmu/percentToEmuconverters from
the units module (joining the existinginchesToEmu/pointsToEmu/
emuToIncheshelpers). - Run-level text shadow: a
shadow(orglow) set on a text run now emits an
<a:effectLst>inside<a:rPr>, so text in table cells — which have no shape
spPr— can finally carry a shadow (upstream gitbrent#1011). OptsChartData.customLabels?: string[]for per-data-point data label text
overrides on BAR/LINE/AREA/RADAR and PIE/DOUGHNUT charts; empty entries fall
back to chart-level settings (upstream gitbrent#1337).OptsChartData.pointStyles?: ChartDataPointStyle[]for typed per-data-point
border/fill styling ({ border?: BorderProps; fill?: HexColor }), index-
aligned withvalues[], on BAR/BAR3D/LINE/AREA/SCATTER/PIE/DOUGHNUT
(upstream gitbrent#1343).- Text-box columns:
columns(1–16) andcolumnSpacing(points) on
TextPropsOptions, emittingnumCol/spcColon<a:bodyPr>(upstream gitbrent#1320). - Line
cap('flat'|'round'|'square') onShapeLinePropsandBorderProps,
emitted on<a:ln>for shapes, table cell borders, and charts via a shared
LineCaptype (upstream gitbrent#782). objectLock(ObjectLockProps) on shapes, text boxes, images, media, and
tables, serializing DrawingMLa:spLocks/a:picLocks/a:graphicFrameLocks
(noGrp, noMove, noResize, noRot, noCrop, …) (upstream gitbrent#438).shapeAdjust({ name, value }, single or array) onShapePropsand
ImageBaseProps, emitting preset-shape adjustment guides in<a:avLst>
(upstream gitbrent#1300).- Chart title
titleItalic/titleUnderlineprops, mirroringtitleBold
(upstream gitbrent#1188). - Partial chart-title manual layout:
titlePosnow accepts a partial
{ x?, y? }, applying a manual offset on one axis while leaving the other on
automatic layout (upstream gitbrent#1363). - Shrink-autofit tuning:
fitaccepts{ type: 'shrink', fontScale?, lnSpcReduction? }(percent 0–100) emitted on<a:normAutofit>; bare
fit: 'shrink'is unchanged (upstream gitbrent#1199). barSeriesLineon bar charts (trueor anOptsChartGridLineobject) emits
<c:serLines>for stacked bars (upstream gitbrent#1329).showBubbleSizeoption for bubble-chart data labels (upstream gitbrent#744).
Changed
- Behavior change: A bare-number coordinate is now always inches. The library no
longer guesses units by magnitude — previously a number>= 100was silently
treated as raw EMU (andinch2Emu/coordinate parsing carried a matching
> 100passthrough), which mis-rendered any legitimately large value and made
values near the threshold ambiguous.- Migration: if you were passing raw EMU as a large number (e.g.
914400),
pass it explicitly as a string instead ('914400emu'), or convert with the
emuToIncheshelper. Bare numbers,'%', and the new unit suffixes need no
change. - Non-finite coordinates now throw with a descriptive message instead of
collapsing the object to zero size; an implausibly large bare number (> 1000
inches) is interpreted as inches but warns, pointing at the'<n>emu'form. - Internally, user coordinates are resolved to EMU exactly once at the
emission boundary (no in-place pre-conversion / double-parse), and resolved
values carry a brandedEmutype so they cannot be silently re-converted.
- Migration: if you were passing raw EMU as a large number (e.g.
- Behavior change: Removed the invalid
LINE_CALLOUT_4*shape presets
(borderCallout4,accentCallout3=4,accentBorderCallout4,callout4) —
no callout-4 exists in ECMA-376ST_ShapeType, so they only ever produced
corrupt packages.FOLDED_CORNERis also corrected from the invalid
folderCornerto the spec spellingfoldedCorner(upstream gitbrent#1449). - Chart values now carry their number format into each series'
<c:numCache><c:formatCode>(resolved fromvalLabelFormatCode/
dataTableFormatCode/dataLabelFormatCode, default#,##0) instead of a
hard-codedGeneral, so PowerPoint and Google Slides honorformatCodethe
way LibreOffice already did. This deliberately changes default cached output
to match the data-label format (upstream gitbrent#1309). - Identical media is now deduplicated: inline base64
data:media is reused
per slide, and a deck-wide export pass collapses repeated images (including
background images and SVG) to a single package part instead of embedding one
copy per use (upstream gitbrent#1339). ChartLineCapis now a deprecated alias for the sharedLineCaptype.
Fixed
- Table merged cells (colspan/rowspan covered cells) now render the span's outer
borders and fill instead of emitting an empty<a:tcPr/>; the origin cell's
border tuple and resolved fill are applied to the covered edges to match
PowerPoint-authored output (upstream gitbrent#680). - RGBA effect colors no longer emit a duplicate
<a:alpha>: when a shadow/glow
caller supplies an explicit alpha (notably on table-cell paths that skip
correctShadowOptions), it wins and the RGBA byte is dropped, fixing
schema-invalid double-<a:alpha>output that triggered PowerPoint repair. - Text-box
marginarrays are now mapped as[top, right, bottom, left],
matching table cells and slide numbers; previously Top and Left were
transposed, mis-rendering asymmetric margins (upstream gitbrent#1248). - Out-of-range fill/line/gradient transparency, glow opacity, and line widths
are clamped to schema-valid<a:alpha>/<a:ln w>ranges (warning on
coercion) instead of emitting values PowerPoint rejects. - Out-of-range
fontSize,charSpacing, andlineSpacingare clamped to their
schema ranges at run/paragraph emission (covering text boxes, table cells, and
the slide-number placeholder). - Chart
gapWidth/gapDepth,overlap,holeSize, andfirstSliceAngare
clamped to their schema ranges via a shared helper (upstream gitbrent#1233). - Chart
lineDataSymbolSizeis rounded and clamped into the valid
ST_MarkerSizerange 2–72 (upstream gitbrent#1233). - Non-finite (
NaN/Infinity) chart data values are dropped (with a warning)
rather than emitting an invalid<c:numCache>that PowerPoint flags for
repair;null/undefinedremain valid sparse gaps (upstream gitbrent#1357). - Chart text (title, legend, axis labels, data labels) now stamps the requested
typeface onto the<a:latin>/<a:ea>/<a:cs>trio so East-Asian and
complex-script glyphs honor the chosen font (most visibly on PowerPoint for
Mac) (upstream gitbrent#1420). - Scatter/bubble X axes in combo charts now emit
<c:valAx>instead of
<c:catAx>, fixing packages PowerPoint flagged for repair; an unsatisfiable
shared-axis configuration now warns (upstream gitbrent#1355). addShape(and theshapeoption onaddText/addImage) now rejects
unknown presets with a clear error at thegenXmlPresetGeomchokepoint rather
than emitting an invalid<a:prstGeom>that corrupts the package
(upstream gitbrent#1449).- HTML-table conversion preserves fractional border widths (e.g. 0.5px hairlines)
instead of rounding them to 0pt; a zero/non-finite computed width now yields
{ type: 'none' }(upstream gitbrent#1235).
v5.2.0
Added
textRun/textRunstyped inline-run factory helpers- Native pattern fills for shapes (
fill: { type: 'pattern', pattern }) defineTableStyle(),TABLE_STYLEenum +tblPrstyle flags,hasHeaderoption- Slide-master
roundRectobject + placeholder shapes - Chart
seriesOptions(per-series color/label); combo-chart legend suppression - Image
duotonerecolor;firstSlideNum;setCustomProperty
Fixed
textRun/textRunsnow exported from every runtime entry (node/browser/standalone/core), not justindex— fixes a runtime "does not provide an export named 'textRun'" under the Node export condition- Image
cover/containcrop computed from natural pixel ratio; out-of-bounds crop now throws - Multi-level category chart workbook/SST indices;
round2SameRect/round2DiagRectadj values - Table
autoPageline-wrap/section/rowspan fixes;breakLine: falseon CRLF runs - SVG PNG preview placeholder; XML-encoded image hyperlink URLs
Full notes in CHANGELOG.md.
v5.1.0
Added
catAxisLabelFormatCodeon scatter and bubble charts sets an independent number format for the X (horizontal) axis, decoupled fromvalAxisLabelFormatCodewhich controls the Y axis.lineDashValues?: ChartLineDash[]on line, scatter, and bubble charts sets a per-series dash pattern; entries fall back to the chart-levellineDashdefault.addImage({ shape })clips a picture to any preset geometry (e.g.'hexagon','roundRect').rounding: trueremains a shorthand forshape: 'ellipse'.addImage({ points })clips a picture to an arbitrary freeform path (custGeom) using the same path DSL as freeform shapes. Takes precedence overshape/rounding.addImage({ svg })accepts raw SVG markup directly, converting it to a base64 data URI internally.altTextprop extended to text boxes, shapes, tables, and media objects (previously only images and charts).- Object name validation: warns on names that cannot provide a stable Selection Pane identity — empty/whitespace, control characters, names over 255 chars, or duplicates on the same slide.
bullet.color(HexColor) colors a bullet glyph independently of the text run color.TextBaseProps.caps('none'|'small'|'all') applies all-caps or small-caps styling to a text run.valAxisCrossBetween('between'|'midCat') exposes the OOXMLcrossBetweensetting on the value axis.STANDARD_LAYOUTS.*now expose.width/.heightinch aliases.pptx.layoutaccepts a preset object directly.slide.width/slide.heightgetters return the active layout size in inches.displayBlanksAs: 'zero'added as a valid chart option value.
Fixed
getSmartParseNumbernow throws onNaN/Infinityinstead of silently collapsing objects to zero size or position.- XML 1.0 illegal control characters stripped before serialization, preventing PowerPoint repair dialogs.
createColorElementguards against non-string input (preventsTypeErrorfromchartColors).- Table
write()/writeFile()is now idempotent on merged-cell tables. - Scatter/bubble chart data labels now apply
dataLabelFontSize,dataLabelFontBold,dataLabelFontItalic,dataLabelColor, anddataLabelFontFace. - Slide master and layout media targets namespaced to prevent collisions in large decks.
- Line charts now emit
c:grouping(required) and respectbarGrouping: 'stacked'. - Single-level category labels now emit
c:strRef/c:strCacheinstead ofc:multiLvlStrRef(better importer compatibility). - Chart zero values preserved in embedded workbook cells.
- Pie/doughnut parent
dLblsnow use user-supplied font/color instead of hard-coded defaults. - Transparent
chartColorsentries on line/radar charts emit<a:noFill/>on markers. - Chart null values now omit
<c:pt>entirely (correct OOXML gap encoding). - Stray apostrophe removed from embedded workbook table-ref attribute (fixes Keynote rendering).
- Pie/doughnut
dataLabelPositionapplied to parentdLblsblock instead of hard-coding'ctr'. - Shadow
blur,angle, andopacityzero values honored instead of replaced by defaults. barOverlapPctrespected on stacked bar charts.- Scatter/bubble cat-axis reads
catAxisLabelPosinstead of hard-coding'nextTo'. catAxisOrientation/valAxisOrientationtype unions now include'maxMin'.
Changed
displayBlanksAsdefault changed from'span'to'gap'.
v5.0.2
Added
- Native linear gradient fills for shapes.
- Public slide-layout unit helpers and package inspection primitives.
- Generated documentation site and object identity reference documentation.
Fixed
- Zero chart axis crossing values are preserved instead of being treated as absent.
- Company metadata XML is escaped before serialization.
- Inner shadow XML is closed correctly.
Changed
- Regression tests were reorganized into the current suite layout.
v5.0.1
Added
- GitHub Actions npm publishing workflow for
@shbernal/pptxgenjs, using npm trusted publishing and provenance on published GitHub releases.
Changed
- Release documentation now describes the automated
publish.ymlworkflow, tag guard, manual retry path, and post-publish checks.
v5.0.0
v5.0.0
First GitHub release for the scoped fork package, @shbernal/pptxgenjs.
Highlights
- Moves the maintained package target to
@shbernal/pptxgenjs. - Keeps the runtime contract intentionally ESM-only for Node.js
>=24and modern bundlers. - Verifies scoped default and subpath imports for
@shbernal/pptxgenjs,@shbernal/pptxgenjs/core,@shbernal/pptxgenjs/node,@shbernal/pptxgenjs/browser, and@shbernal/pptxgenjs/standalone. - Keeps package artifacts generated under
dist/and excludes legacy CJS/IIFE/browser-global artifacts. - Adds the release checklist under
docs/RELEASING.md. - Updates CI to run Node 24 and Node 26 validation with package lint, pack checks, package smoke tests, and demo smoke tests.
Breaking Changes
- Package import path changes from
pptxgenjsto@shbernal/pptxgenjs. - CommonJS
require(...), IIFE/global browser bundles, direct CDN script-tag workflows, and legacy artifact names are not maintained package targets.
npm Status
npm publishing is not automated for this first scoped release. Publishing @shbernal/pptxgenjs@5.0.0 remains a manual follow-up after npm ownership/package setup is confirmed.
Verification
GitHub CI passed on Node 24 and Node 26 for commit 688189aaa612fcd4e718bdb6131ac790dcf0e4d5.
CI run: https://github.com/shbernal/PptxGenJS/actions/runs/27091629379