Democraft

Custom entry point

Override the generated Remotion composition for advanced use cases.

Democraft normally generates an entry from demo.ts, including components in its visuals map. You do not need this page to use a local or copied remocn component. Create a custom entry only when you need to replace the composition, override caption/callout internals, or control Remotion registration directly.

Why a custom entry?

The Remotion entry point is the file that calls registerRoot(Root). It defines which <Composition> renders your video and what props it receives. By taking control of it, you can:

  • Register custom visual components (local.* renderers).
  • Override built-in renderers with your own implementations.
  • Mix remocn-registry components with your own.

Creating the entry file

In your project root (next to demo.ts), create remotion-entry.ts:

remotion-entry.ts
import React from "react";
import { Composition, registerRoot } from "remotion";
import {
  ProductDemoVideo,
  compositionId,
  defaultProductDemoProps,
  defineVisualRegistry,
} from "@democraft/remotion";
 
// Import your custom components here
// import { MyCaption } from "./components/my-caption";
 
const registry = defineVisualRegistry(
  // { kind: "caption", id: "local.my-caption", component: MyCaption },
);
 
function Root() {
  return React.createElement(Composition, {
    id: compositionId,
    component: ProductDemoVideo,
    width: 1920,
    height: 1080,
    fps: 60,
    durationInFrames: 1,
    defaultProps: { ...defaultProductDemoProps, registry },
    calculateMetadata: ({ props }) => ({
      durationInFrames: props.timeline.durationInFrames,
      fps: props.timeline.fps,
      width: props.width,
      height: props.height,
    }),
  });
}
 
registerRoot(Root);

Import your components and add them to defineVisualRegistry():

remotion-entry.ts
import { MyCaption } from "./components/my-caption";
import { PulseCallout } from "./components/pulse-callout";
 
const registry = defineVisualRegistry(
  { kind: "caption", id: "local.my-caption", component: MyCaption },
  { kind: "callout", id: "local.pulse-callout", component: PulseCallout },
);

defineVisualRegistry extends the built-in defaults — you only list your additions. Entries with the same ID as a built-in renderer override the default.

Pass --entry to the CLI when rendering:

democraft render demo.ts --entry ./remotion-entry.ts \
  -o out.mp4

Installing remocn components from the registry

Remocn components are distributed via a shadcn-compatible registry. The registry is already configured in components.json:

# Clone a component into your project
pnpm dlx shadcn@latest add @remocn/soft-blur-in

This copies the component source into your project (typically components/remocn/). You then import it in your entry file and register it:

remotion-entry.ts
import { SoftBlurIn } from "./components/remocn/soft-blur-in";
import type { CaptionProps } from "@democraft/remotion";
 
// Adapt the remocn component to the CaptionProps contract
function MyBlurCaption({ overlay, opacity }: CaptionProps) {
  return React.createElement(SoftBlurIn, {
    text: overlay.text,
    color: "white",
    fontSize: 42,
  });
}
 
const registry = defineVisualRegistry(
  { kind: "caption", id: "local.blur-caption", component: MyBlurCaption },
);

You own the cloned source. Edit the .tsx file directly to change colors, timing, animation curves — anything. The component is yours.

The defineVisualRegistry API

import { defineVisualRegistry } from "@democraft/remotion";
 
const registry = defineVisualRegistry(
  { kind: "caption", id: "<renderer-id>", component: MyCaption },
  { kind: "callout", id: "<renderer-id>", component: MyCallout },
);

Each entry has:

  • kind"caption" or "callout" (determines which overlay type uses it).
  • id — the renderer string authors write in demo.ts.
  • component — a React component accepting CaptionProps or CalloutProps.

The returned registry includes all built-in renderers plus your additions.

Experimental

The defineVisualRegistry API is stable in shape but the broader adapter model (remocnAdapter(), defineConfig({ adapters })) is still being wired through the pipeline. Today, register components via the custom entry as shown above. The adapters config field exists but is not yet consumed at render time.

Using the entry with the Studio

The Studio's render queue accepts an entryPath in the enqueue request. When set, the render uses your custom entry instead of the built-in one.

From the Studio UI, this field appears in the render panel. Programmatically:

// The enqueue request payload
{
  entryPath: "./remotion-entry.ts",
  // ... other render options
}

When entryPath is omitted, the Studio falls back to @democraft/remotion/dist/entry.js (the built-in entry).

Next steps

On This Page

On this page