---
title: Docs
description: Odori is the application framework for React video, with conventions, components, preview, and production rendering around a first-class videos folder.
sidebar:
  order: 0
---

# Build videos like applications

Odori is an independent React video framework. It owns the deterministic frame
runtime, timeline compiler, browser player, and export pipeline, plus the
conventions a production project otherwise has to invent:

- a first-class `videos/` source root
- layouts, schemas, prepared data, and inherited brand policy
- beautiful source-owned components installed like shadcn
- instant live preview without encoding an MP4
- deterministic export jobs that render the exact previewed inputs

<CardGroup cols={2}>
  <Card title="Quickstart" href="/docs/quickstart" icon="rocket">
    Create a project and preview your first video.
  </Card>
  <Card title="The video file" href="/docs/concepts/video-files" icon="file-code">
    See the JSX-first `video.tsx` authoring model.
  </Card>
  <Card title="Video components" href="/docs/guides/components" icon="blocks">
    Install polished motion primitives as editable source.
  </Card>
  <Card title="Audio" href="/docs/guides/audio" icon="music">
    Score a cut with cues the encoder mixes for you.
  </Card>
</CardGroup>

## The mental model

Odori uses React as its authoring model, but does not depend on another video
framework. It provides project structure, deterministic frame state, timeline
compilation, data boundaries, component distribution, preview discovery,
validation, caching, and render operations.

```text
React components + Odori frame state
                 ↓
     Odori timeline runtime
                 ↓
Studio · embedded Player · stills · MP4 exports
```

## The packages

| Package | Role |
| --- | --- |
| `odori` | Runtime, timeline, player, hooks, schema, manifest |
| `@odori/cli` | Discovery, Studio dev server, stills, tests, export jobs |
| `@odori/studio` | The Studio workspace served by `odori dev` |
| `@odori/registry` | Source-owned components installed by `odori add` |
| `@odori/next` | Next.js config, server helpers, and the embedded player |
| `create-odori` | Project scaffolder |

## A complete video entry

```tsx title="videos/launch/video.tsx" lineNumbers
import {Scene, Video, defineVideoMetadata} from "odori";
import {CodeProof} from "../components/code-proof/code-proof";
import {EndCard} from "../components/end-card/end-card";
import {TitleReveal} from "../components/title-reveal/title-reveal";
import {productLayout} from "../layout";

export const metadata = defineVideoMetadata({
  title: "Introducing Odori",
  layout: productLayout,
  duration: "12s",
});

export default function ProductLaunch() {
  return (
    <Video>
      <Scene id="opening" duration="4s">
        <TitleReveal title="Build videos like applications." />
      </Scene>
      <Scene id="proof" duration="5s">
        <CodeProof code={'pnpm odori dev'} language="shell" />
      </Scene>
      <Scene id="end" duration="3s">
        <EndCard title="Author. Preview. Ship." />
      </Scene>
    </Video>
  );
}
```

The module exports static metadata for discovery and a normal React component
for the timeline. JSX is the default authoring surface; source files under
`scenes/` are an organizational choice, not a framework requirement.

## What Odori owns

| Odori owns | You own |
| --- | --- |
| Discovery and generated manifests | Story and product truth |
| Layout inheritance and input schemas | React components and scene composition |
| Preview, still, test, and export commands | Content, pacing, and visual decisions |
| Asset readiness and frozen render inputs | Your source repository |
| Render jobs, progress, retries, and storage | When an MP4 should be created |

<CardGroup cols={2}>
  <Card title="Project structure" href="/docs/concepts/project-structure" icon="folder-tree">
    Learn every special file and folder.
  </Card>
  <Card title="Preview and export" href="/docs/concepts/lifecycle" icon="play">
    Understand the development and production lifecycle.
  </Card>
</CardGroup>
