Create

Plugins

Use default GFM, Shiki, and Tailwind CSS; opt into Math, Charts, and Media; or add typed build and runtime capabilities.

See the output

The common path is ready by default. Specialized behavior stays explicit.

Add capability without exposing the toolchain

Presentation authors configure typed Drever plugins. They do not need to configure Vite, Remark, or Rehype directly. Plugin developers can work at those boundaries through one normalized descriptor.

A plugin may contribute:

  • Vite plugins at build time.
  • Remark, Rehype, and Recma modules for MDX compilation.
  • Components exposed to authored MDX.
  • Scoped styles.
  • Runtime and deterministic export setup.

Build-only dependencies do not enter the browser bundle. Runtime modules ship only when the resolved plan references them.

Official plugins

PluginActivationBrowser output
@drever/plugin-gfmEnabled by defaultSemantic HTML and scoped task-list CSS; no plugin JavaScript
@drever/plugin-shikiEnabled by defaultHighlighted HTML and CSS variables
@drever/plugin-tailwindcssEnabled by defaultGenerated utility CSS, without Preflight
@drever/plugin-mathExplicit opt-inAccessible HTML, MathML, CSS, and font assets
@drever/plugin-chartsExplicit opt-inSemantic SVG and presentation metrics; no charting dependency
@drever/plugin-mediaExplicit opt-inAudience iframe; stable link on non-interactive surfaces
MermaidNot implemented yetDeferred until security and export contracts are complete

GFM, Shiki, and Tailwind can be configured or disabled:

ts
import { defineConfig, gfm, shiki, shikiPlugin, tailwindCss } from "drever";

export default defineConfig({
  plugins: [
    gfm({ singleTilde: false }),
    shiki({ lightTheme: "github-light", darkTheme: "github-dark" }),
    tailwindCss({ optimize: true }),
  ],
});

// To disable the default Shiki plugin instead:
// plugins: [{ plugin: shikiPlugin, enabled: false }]

Use familiar Markdown by default

GFM adds tables, task lists, autolink literals, and strikethrough at build time. It ships no browser parser; a small component-layer stylesheet aligns task-list checkboxes across designs. Footnotes currently fail with a clear build error because document-level footnote output must not escape Drever's protected Slide boundaries.

md
| Decision      | State |
| ------------- | ----- |
| Ship the demo | Ready |

- [x] Review the live deck
- [ ] Rehearse the decision

Enable LaTeX

bash
npm install --save-dev @drever/plugin-math
ts
import { math } from "@drever/plugin-math";
import { defineConfig } from "drever";

export default defineConfig({
  plugins: [math({ strict: "warn", throwOnError: true })],
});
md
Einstein's relation is $E = mc^2$.

$$
\int_0^1 x^2\,dx = \frac{1}{3}
$$

The plugin parses LaTeX with Remark Math and renders HTML plus MathML with Rehype KaTeX at build time. It ships no client-side typesetter.

Keep chart data inspectable

bash
npm install --save-dev @drever/plugin-charts
ts
import chartsPlugin from "@drever/plugin-charts";
import { defineConfig } from "drever";

export default defineConfig({
  plugins: [chartsPlugin],
});
mdx
<DataChart
  label="Adoption by quarter"
  kind="area"
  valueSuffix="%"
  data={[
    { label: "Q1", value: 28 },
    { label: "Q2", value: 46 },
    { label: "Q3", value: 71 },
  ]}
/>

<AnimatedNumber label="Decision confidence" from={31} value={96} valueSuffix="%" duration={1200} />

DataChart accepts one to twelve labeled values and renders bar, line, area, dot, or donut SVG directly with React. Its title and complete value description come from the same data; valuePrefix and valueSuffix keep units consistent across both. AnimatedNumber gives one important value presentation-scale emphasis, with optional starting value, duration, decimals, prefix, and suffix.

The boundary is intentional: these are small, theme-aware storytelling components for comparisons, trends, rankings, proportions, and single-number changes. They do not bring a charting framework, canvas renderer, data transformation layer, multi-series grammar, tooltip system, or dashboard state into every deck. If a story genuinely needs those capabilities, import a mature React chart library in a local project component and expose only the narrow visualization the slide needs. Drever does not need to wrap or own that dependency.

Adapt media to the surface

bash
npm install --save-dev @drever/plugin-media
ts
import mediaPlugin from "@drever/plugin-media";
import { defineConfig } from "drever";

export default defineConfig({
  plugins: [mediaPlugin],
});
mdx
<YouTube id="M7lc1UVf-VE" title="YouTube player API demo" start={30} />

The active audience slide receives a lazy player from youtube-nocookie.com and never autoplays it. Leaving the slide removes its remote source so playback cannot continue over the next slide. Speaker previews, Document View, PDF export, and print receive a stable title and link instead of an iframe or remote thumbnail. The required title keeps the component accessible; invalid ids and start times fail near their source. The audience iframe still makes a third-party YouTube request: privacy-enhanced mode limits storage before playback, but does not make embedded playback private.

Why Mermaid is deferred

Drever will not insert unchecked SVG strings and call that a plugin. Mermaid needs strict security, sanitized output, collision-free IDs across speaker previews, accessible labels, useful diagnostics, and deterministic development, production, and PDF behavior. Until those contracts exist together, the official catalog does not claim Mermaid support.

Keep ownership clear

Themes own global visual language. Plugins own added behavior. Stage modules own persistent deck-specific background and foreground UI. Keeping those responsibilities separate lets a deck change its visual system without changing its delivery contract.

NextPresenting

Navigate, annotate, rehearse, and share the exact moment.