npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@n4ze3m/react2pptx

v0.7.0

Published

Export a React Router slide deck (Vite app) to an editable .pptx file. CLI + programmatic API.

Downloads

1,154

Readme

react2pptx

Export a React Router slide deck (built with Vite) to an editable PowerPoint file.

The exporter walks the DOM and emits native PPTX text boxes, shapes, and images — not screenshots. Recipients can open the result in PowerPoint or Keynote and edit text, restyle shapes, copy slides, and re-flow content.

Installation

npm install -D react2pptx
# or
pnpm add -D react2pptx

Every runtime dependency (pptxgenjs, playwright-core, yaml) is pulled in automatically. The only thing you need on your machine is a Chrome/Chromium/Edge install — react2pptx finds it for you on Linux, macOS, and Windows.

CLI

react2pptx [projectDir] [-o output.pptx]

Examples:

react2pptx                                  # export ./ to ./deck.pptx
react2pptx . -o presentation.pptx
react2pptx ./apps/marketing -o out.pptx
react2pptx --url http://localhost:5173 -o deck.pptx   # capture against a running server

Run react2pptx --help for the full flag list.

Configuration via slide.yml

Drop a slide.yml in your project root to customize the pipeline (e.g. for Next.js, Astro, or a non-default port). Every field is optional:

enable: true          # gate for `react2pptx validate`; set false to disable
build: vite build
preview: vite preview --port {port} --host 127.0.0.1 --strictPort
routePattern: /slide/{i}?export=1
layout: LAYOUT_16x9
output: deck.pptx
timeoutSec: 30

See slide.example.yml shipped with this package for the annotated schema.

CLI flags take precedence over slide.yml; slide.yml takes precedence over built-in defaults.

Gating validate with enable

react2pptx validate only runs when enable: true (the default). If your project ships enable: false, the command refuses with:

Error: `react2pptx validate` is disabled. Set `enable: true` in slide.yml to enable it.

Other commands (the default export) ignore this field.

Project conventions

The exporter discovers slides by hitting /slide/0, /slide/1, ... and looks for two DOM signals on each page:

  • [data-slide-root] — the element it should measure and walk.
  • [data-total="N"] on the same element — the total slide count.

For slides that load data asynchronously, also set [data-slide-ready="true"] once the slide is fully rendered. The exporter waits up to timeoutSec seconds for this attribute to appear.

A minimal slide host looks like this:

// src/components/SlideDeck.tsx
import { useParams } from 'react-router';

export function SlideDeck({ slides }: { slides: React.ComponentType[] }) {
  const { id = '0' } = useParams();
  const index = parseInt(id, 10);
  const Slide = slides[index];
  return (
    <div data-slide-root data-total={slides.length} style={{ width: 960, height: 540 }}>
      <Slide />
    </div>
  );
}

Programmatic API

import pptxgen from 'pptxgenjs';
import { react2pptx, exportJob } from 'react2pptx';

// Option A: full pipeline (build + preview + capture)
await exportJob('./my-slide-project', { output: 'deck.pptx' });

// Option B: capture against an already-running server, with a custom
// `onSlide` hook for injecting native PowerPoint charts into placeholders.
const pres = new pptxgen();
pres.layout = 'LAYOUT_16x9';
await react2pptx('http://localhost:5173', pres, {
  onSlide({ slide, placeholders, index }) {
    const chartHere = placeholders.find((p) => p.id === 'revenue-chart');
    if (chartHere) {
      slide.addChart(pres.charts.BAR, [/* ... */], chartHere);
    }
  },
});
await pres.writeFile({ fileName: 'deck.pptx' });

Fidelity

This exporter is editable, not pixel-perfect — see the design notes shipped alongside the source. The TL;DR:

  • Use fonts that ship with Office (Calibri, Aptos, Arial, Georgia, Cambria, Consolas) for predictable rendering on every machine.
  • Leave 4–8 px of slack in tight text boxes; PowerPoint's text shaper differs slightly from Chrome's.
  • Wrap text in <p> / <h1><h6> / <ul> / <ol>; bare text in <div> is rejected.
  • Box styling (background/border/shadow/radius) goes on <div>; text styling goes on the text element.
  • CSS gradients, filters, blend modes, clip-path, and gradient text are auto-rasterized: those elements are screenshotted and embedded as PNGs at the same position, so the slide still looks right — they just aren't editable as text/shape in PowerPoint.

The CLI will print every validation issue it finds, with the slide index and the source of the problem, so you can fix them at authoring time instead of debugging a broken .pptx.

Bitmap fallback (data-slide-rasterize)

If you have a subtree with CSS effects we can't translate semantically — or you simply want to flatten a section to a PNG (the way Gamma does) — add data-slide-rasterize to any element:

<div data-slide-rasterize="hero">
  <ComplicatedHeroWithBlendModesAndGradients />
</div>

The exporter takes an element-scoped screenshot, replaces the subtree with a single <img> at the same position, and embeds that PNG in the slide. Anything outside the marked subtree (titles, body copy, charts) stays as native editable PowerPoint objects.

The same fallback kicks in automatically when the walker sees filter, backdrop-filter, mix-blend-mode, clip-path, mask-image, gradient backgrounds (on non-root elements), or gradient text — so most decks Just Work without any annotation.

Requirements

  • Node.js 20 or newer
  • Chrome, Chromium, or Edge installed locally (or pointed to via CHROME_PATH)
  • A Vite project (or any other static site you can serve) with the slide conventions above

License

MIT