Democraft

defineDemo

Reference for the DemoDefinition shape and defineDemo builder.

defineDemo declares and normalizes a demo. Put targets and config directly in the definition for the simplest one-file workflow; extracting them is optional organization for larger demos.

Signature

function defineDemo<TTargets extends Record<string, TargetInput>>(
  definition: DemoInput<TTargets>,
): DemoDefinition<DefinedTargets<TTargets>>;

DemoDefinition

PropTypeDefault
name
-
type
-
description
-
FieldTypeRequiredDescription
idstringYesStable identifier. Renaming invalidates the capture cache.
titlestringYesHuman-readable name.
configDemoConfigNoReusable config attached to this demo.
source.baseUrlstringYesOrigin of the target app. Must be live during capture.
source.initialPathstringNoStarting path. Defaults to the first scene's goto.
authentication.profileIdstringNoOpaque local authentication profile reference. No browser state enters source.
targetsTTargetsYesNamed element contracts. Literal keys become the allowed target IDs in scene methods. See locators.
visualsVisualMapNoLocal typed React/Remotion-compatible visual definitions.
audioTracksAudioTrackInput[]NoPresentation-only music, narration, sound effects, or ambient tracks.
run({ demo }) => Promise<void> | voidYesDrives the capture via demo.scene(...).

See audio for track timing and Studio editing, and authentication profiles for the complete local session lifecycle.

Minimal example

demo.ts
import { byTestId, defineDemo } from "@democraft/core";
 
export default defineDemo({
  id: "create-project-live",
  title: "Create a project live",
  source: {
    baseUrl: "http://localhost:4173",
    initialPath: "/dashboard",
  },
  targets: {
    dashboard: byTestId("dashboard"),
  },
  async run({ demo }) {
    await demo.scene("intro", async (scene) => {
      await scene.goto("/dashboard");
      await scene.establish("dashboard");
      await scene.caption("Create a workspace in seconds.");
      await scene.hold("5000ms");
    });
  },
});

DemoCapture

The demo argument to run is a DemoCapture. It has a single overloaded method:

PropTypeDefault
name
-
type
-
description
-
// without metadata
await demo.scene("intro", async (scene) => { /* ... */ });
 
// with metadata
await demo.scene("intro", { purpose: "Introduce the product" }, async (scene) => { /* ... */ });

defineConfig (optional)

For a single-file demo, put config directly in the definition:

export default defineDemo({
  id: "save-profile",
  title: "Save profile",
  config: { fps: 30 },
  source: { baseUrl: "http://localhost:3000" },
  targets: {},
  async run() {},
});

defineConfig remains available when several demos intentionally share the same settings.

PropTypeDefault
name
-
type
-
description
-

Experimental

environment, outputs, and adapters are reserved for future use and not yet consumed by the pipeline. Only fps is wired through today.

On This Page

On this page