# Getting started

## Prerequisites

- **[Bun](https://bun.com) 1.3+**: liebstoeckel uses Bun as runtime, bundler, and test runner.
- A browser. (Optional: a Chromium for build-time thumbnails and PNG/PDF export, see [Chromium setup](https://docs.liebstoeckel.app/guides/chromium/).)
**Pre-1.0:** liebstoeckel is pre-1.0. Breaking changes can land in minor releases without a major
version bump; pin exact versions if a deck has to keep building unchanged.

## Scaffold a deck

The umbrella CLI scaffolds a workspace-wired deck:

1. Create a deck:

   ```bash
   liebstoeckel new my-talk            # or: bunx @liebstoeckel/cli new my-talk --brand acme
   ```

2. Install dependencies (links the workspace packages):

   ```bash
   bun install
   ```

3. Start the dev server (instant HMR + React Fast Refresh):

   ```bash
   cd my-talk && bun run dev           # http://localhost:3000 (set PORT to change it)
   ```

   To present a live session for a room instead (LAN by default, or through a
   public relay), use `liebstoeckel live my-talk`. See [Live presenting](https://docs.liebstoeckel.app/guides/live/).

A new deck looks like this:

- my-talk/
  - package.json      deps, scripts, and the `files` allowlist
  - index.html        the page shell (sets `data-brand`)
  - main.tsx          mounts `<Present>` with your slides
  - build.ts          single-file build (+ thumbnails)
  - server.ts         HMR dev server
  - bunfig.toml        dev-server plugins (tailwind + mdx)
  - .gitignore
  - slides/
    - 01-intro.tsx
## The entry point

`main.tsx` wires a brand, plugins, and ordered slides into the engine:

```tsx title="main.tsx"
import { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import { Present } from "@liebstoeckel/engine";
import "@liebstoeckel/theme/styles.css";

import Intro from "./slides/01-intro";

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <Present title="My Talk" brands={["liebstoeckel"]} slides={[Intro]} />
  </StrictMode>,
);
```
**Tip:** `brands` is an array. Pass more than one (e.g. `["acme", "sunset"]`) and press <kbd>t</kbd> while presenting to cycle the whole deck through them.

## Build a single file

```bash
liebstoeckel build my-talk            # → my-talk/dist/my-talk.html
```

The output is one self-contained `.html` (named after the deck: `dist/<deck-slug>.html`) with JS/CSS inlined, assets base64'd, and slide thumbnails embedded. Open it directly, email it, or host it anywhere static.
**Bun-only build API:** Decks are bundled with the **`Bun.build()` JS API** (in `build.ts`), not the `bun build` CLI. `compile: true` + `target: "browser"` is what inlines everything. See [Building & deploying](https://docs.liebstoeckel.app/guides/building/).

## Keyboard during a talk

| Key | Action |
| --- | --- |
| <kbd>→</kbd> / <kbd>Space</kbd> | next reveal, then next slide |
| <kbd>←</kbd> | previous |
| <kbd>o</kbd> | overview grid |
| <kbd>p</kbd> | open presenter window |
| <kbd>f</kbd> | fullscreen · <kbd>b</kbd> blur screen |
| <kbd>q</kbd> | show the join QR (live) · <kbd>t</kbd> cycle brand |
| <kbd>123…</kbd>+<kbd>Enter</kbd> | jump to slide · <kbd>?</kbd> help |

[Author your first deck](https://docs.liebstoeckel.app/guides/your-first-deck/)