Quickstart
Scaffold a deck with deckard init, run it, and change a slide.
deckard init writes a Next.js app with a sample deck in it, installs the dependencies, makes the first commit, and typechecks the result.
Scaffold a deck
Run init
npx @thebuilder/deckard-cli init my-talkinit installs with whichever package manager invoked it. Through npx that is npm, through pnpm dlx it is pnpm. It writes no packageManager field, so the deck is not locked to that choice, and later deckard commands read the lockfile.
Start the dev server
cd my-talk
npm run devThe app redirects / to the first slide. Arrow keys move through the deck.
Edit a slide
Open deck/slides.tsx. Change the title of the first entry and save. The open slide updates.
What it writes
- my-talk/
- app/
- slides/
- blocks/ (the block families, yours to edit)
- [id]/page.tsx
- presenter/page.tsx
- page.tsx
- sitemap.ts
- not-found.tsx
- layout.tsx
- globals.css
- slides/
- deck/
- deck.ts (the defineDeck config)
- slides.tsx (the slide array)
- lib/utils.ts
- public/
- components.json
- next.config.ts
- package.json
- app/
The theme is not a file. init writes it as an import from @thebuilder/deckard-themes in deck/deck.ts, so --theme phosphor changes one identifier.
init flags
| Flag | Default | What it does |
|---|---|---|
--theme <name> |
meridian |
Any built-in, listed on the theme gallery. |
--empty |
off | A bare deck instead of the sample one. |
--package-manager <name> |
detected | bun, npm, pnpm, or yarn. |
--no-install |
install runs | Write the files and stop. Skips the typecheck too. |
--no-git |
git runs | Skip git init and the first commit. |
--registry <url> |
https://deckard.thebuilder.dk/r/{name}.json |
The @deckard registry written into components.json. |
--core-tarball <path> |
^<cli version> |
Install @thebuilder/deckard-core from a local tarball instead of npm. |
--themes-tarball <path> |
^<cli version> |
Same, for @thebuilder/deckard-themes. |
--cli-tarball <path> |
^<cli version> |
Same, for @thebuilder/deckard-cli. |
init refuses a directory that already has files in it. It asks no questions.
The blocks
The slide blocks ship inside the CLI package, and init copies them into app/slides/blocks/, where they are source you edit. Adding a block later fetches it from the registry the docs site serves. See Blocks and the registry.
Adding a deck to an app you already have
init writes a new directory. Do the same four things by hand when the deck has to live inside an existing Next.js app.
Install the packages
pnpm add @thebuilder/deckard-core @thebuilder/deckard-themes
pnpm add -D @thebuilder/deckard-cli playwright pdf-libplaywright and pdf-lib are what check-overflow, screenshots, contact-sheet, and export pdf load from the deck. Leave them out if the deck will only ever be presented.
Import the stylesheet
@import "tailwindcss";
@import "@thebuilder/deckard-core/styles.css";That sheet carries the --slide-* token contract and registers the package’s own compiled output as a Tailwind source, so the runtime’s utility classes survive without you naming a path inside node_modules. There is no transpilePackages entry to add.
Install the slide blocks
pnpm dlx shadcn@latest add https://deckard.thebuilder.dk/r/preset-blocks.jsonThis writes the block source and its barrel to app/slides/blocks/. The Introduction imports from that barrel.
Write the deck
Create deck/deck.ts and deck/slides.tsx as shown on the Introduction.
Re-export the four routes
import { createSlideRoute } from "@thebuilder/deckard-core/next"
import { deck } from "@/deck/deck"
const { Page, generateMetadata, generateStaticParams } =
createSlideRoute(deck)
export { generateMetadata, generateStaticParams }
export default PageThe other three are app/presenter/page.tsx, app/sitemap.ts, and app/page.tsx. See Route adapters.
Run deckard doctor afterwards. It checks exactly these things and names the one you missed.