Skip to content

Export to PDF, PNG and PPTX

In this guide you export a deck to every format the engine writes, choose which slides and steps end up on the pages, give viewers a Download button, and set up an export that runs on every push. It takes about ten minutes, most of it the one-time browser download.

You need a deck that builds with npm run buildpnpm buildyarn buildbun run build. The numbers below come from the starter deck (npm create @kadal/deck@latestpnpm create @kadal/deckyarn create @kadal/deckbun create @kadal/deck): 8 slides, which print as 13 pages with their click steps.

kadal-deck export opens the built deck in a real Chromium and photographs it, so what you get is what the audience saw. Playwright is an optional dependency of the engine, so a deck that never exports never downloads a browser. In the deck folder:

Terminal window
npm i -D playwright
npx playwright install chromium
Terminal window
pnpm add -D playwright
pnpm dlx playwright install chromium
Terminal window
yarn add -D playwright
yarn dlx playwright install chromium
Terminal window
bun add -D playwright
bunx playwright install chromium

Without them, export stops with an error that Playwright can’t be found. kadal-deck screenshot, build --download and seoMeta.ogImage: auto use the same browser.

Terminal window
npx kadal-deck export
Terminal window
pnpm exec kadal-deck export
Terminal window
yarn kadal-deck export
Terminal window
bunx kadal-deck export
build vite build
pages 13 at 1920×1080
pdf export/my-talk.pdf (8 bookmarks)
done 13 pages, 1 file(s)

The command builds the deck, serves it on a free local port, prints it and stops the server: about seven seconds for the starter deck. The file is named after the deck’s folder and lands in export/.

By default you get a page per click step, so a slide that reveals three points in turn becomes three pages; the starter’s 8 slides make 13 pages. Each page is a picture of the slide with its text printed over it as real text, so the PDF looks the same in every viewer and stays searchable and copyable. Slide titles become bookmarks (vertical stacks nested under their column), and the deck’s title, author and info become the PDF’s metadata.

One page per slide instead, as a handout, under another name:

Terminal window
npx kadal-deck export --no-with-clicks --output handout
Terminal window
pnpm exec kadal-deck export --no-with-clicks --output handout
Terminal window
yarn kadal-deck export --no-with-clicks --output handout
Terminal window
bunx kadal-deck export --no-with-clicks --output handout

That writes export/handout.pdf with 8 pages. pdfSeparateFragments: false in the headmatter makes one page per slide the deck’s default.

Terminal window
npx kadal-deck export --png --pptx
Terminal window
pnpm exec kadal-deck export --png --pptx
Terminal window
yarn kadal-deck export --png --pptx
Terminal window
bunx kadal-deck export --png --pptx

Alongside the PDF you get export/png/, one PNG per page (named by slide and step: 001.png, 004-0.png, 004-1.png…) at twice the stage size, 3840 × 2160, and export/my-talk.pptx, one picture per page with each slide’s speaker notes attached. --scale 1 halves the pictures; --no-pdf skips the PDF when you only want the others.

The .pptx above is pictures: it looks exactly right and edits like a photograph. To hand a deck to someone who will change the words:

Terminal window
npx kadal-deck export --format pptx-editable
Terminal window
pnpm exec kadal-deck export --format pptx-editable
Terminal window
yarn kadal-deck export --format pptx-editable
Terminal window
bunx kadal-deck export --format pptx-editable
pptx export/my-talk.editable.pptx (editable: 47 text boxes, 41 shapes, 0 pictures, 0 tables natively; 4 drawn as pictures)
fonts named: Courier New, Inter, JetBrains Mono (a .pptx names fonts; it does not carry them)

Every slide is measured in the browser and rebuilt as PowerPoint objects:

  • text boxes with their runs: font, size, colour, bold, italic, underline, strike-through, links;
  • lists with real bullets, numbering and levels;
  • rectangles, rounded rectangles and ellipses with their fill, border and shadow;
  • pictures as the original files, cropped as the slide crops them, and tables as tables;
  • code as coloured monospace text;
  • the speaker notes.

