# Core library workflows

To create slides by editing TSX with an AI agent and a live preview, start with
[Create slides with AI](/pptx/docs/authoring). This page covers
the underlying function API.

This page walks the canonical @office-kit/pptx workflows: **fill a template**, **build a deck from scratch**, **edit images in place**. Every snippet below is a real `.ts` file in this repo — `svelte-check` compiles them against the live `@office-kit/pptx` types on every build, so when this page renders, it's already proven that the code typechecks.

## Token-based template fill

The most common @office-kit/pptx use case: take a designer-authored template, swap `{{tokens}}` with your data, save. Formatting on the surrounding runs is preserved.

```ts title="site/src/lib/examples/template-fill.ts"
// Open a template .pptx, replace `{{tokens}}` everywhere, save it back.
//
// This file is imported as ?raw into the docs site so the snippet shown
// to readers is exactly what svelte-check / tsc compiled — if an API
// rename breaks this import, the docs build fails before deploy.

import { readFile, writeFile } from 'node:fs/promises';
import { loadPresentation, replaceTokensInPresentation, savePresentation } from '@office-kit/pptx';

const pres = await loadPresentation(await readFile('template.pptx'));
replaceTokensInPresentation(pres, {
  name: 'Yamashita',
  event: 'Re:Invent',
  date: '2026-12-01',
});
await writeFile('out.pptx', await savePresentation(pres));
```

`loadPresentation` accepts a `Uint8Array`, `ArrayBuffer`, or `Blob` — anything you can `fetch` or `readFile`. `replaceTokensInPresentation` walks every text run in every slide (and the speaker notes) replacing exact-match `{{name}}` tokens.

## Build a deck from scratch

`createPresentation()` returns an empty deck that already carries a slide master, a default theme, and three layouts (`Blank`, `Title Slide`, `Title and Content`), so there is no template file to ship. Add slides with `addTitleSlide` / `addContentSlide` / `addBlankSlide`, then fill them in with the typed `addSlide*` helpers:

```ts title="site/src/lib/examples/build-deck.ts"
// Build a deck from scratch: start from the built-in empty deck, add slides
// on its layouts, drop in a text box, an image, and a chart, then save.

import { readFile, writeFile } from 'node:fs/promises';
import {
  addBlankSlide,
  addSlideChart,
  addSlideImage,
  addSlideTextBox,
  addTitleSlide,
  createPresentation,
  inches,
  savePresentation,
} from '@office-kit/pptx';

const pres = createPresentation();
addTitleSlide(pres, 'Q3 review');

const slide = addBlankSlide(pres);
addSlideTextBox(slide, {
  x: inches(0.7),
  y: inches(0.5),
  w: inches(9),
  h: inches(0.7),
  text: 'Numbers up and to the right',
});
addSlideChart(slide, {
  x: inches(0.7),
  y: inches(1.5),
  w: inches(8),
  h: inches(4.5),
  spec: {
    kind: 'column',
    categories: ['Q1', 'Q2', 'Q3', 'Q4'],
    series: [{ name: 'Revenue', values: [120, 180, 240, 300] }],
    title: 'FY26',
  },
});
addSlideImage(slide, await readFile('logo.png'), {
  x: inches(8),
  y: inches(0.4),
  w: inches(1.5),
  h: inches(1),
});

await writeFile('out.pptx', await savePresentation(pres));
```

`inches(n)`, `cm(n)`, `pt(n)`, and `emu(n)` all return a branded `Emu` number — internally @office-kit/pptx only sees EMUs, so unit confusion is caught at the type level.

## Replace an image, preserve geometry

A common L2 (template-edit) workflow: a designer drops a placeholder image into the template, your code swaps in the real one without disturbing crop, position, or scaling.

```ts title="site/src/lib/examples/image-replace.ts"
// Swap an image in a template, preserving its crop / transform / sizing.
// The format is auto-detected from the new bytes.

import { readFile, writeFile } from 'node:fs/promises';
import {
  getShapeKind,
  getShapeName,
  getSlideShapes,
  getSlides,
  loadPresentation,
  savePresentation,
  setShapeImage,
} from '@office-kit/pptx';

const pres = await loadPresentation(await readFile('template.pptx'));
const newLogo = await readFile('new-logo.png');

for (const slide of getSlides(pres)) {
  for (const shape of getSlideShapes(slide)) {
    if (getShapeKind(shape) === 'picture' && getShapeName(shape) === 'Logo') {
      setShapeImage(shape, newLogo);
    }
  }
}
await writeFile('out.pptx', await savePresentation(pres));
```

`setShapeImage` auto-detects the new image's format (PNG / JPEG / GIF / SVG / BMP / TIFF) from magic bytes — pass `options.format` to override.

## Direct fs helpers (Node)

`@office-kit/pptx/node` exposes `loadPresentationFile` / `savePresentationToFile` so you can skip the `readFile` / `writeFile` glue:

```ts title="site/src/lib/examples/node-fs.ts"
// One-shot read + save direct from / to disk via the @office-kit/pptx/node
// helpers, no manual fs glue needed.

import { loadPresentationFile, savePresentationToFile } from '@office-kit/pptx/node';

const pres = await loadPresentationFile('input.pptx');
// ...mutate pres...
await savePresentationToFile(pres, 'output.pptx');
```

## Browser via fetch

The default entry is browser-safe (no `node:fs`). Load straight from a `fetch` Response:

```ts title="site/src/lib/examples/browser-fetch.ts"
// Browser: fetch a .pptx and load it. loadPresentation accepts any of
// Uint8Array / ArrayBuffer / Blob — `await response.arrayBuffer()` is the
// most browser-portable form.

import { getSlides, getSlideTitle, loadPresentation } from '@office-kit/pptx';

const response = await fetch('/template.pptx');
const pres = await loadPresentation(await response.arrayBuffer());
for (const slide of getSlides(pres)) {
  console.log(getSlideTitle(slide));
}
```

This works in any environment with `fetch`: modern browsers, Bun, Deno, Cloudflare Workers, edge runtimes.

## What's next

- <strong>[Recipes](/pptx/docs/recipes)</strong> — copy-pasteable code for the most common tasks (charts, tables, comments, animations, transitions, validation).
- <strong>[Cheatsheet](/pptx/docs/cheatsheet)</strong> — one-page lookup: "I want to do X" → exact functions to call.
- <strong>[API reference](/pptx/api)</strong> — every export, organized by section.
- **GitHub:** [`office-kit/pptx`](https://github.com/office-kit/pptx)
