This guide is the deep reference for the people who operate, extend, deploy, or contribute to Slidev — DevOps engineers wiring it into CI/CD, theme and addon authors, and developers working on the codebase itself. It documents the architecture, the complete configuration surface, the rendering pipeline internals, extension points, deployment, and security considerations.
For day-to-day authoring (writing slides, presenting, exporting), see the companion Slidev User Guide.
1. Executive Summary
Slidev is a Markdown-driven, web-based presentation tool for developers. A presentation
is a single Markdown file that Slidev parses into slides and renders as a
Vue 3 application served by Vite. The same
codebase powers three runtime modes — dev (interactive presenter server), build
(static single-page app), and export (headless-browser rendering to PDF/PNG/PPTX/MD).
Key characteristics for operators:
- Monorepo, several npm packages. The product ships as
@slidev/cliplus the supporting@slidev/parser,@slidev/types,@slidev/client, and a VS Code extension. (This documented repository is the engine; the end-user documentation site lives in a separate repository, slidevjs/docs, published at sli.dev.) - Build tooling, not a server runtime. There is no application server, database, or
hosted backend.
slidevruns a Vite dev server locally for authoring;slidev buildemits static files you host anywhere;slidev exportdrives a local headless browser. - Config-as-code. A deck is configured entirely from the first slide's YAML
headmatter and optional
setup/*.tshook files in the user's project — there is no separate config service. - Node.js ≥ 20.12.0, MIT licensed (© 2021 Anthony Fu).
2. Architecture
2.1 High-level data flow
slides.md (+ imported *.md via `src:`)
│
┌─────────────▼──────────────┐
│ @slidev/parser │ parse() splits on `---`,
│ - parse / parseSync │ extracts frontmatter, notes,
│ - load (fs, resolves src) │ detects features, loads imports
│ - resolveConfig │
└─────────────┬──────────────┘
│ SlidevData { slides, config, headmatter, features }
┌─────────────▼──────────────┐
│ @slidev/cli (node) │ resolveOptions(): merge theme +
│ - resolveOptions / roots │ addon + user roots; build the
│ - ViteSlidevPlugin │ Vite config; define feature flags
└─────────────┬──────────────┘
│
┌────────────────────────────┼────────────────────────────┐
▼ dev ▼ build ▼ export
Vite dev server vite build → dist/ Playwright Chromium
@slidev/client SPA static SPA + 404.html renders /print routes →
presenter / overview / + _redirects + og-image PDF / PNG / PPTX / MD
drawing / remote control (+ optional download PDF) (+ outline, metadata)
2.2 Package responsibilities
| Package | Path | Responsibility |
|---|---|---|
@slidev/cli |
packages/slidev |
The slidev binary: command parsing (yargs), option/roots resolution, the Vite plugin, and the serve/build/export commands. |
@slidev/parser |
packages/parser |
Pure Markdown→slides parsing, frontmatter/notes extraction, feature detection, config resolution, and the fs loader that follows src: imports. No browser dependencies. |
@slidev/types |
packages/types |
Shared TypeScript types: the config/headmatter schema, CLI argument shapes, setup-hook signatures, and the navigation API. The single source of truth for the configuration surface. |
@slidev/client |
packages/client |
The Vue 3 front-end: the slide renderer, presenter mode, overview, drawing tool, editor, monaco/shiki/katex setup, navigation, and state. |
| Slidev for VS Code | packages/vscode |
The editor extension: project detection, preview webview, a Volar-based language server, and AI language-model tools. |
create-app / create-theme |
packages/create-* |
Scaffolders behind npm init slidev and theme creation. |
The repository is a pnpm workspace (pnpm-workspace.yaml) spanning packages/*,
demo/*, cypress/fixtures/*, and docs, with a shared dependency catalog.
2.3 Roots resolution model
At startup the CLI resolves a set of roots that are layered to produce the final
configuration and asset search path (packages/slidev/node/options.ts,
resolver.ts):
userRoot— the directory containing the entry Markdown file.themeRoots— the resolved theme package (if any).addonRoots— every addon listed in theaddonsheadmatter.clientRoot—@slidev/clientitself (the built-in components/layouts).
The effective roots array is [...themeRoots, ...addonRoots, userRoot]. Vite configs,
layouts, components, and setup/*.ts files are discovered across all roots and merged,
so themes and addons can contribute to any of them, with the user's project taking
precedence.
2.4 Feature flags
The CLI computes compile-time feature flags from config and mode
(getDefine() in options.ts) and injects them as __SLIDEV_FEATURE_* defines:
| Define | Driven by |
|---|---|
__SLIDEV_FEATURE_DRAWINGS__ |
drawings.enabled matched against the current mode. |
__SLIDEV_FEATURE_DRAWINGS_PERSIST__ |
drawings.persist. |
__SLIDEV_FEATURE_EDITOR__ |
editor !== false and dev mode only. |
__SLIDEV_FEATURE_RECORD__ |
record. |
__SLIDEV_FEATURE_PRESENTER__ |
presenter. |
__SLIDEV_FEATURE_PRINT__ |
export mode, or build mode with download truthy. |
__SLIDEV_FEATURE_BROWSER_EXPORTER__ |
browserExporter. |
__SLIDEV_FEATURE_WAKE_LOCK__ |
wakeLock. |
__SLIDEV_HAS_SERVER__ |
true except in build mode. |
Options whose values are 'dev' / 'build' enable the feature only in that mode —
this is how, for example, presenter: 'dev' keeps presenter mode out of a public build.
3. Requirements
| Requirement | Detail |
|---|---|
| Node.js | ≥ 20.12.0 (engines.node). Netlify builds in the repo pin Node 24. |
| Package manager | Any (npm/pnpm/yarn). The repo itself uses pnpm with a catalog. |
| Browser | A modern evergreen browser to view decks. |
| Export engine | playwright-chromium (peer/optional) — required only for slidev export and build --download. |
| Memory | Large decks build comfortably; the repo's own docs build sets --max-old-space-size=8192 for the combined site build. |
Note
playwright-chromiumhas a post-install step that downloads a browser. pnpm v11 blocks unapproved build scripts by default; scaffolded projects allowlist it inpnpm-workspace.yaml(allowBuilds: { playwright-chromium: true }).
4. Configuration Reference (Headmatter)
The first slide's frontmatter is the headmatter and configures the whole deck. The
table below is the complete option set with the actual runtime defaults from
getDefaultConfig() (packages/parser/src/config.ts) and the schema in
packages/types/src/frontmatter.ts. Options typed boolean | 'dev' | 'build' enable
the feature globally (true), only in the dev server ('dev'), or only in a static
build ('build').
4.1 Identity & metadata
| Option | Default | Type | Description |
|---|---|---|---|
theme |
'default' |
string | Theme package, local path, or none. |
title |
'Slidev' |
string | Deck title (supports inline Markdown). |
titleTemplate |
'%s - Slidev' |
string | Template for the page <title>; %s is the title. |
author |
'' |
string | Author; embedded in exported PDF/PPTX metadata. |
info |
false |
string | boolean | Info shown on the built SPA (Markdown allowed). |
favicon |
jsDelivr Slidev icon URL | string | Favicon URL. |
seoMeta |
{} |
object | Open Graph / Twitter card meta (ogTitle, ogImage, twitterCard, …). ogImage: 'auto' auto-generates a preview at build. |
4.2 Appearance & layout
| Option | Default | Type | Description |
|---|---|---|---|
colorSchema |
'auto' |
auto/light/dark/all |
Force or auto-detect the color scheme. |
aspectRatio |
16/9 |
number | string | Slide aspect ratio (16/9, 1:1, 3x4). |
canvasWidth |
980 |
number | Logical canvas width in px (height derives from aspect ratio). |
selectable |
false |
boolean | Whether slide text is selectable. |
htmlAttrs |
{} |
object | Attributes applied to the <html> element. |
fonts |
{} |
object | Web font config (sans/serif/mono/weights/provider/local/fallbacks). Default provider google, default weights 200,400,600. |
themeConfig |
{} |
object | Theme-specific options injected as --slidev-theme-* CSS vars. |
transition |
null |
string | object | Default page transition. |
clickAnimation |
'' |
string | Default per-click animation. |
4.3 Code & rendering
| Option | Default | Type | Description |
|---|---|---|---|
highlighter |
'shiki' |
'shiki' |
Syntax highlighter. prism is removed (throws); shikiji auto-migrates with a warning. |
twoslash |
true |
boolean/dev/build | Enable TwoSlash type hovers in TS code. |
lineNumbers |
false |
boolean | Show line numbers in code blocks. |
codeCopy |
true |
boolean | Copy button on code blocks. |
magicMoveCopy |
true |
boolean / 'final' / 'always' |
Copy button behavior on Magic Move blocks. |
magicMoveDuration |
800 |
number | Magic Move transition duration (ms). |
monaco |
true |
boolean/dev/build | Enable the Monaco editor for {monaco} blocks. |
monacoTypesSource |
'local' |
cdn/local/none |
Where Monaco loads type definitions from. |
monacoTypesAdditionalPackages |
[] |
string[] | Extra packages to load as Monaco types. |
monacoTypesIgnorePackages |
[] |
string[] | Packages (glob) to skip when loading types. |
monacoRunAdditionalDeps |
[] |
string[] | Extra local modules available to {monaco-run}. |
monacoRunUseStrict |
true |
boolean | Run {monaco-run} code in strict mode. |
plantUmlServer |
https://www.plantuml.com/plantuml |
string | PlantUML rendering server. |
mdc |
false |
boolean | Deprecated — use comark. |
comark |
false |
boolean | Enable Comark (MDC-style) Markdown syntax. |
css |
'unocss' |
'unocss' |
Deprecated/fixed — Atomic CSS engine (only UnoCSS; other values warn and fall back). |
4.4 Presenting & interaction
| Option | Default | Type | Description |
|---|---|---|---|
presenter |
true |
boolean/dev/build | Enable presenter mode. |
editor |
true |
boolean | Enable the built-in editor (dev only at runtime). |
contextMenu |
null |
boolean/dev/build/null | Enable the right-click context menu. |
wakeLock |
true |
boolean/dev/build | Keep the screen awake while presenting. |
record |
'dev' |
boolean/dev/build | Enable camera recording. |
drawings |
{} |
object | Drawing tool: enabled (default true), persist (default false, or a path), presenterOnly (default false), syncAll (default true). |
duration |
'30min' |
string | number | Expected talk duration (for the timer). |
timer |
'stopwatch' |
stopwatch/countdown |
Presenter timer mode. |
notesAutoRuby |
{} |
object | Map of words → ruby readings, auto-applied to notes. |
remote |
false |
string | boolean | Listen on the network; a string sets the presenter password. |
4.5 Build, export & routing
| Option | Default | Type | Description |
|---|---|---|---|
routerMode |
'history' |
hash/history |
Vue Router mode. Use hash for sub-directory deploys. |
download |
false |
boolean | string | Show a download button on the built SPA; a string is a custom PDF URL. |
exportFilename |
'' |
string | Force the export filename (extension auto-added). |
export |
{} |
object | Default export options applied to the export command. |
browserExporter |
'dev' |
boolean/dev/build | Enable the in-browser /export/ exporter. |
remoteAssets |
false |
boolean/dev/build | Download remote assets locally via vite-plugin-remote-assets. |
preloadImages |
true |
boolean | { ahead?: number } |
Preload upcoming slide images (default look-ahead 3). |
addons |
[] |
string[] | Slidev addons to load. |
Important
Changing any of
monaco,routerMode,fonts,css,mdc,editor,theme, orseoMetain the headmatter triggers a dev-server restart (these are inCONFIG_RESTART_FIELDS). A theme change or a katex/monaco feature change also restarts. This is expected behavior, not a fault.
4.6 Per-slide frontmatter
Every non-first slide accepts the per-slide keys (layout, class, transition,
clicks, clicksStart, hide/disabled, hideInToc, title, level, routeAlias,
zoom, src, image/background, dragPos, …). These are documented in the User
Guide, §3.2. disabled/hide slides are dropped from the rendered slides array;
src slides are replaced by the imported file's slides.
5. The Rendering Pipeline (Internals)
5.1 Parsing (@slidev/parser)
parse() (core.ts) splits the Markdown on lines equal to ---, while correctly
skipping --- inside fenced code blocks and HTML comments. For each slide it:
- Extracts frontmatter (either a
---fenced block or a leading```yamlblock). - Detects a trailing HTML comment as the slide's note.
- Derives
title/levelfrom frontmatter or the first heading. - Extracts image URLs from frontmatter, Markdown, Vue props, and CSS
url()(so build's content stripping doesn't lose them). - Computes a content
revisionhash for HMR.
detectFeatures() scans the combined source for KaTeX ($…$/$$), Monaco
({monaco…}), Mermaid (```mermaid), and Tweet/Bluesky tags, returning a
SlidevDetectedFeatures record that gates which heavy machinery loads.
load() (fs.ts) resolves src: imports recursively (with #range slicing via
parseRangeString), applies frontmatter overrides down the import chain, records
watchFiles for HMR, and runs any preparser extensions.
resolveConfig() (config.ts) merges, in increasing precedence:
default config → theme defaults → headmatter.config → headmatter top-level — then
resolves fonts, drawings, htmlAttrs, and themeConfig sub-objects and normalizes the
aspect ratio. verifyConfig() warns on theme/highlighter/color-schema mismatches.
5.2 Serving (commands/serve.ts)
createServer() builds a Vite dev server from the merged config
(resolveViteConfigs() in shared.ts), which loads every root's vite.config.*,
merges them, and mounts ViteSlidevPlugin. The dev command (cli.ts) wires a
loadData callback that re-parses on change and decides whether to hot-update or restart
(theme/config/feature changes force a restart). A chokidar watcher restarts on
add/remove of watched setup/config files.
5.3 Building (commands/build.ts)
build() runs vite build with the generated index.html, then post-processes the
output directory:
- Generates or copies the SEO
ogImage(rendering one slide to PNG via the exporter whenogImage: 'auto'). - Copies
index.html→404.html(so GitHub Pages serves the SPA on deep links). - Writes a
_redirectsfile ({base}* {base}index.html 200) for Netlify-style SPA routing, unless one already exists. - When
downloadis truthy, servesdist/locally withsirvand runs the exporter to bundle a downloadable PDF.
5.4 Exporting (commands/export.ts)
Export launches Playwright Chromium and navigates the running server's print routes:
- Formats:
pdf(default),png,pptx,md. PPTX renders slides to PNG and assembles a deck withpptxgenjs, carrying titles/notes; MD emits image references plus notes. - One-piece vs
--per-slide: by default the whole deck renders as one print page;--per-sliderenders each slide separately (better for some global components but breaks cross-slide links and the PDF outline). - Clicks:
--with-clicksdrivesArrowRightto capture each animation step. - TOC:
--with-tocbuilds a nested outline from slide titles/levels and injects it with@lillallol/outline-pdf. - Metadata: the first slide's
title/author/info/keywordsare written into the PDF metadata. - Robust waits: the renderer waits for
.slidev-slide-loadingto clear, honorsdata-waitfor, waits for iframes and Mermaid containers, and hides Monaco aria nodes before capture.--wait/--wait-until/--timeouttune timing.
playwright-chromium is resolved from the user root, the workspace root, the global
registry, and finally the CLI's own install — failing with an actionable install message.
6. Customization & Extension
6.1 Setup hooks
Place TypeScript files under setup/ in your project (or theme/addon) and export a
define*Setup function. These are the supported hooks (packages/types/src/setups.ts):
| File / hook | Customizes |
|---|---|
setup/shiki.ts → defineShikiSetup |
Shiki languages, themes, transformers. |
setup/katex.ts → defineKatexSetup |
KaTeX options. |
setup/unocss.ts (uno.config.ts) → defineUnoSetup |
UnoCSS configuration. |
setup/monaco.ts → defineMonacoSetup |
Monaco editor options. |
setup/main.ts → defineAppSetup |
Vue app/router setup (install plugins). |
setup/root.ts → defineRootSetup |
Root-component setup. |
setup/routes.ts → defineRoutesSetup |
Modify the generated routes. |
setup/mermaid.ts → defineMermaidSetup / defineMermaidRendererSetup |
Mermaid config or a custom renderer. |
setup/shortcuts.ts → defineShortcutsSetup |
Add/replace keyboard shortcuts (receives the nav API). |
setup/transformers.ts → defineTransformersSetup |
Markdown/code-block transformers. |
setup/preparser.ts → definePreparserSetup |
Preparser extensions (transform raw lines/slides/notes before parsing). |
setup/vite-plugins.ts → defineVitePluginsSetup |
Inject custom Vite plugins. |
setup/code-runners.ts → defineCodeRunnersSetup |
Register runners for {*-run} blocks. |
setup/context-menu.ts → defineContextMenuSetup |
Customize the right-click menu. |
Warning
Editing
setup/shiki.ts,setup/katex.ts,setup/preparser.ts,setup/transformers.ts,setup/unocss.ts,setup/vite-plugins.ts,uno.config.ts,unocss.config.ts, orvite.config.*triggers a full dev-server restart (they are inFILES_CHANGE_RESTART). HMR does not apply to these.
6.2 Layouts and components
Any .vue file in a layouts/ folder across the roots becomes a usable layout: value
(layouts are globbed and cached). Components in a components/ folder are auto-imported
(via unplugin-vue-components) and usable directly in Markdown.
6.3 Code runners
{monaco-run} and custom {lang-run} blocks dispatch to runners registered via
defineCodeRunnersSetup. A runner returns HTML, text, a DOM element, or an error. The
context provides a highlight() helper and a run() to delegate to other runners.
Caution
A runner's
CodeRunnerOutputHtmlis rendered without sanitization — Slidev's own type docs state it does not sanitize the HTML for you. Only return HTML from trusted sources, or sanitize it in your runner. See §8.
6.4 Themes and addons
- Themes are npm packages named
@slidev/theme-*(official) orslidev-theme-*(community), or local folders. A theme'spackage.jsoncarries aslidevfield (SlidevThemeMeta) withdefaults,colorSchema, andhighlighter. - Addons are listed in the
addonsheadmatter and contribute slides, components, layouts, and setup hooks via the same roots mechanism. slidev theme ejectcopies the active theme into a localtheme/folder and rewrites the deck'stheme:to point at it.
7. Operations
7.1 Running modes
| Command | Mode | Notes |
|---|---|---|
slidev [entry] |
dev | Vite dev server, default port 3030 (auto-scans 3030–4000). Prints public/presenter/overview/export URLs. |
slidev build [entry..] |
build | Emits a static SPA to dist/ (or --out). Accepts multiple entries. |
slidev export [entry..] |
export | Headless render to PDF/PNG/PPTX/MD. |
slidev export-notes [entry..] |
export | Renders presenter notes to PDF. |
slidev format [entry..] |
— | Re-serializes Markdown through the parser. |
slidev theme eject |
— | Ejects the theme locally. |
7.2 Environment variables
| Variable | Effect |
|---|---|
EDITOR |
Editor opened by the dev e shortcut and by the editor integration; defaults to code (VS Code). Set in serve.ts. |
There are no required secrets or service credentials — Slidev has no backend.
7.3 Networking & remote control
--remote switches the listen host to --bind (default 0.0.0.0) and enables
presenter remote control; pass --remote <password> to gate presenter mode. --tunnel
opens a Cloudflare Quick Tunnel (requires --remote) for a public URL. The startup
banner enumerates LAN URLs and the public IP; the c shortcut prints a QR code.
7.4 Global installs
The resolver (resolver.ts) deliberately handles global installs across npm/yarn and
pnpm v11's isolated globals layout, discovering sibling install groups so a globally
installed theme can be found alongside a globally installed @slidev/cli. This matters
when operators install Slidev with pnpm add -g.
8. Security
Slidev produces and runs web content; treat decks like code. Operator-relevant considerations, grounded in the source:
- Theme/addon name validation. Package names are validated against a strict npm-name
regex (
RE_SAFE_PKG_NAME) before resolution. Names with shell metacharacters, backslashes, uppercase letters, parent-traversal segments, or extra slashes are rejected withInvalid theme/addon name … Only valid npm package names are allowed.This blocks command/path injection via thetheme/addonsconfig. - Interactive install prompts. Missing themes/addons (and a missing entry file) trigger an install/create prompt only in an interactive TTY; non-interactive environments hard-fail instead of running an unattended install — safe for CI.
- Unsanitized HTML in code-runner output. Custom runners that return
CodeRunnerOutputHtmlare rendered as-is (no sanitization). Only enable trusted runners; sanitize untrusted output yourself. - Arbitrary code execution by design.
{monaco-run}executes code in the browser;monacoRunUseStrict(default true) only sets strict mode. This is intended for trusted, author-controlled decks — do not load untrusted slide sources. - Remote exposure.
--remoteexposes presenter control on the network and--tunnelpublishes a public URL. Always set a presenter password on untrusted networks; tunnels last only for the session. - External services. PlantUML rendering posts diagram source to
plantUmlServer(default the publicplantuml.comserver) — point it at a self-hosted instance for sensitive content.remoteAssetsand the defaultfaviconfetch from remote URLs/CDNs; setremoteAssetsand a local favicon to keep builds self-contained. Web fonts default to Google Fonts (fonts.provider); useprovider: noneorfonts.localto avoid third-party font requests.
Important
Slidev has no authentication, authorization, or multi-tenant model — it is a local authoring tool and a static-site generator. Security of a published deck is the security of the static host you deploy it to.
9. Deployment
slidev build emits a self-contained static SPA. Deploy dist/ to any static host.
9.1 Sub-path deploys (GitHub Pages, project sites)
slidev build --base /my-talk/ --router-mode hash
--base must start and end with /. hash routing avoids server-side rewrite
requirements; the emitted 404.html covers history-mode deep links on GitHub Pages.
9.2 Netlify
Scaffolded projects ship a netlify.toml:
[build]
publish = "dist"
command = "npm run build"
[build.environment]
NODE_VERSION = "20"
The build also writes a _redirects file for SPA fallback.
9.3 Vercel
Scaffolded projects ship a vercel.json that rewrites all routes to index.html:
{
"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }],
"buildCommand": "npm run build",
"outputDirectory": "dist"
}
9.4 Deployment checklist
- [ ]
slidev buildsucceeds locally anddist/renders when served statically. - [ ]
--baseset (with leading/trailing/) if deploying under a sub-path. - [ ]
--router-mode hashfor GitHub Pages project sites (or rely on404.html). - [ ]
--without-notesif speaker notes must not ship publicly. - [ ]
--download(ordownload: true) if you want a downloadable PDF + button. - [ ] SEO
seoMeta/ogImageset for link previews. - [ ] Node version on the host ≥ 20.12.0.
10. Developer Internals
10.1 Repository layout
| Path | Contents |
|---|---|
packages/slidev/node |
CLI, command implementations, options/roots resolution, Vite plugin, syntax/vite/virtual sub-systems. |
packages/parser/src |
core.ts (parse), fs.ts (load + imports), config.ts (defaults + resolve), utils.ts (ranges, aspect ratio), timesplit. |
packages/types/src |
Config/frontmatter/cli/setups/options/clicks/code-runner/toc/transform/vite types. |
packages/client |
Vue front-end: internals/, setup/, state/, styles/, layouts/, builtin/, composables/, logic/, modules/, pages/. |
packages/vscode |
Extension src/, Volar language-server/, schema/syntaxes. |
packages/create-app, packages/create-theme |
Scaffolders + templates. |
demo/* |
Example decks used as fixtures and showcases. |
docs/ |
VitePress source for sli.dev (separate publishable site). |
cypress/, test/ |
E2E (Cypress, baseUrl :3041) and unit tests (Vitest). |
10.2 Build & tooling
- Bundling:
tsdown(ESM,target: node20, dts) for the node packages. - Tests: Vitest projects across
packages/*andtest; Cypress E2E against a fixture served on port 3041. - Lint/format:
@antfu/eslint-config, including a Slidev formatter forslides.mdfixtures. - Release:
bumpp, withovsx/vscefor the VS Code extension;tazefor dep bumps. - Key runtime deps: Vue 3, Vue Router, Vite, Shiki (+ TwoSlash, magic-move), Monaco,
KaTeX, Mermaid, UnoCSS, yargs, chokidar, Playwright (export), pdf-lib + outline-pdf,
pptxgenjs, Drauu (drawings), RecordRTC (recording),
@vueuse/*.
10.3 Code patterns worth knowing
- Config-as-code with a single schema source.
HeadmatterConfig/Frontmatterin@slidev/typesis the canonical schema; the VS Code extension even generates itsheadmatter.jsonJSON-schema from it (packages/vscode/scripts/schema.ts), so editor validation never drifts from the runtime. - Mode-aware feature gating. The
'dev'/'build'tri-state on many options, resolved into__SLIDEV_FEATURE_*defines, keeps the client bundle lean and lets a single config express "dev-only" behavior. - Reactive VS Code extension. The extension uses
reactive-vscode(Vue reactivity in the extension host) and a Volar language server, with project state as reactiveMaps/refs.
10.4 Testing strategy
Parser logic is unit-tested (range parsing, aspect ratios, resolver path logic with a
mocked filesystem — note the extensive findInvocationNodeModulesPath /
computeInvocationSearchPaths suites for pnpm/npm/yarn global-install layouts). E2E
coverage runs through Cypress against a built fixture. New CLI flags or config keys should
add a parser/option test and, ideally, an E2E assertion.
11. Known Issues & Improvement Areas
Sourced from the issue tracker (community-confirmed) at the documented commit:
| Area | Signal | Reference |
|---|---|---|
| ESM/CJS interop | Dev server imports @fix-webm-duration/fix as a named ESM export. |
#2617, #2569 |
| Magic Move | Code-snippet inclusions in Magic Move regressed in a recent release. | #2586 |
| Theme assets in pnpm workspaces | vite-plugin-static-copy path resolution for theme public/ assets. |
#2607 |
| Windows first-run | Scaffolder uses slidev --open, which can fail on Windows. |
#2582 |
| Public assets | Loading public/ assets outside frontmatter. |
#2616 |
| PDF reactivity | useNav().currentSlideNo not reactive during PDF export. |
#1776 |
| One-piece PDF | Named-slot <img> can disappear with container padding. |
#2588 |
Frequently-requested capabilities include multi-presenter sync (#2611), single-file HTML export (#2581), and VS Code slide reordering/deletion (#2529).
Note
Two config fields are marked deprecated in the schema and should be migrated:
css(fixed tounocss) andmdc(replaced bycomark). Theprismhighlighter is fully removed and throws.
12. Quick Reference
Commands
slidev [entry] # dev server (default)
slidev build [entry..] # static SPA → dist/
slidev export [entry..] # PDF/PNG/PPTX/MD
slidev export-notes … # notes → PDF
slidev format [entry..] # reformat markdown
slidev theme eject # eject theme locally
Dev URLs (default port 3030)
/ public slide show
/presenter/ presenter mode
/overview/ slides overview
/export/ in-browser exporter
/__inspect/ Vite inspector (with --inspect)
Restart triggers (dev)
config: monaco, routerMode, fonts, css, mdc, editor, theme, seoMeta (+ theme/katex/monaco feature change)
files: setup/{shiki,katex,preparser,transformers,unocss,vite-plugins}.ts,
uno.config.ts, unocss.config.ts, vite.config.* (+ add/remove of watched files)
Build artifacts
dist/index.html, dist/404.html (GH Pages), dist/_redirects (Netlify SPA),
og-image (when seoMeta.ogImage), optional downloadable PDF (--download)
Key paths
packages/slidev/node/cli.ts command definitions (yargs)
packages/parser/src/config.ts getDefaultConfig() — defaults
packages/types/src/frontmatter.ts HeadmatterConfig — schema + docs
packages/slidev/node/commands/*.ts serve / build / export