What PowerPoint can’t draw (SVG, canvas, maths, diagrams, sketches, embedded pages, gradients, filters) is placed as a picture exactly where it stood, so nothing goes missing; the summary line counts those. A .pptx names its fonts without carrying them, so the export lists the families the people you send it to should have installed. To steer one element, put data-export="image" on it to photograph it whole, or data-export="skip" to leave it out.

Terminal window
npx kadal-deck export --format md
Terminal window
pnpm exec kadal-deck export --format md
Terminal window
yarn kadal-deck export --format md
Terminal window
bunx kadal-deck export --format md

You get export/my-talk.md and export/png/: each page as an image, with that slide’s notes as text under it. It reads well in a repository, a wiki or an email.

6. Pick the slides, the scheme and the background

Section titled “6. Pick the slides, the scheme and the background”

These flags work with every format:

Terminal window
npx kadal-deck export --range 1,3-5 --dark --png --no-pdf --out export/dark
Terminal window
pnpm exec kadal-deck export --range 1,3-5 --dark --png --no-pdf --out export/dark
Terminal window
yarn kadal-deck export --range 1,3-5 --dark --png --no-pdf --out export/dark
Terminal window
bunx kadal-deck export --range 1,3-5 --dark --png --no-pdf --out export/dark
Flag What it does
--range 1,3-5 only these slides, counted from 1 in play order; 8- runs to the end
--dark, --scheme light the colour scheme, whatever the viewer’s default would be
--with-clicks, --no-with-clicks a page per click step, or one per slide
--omit-background transparent pages: no page colour and no background layer (for PNGs over your own design)
--out <dir>, --output <name> the folder (default export/) and the files’ base name

The example writes 9 dark PNGs: slide 1, then slides 3 to 5 with their steps. The Export reference lists every flag, including timeouts and a Chrome of your own.

7. Export from the browser, with nothing installed

Section titled “7. Export from the browser, with nothing installed”

Every deck has an export page at /export beside it: http://localhost:5173/export while you run npm run devpnpm devyarn devbun run dev, or https://decks.kadal.cc/@you/my-talk/export for a published deck. It needs no Playwright. Pick the range, the click steps, the colour scheme, whether to include notes, the picture size and a transparent background, watch the live preview, and save:

  • PDF through the browser’s print dialog;
  • PNG, a zip with one picture per page;
  • PPTX, one picture per slide with the notes;
  • Markdown with the pictures.

Long exports show their progress and can be cancelled. Right-click any slide and choose Export to get there. The browser exporter makes picture PowerPoint files only; the editable one needs the command line.

Add download: true to the headmatter:

---
title: My talk
download: true
---

A Download button appears beside the theme menu, and kadal-deck build prints dist/deck.pdf for it (about seven more seconds of build for the starter deck). Without that PDF, the button opens the deck’s /export page instead. kadal-deck build --download prints the PDF without the key, and --no-download skips it. download: talk.pdf (a file in public/) or a URL links a PDF you made yourself.

On deck.kadal.cc the button is a paid-plan feature: on Starter, Pro and Team it shows when the deck asks for one; on Free it never shows. See Pricing.

A live web page on a slide (layout: iframe-right with a url:, or <Iframe>) can’t be live in a PDF. Before each export the engine photographs every embedded page at the size of its pane and saves it to public/posters/, and the PDF, PNGs, PPTX, the overview and the presenter’s next-slide box show that picture:

poster https://example.com at 960×1080
→ public/posters/v03177@960x1080.jpg
poster 1 embedded page(s), 1 captured

Commit public/posters/ so the pictures ship with the deck. --posters only captures them and stops, --refresh-posters takes them again, and poster: shots/map.jpg on the slide uses a picture of your own. YouTube videos, posts and Bluesky embeds get posters the same way.

The export runs headless, so CI can do it. This GitHub Actions workflow exports a PDF and a PowerPoint file and keeps them with the run:

.github/workflows/export-deck.yml
name: Export the deck
on:
push:
branches: [main]
jobs:
export:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npx playwright install --with-deps chromium
- run: npx kadal-deck export --pptx --json
- uses: actions/upload-artifact@v4
with:
name: deck
path: export/

--json prints one JSON object (the files, the page count) for a later step to read; the progress goes to the log.

Send feedback