Skip to content

Where it runs ​

ts-pptx ships one ESM build. Node, bundlers, browsers and require() all load that build, and no office application is involved anywhere.

Runtimes ​

RuntimeLoad it withwriteFile
Node.js 24 or laterimport, or require()writes the file to disk
A browser app built with a bundler (Vite, Rollup, Webpack and others)importdownloads the file
A browser page with no build step<script type="module"> from an ESM CDNdownloads the file
Deno, Bun, edge workersimportthrows; use toBytes() instead

CI runs the browser build in a real Chromium, and compares the deck it assembles part for part with the one Node builds from the same code. They are identical.

Entry points ​

SubpathImportWhat it is forRuns inGuide
pptx-tsimport TsPptx from "pptx-ts"Writing decks: TsPptx, createPresentation, enums, types and unit helpersEvery runtime, through the build for that runtimeYour first deck, API reference
pptx-ts/nodeimport TsPptx from "pptx-ts/node"The Node build, whatever the resolver's conditionsNodeAPI reference
pptx-ts/browserimport TsPptx from "pptx-ts/browser"The browser build, whatever the resolver's conditionsBrowsersAPI reference
pptx-ts/familiesimport { charts } from "pptx-ts/families"Construct families for createPresentation({ use })Every runtimeSmaller bundles
pptx-ts/readimport { Presentation } from "pptx-ts/read"Opening, editing and saving an existing deckEvery runtime. Loading from a file path needs NodeRead and edit a deck
pptx-ts/inspectimport { inspectPptx } from "pptx-ts/inspect"Reporting what a package holds without building the full modelEvery runtimeInspect a package
pptx-ts/scriptimport { printScript, readModelToIr } from "pptx-ts/script"Turning a deck into the TypeScript that rebuilds itEvery runtimeDeck to script
pptx-ts/measureimport { measureText } from "pptx-ts/measure"Measuring text against real font metricsEvery runtimeText that fits
pptx-ts/htmlimport { tableToSlides } from "pptx-ts/html"Converting an HTML <table> into slidesAnywhere with a DOM: a browser, or Node with a DOM library such as happy-domHTML tables to slides
pptx-ts/mathimport { latexToOmml } from "pptx-ts/math"Turning LaTeX and MathML into native equationsNode onlyMath equations
pptx-ts/zipimport { readZip } from "pptx-ts/zip"The zip reading and writing that read and inspect shareEvery runtimeNone

Which build the bare import gives you ​

import TsPptx from "pptx-ts" resolves through export conditions, so the file you get depends on the runtime doing the resolving:

The resolver setsYou getwriteFile
nodedist/node.jswrites to disk through node:fs
browser (bundlers targeting the browser, --conditions=browser)dist/browser.jsstarts a download
neither: Deno, Bun, edge workersdist/index.jsthrows runtime/file-output-unavailable

Types resolve through the same condition as the code, so what TypeScript shows you is what that runtime has. To get one build whatever the conditions, import pptx-ts/node or pptx-ts/browser directly.

require() from CommonJS ​

js
const { default: TsPptx, ShapeType } = require("pptx-ts")

const pptx = new TsPptx()

Node loads ES modules through require() from version 22.12, and the package requires Node 24, so this works on every supported version. require() returns the module's namespace rather than a separate CommonJS build, so the class arrives on .default. Every subpath loads the same way.

A browser, with a <script> tag ​

pptx-ts/browser is an ES module. An ESM CDN resolves its dependencies and serves it to a module script:

html
<script type="module">
  import TsPptx from "https://esm.sh/pptx-ts/browser"

  const pptx = new TsPptx()
  pptx.addSlide().addText("Built in the browser", { x: 1, y: 1, w: 8, h: 1 })
  await pptx.writeFile({ fileName: "example.pptx" })
</script>

jsDelivr serves the same build from https://cdn.jsdelivr.net/npm/pptx-ts/+esm.

Using the browser entry without a bundler ​

To serve the files yourself instead of from a CDN, load dist/browser.js from a module script and map the two bare specifiers it imports:

html
<script type="importmap">
  {
    "imports": {
      "fflate": "/node_modules/fflate/esm/browser.js",
      "opentype.js": "/node_modules/opentype.js/dist/opentype.mjs"
    }
  }
</script>

opentype.js is imported only when a font is first registered, so a page that never calls registerFontMetrics will not notice a missing entry for it until it does. embedFont reads no font tables and does not import it.

Deno, Bun and edge workers ​

These runtimes load the runtime-agnostic build, dist/index.js. Authoring is the same as anywhere else, and everything that hands bytes back (toBytes(), write(), toParts()) works. A worker that returns a deck in a response body needs nothing more.

What this build cannot do is place a file for you. It has no filesystem and no page to download onto, so writeFile() throws an UnsupportedFeatureError with the code runtime/file-output-unavailable, naming the two entries that can write a file.

Math is Node-only ​

pptx-ts/math loads its two optional dependencies through Node's createRequire, which keeps latexToOmml() and mathmlToOmml() synchronous, and a browser has no createRequire.