---
title: "@hyperframes/studio"
description: "Visual composition editor with live preview, timeline view, and hot reload."
---

The studio package provides a browser-based visual editor for creating and previewing Hyperframes compositions. It gives you a real-time preview of your video, a visual timeline of all clips, and player controls for seeking and playback — all updating live as you edit your HTML.

```bash
npm install @hyperframes/studio
```

## When to Use

**Use `@hyperframes/studio` when you need to:**
- Build a custom composition editor UI (e.g., embedded in your own web application)
- Integrate the Hyperframes preview player into a larger product
- Extend the editor with custom panels, toolbars, or integrations

**Use a different package if you want to:**
- Preview compositions during development — use the [CLI](/packages/cli) (`npx hyperframes preview`), which launches the studio for you
- Render compositions to MP4 — use the [CLI](/packages/cli) or [producer](/packages/producer)
- Capture frames programmatically — use the [engine](/packages/engine)

<Tip>
  **For most development workflows, you do not need to install the studio directly.** Running `npx hyperframes preview` starts the studio automatically with hot reload. Install `@hyperframes/studio` only if you are embedding the editor into your own application.
</Tip>

## Running the Studio

### Via the CLI (recommended)

```bash
npx hyperframes preview
```

This starts the studio development server, opens your composition in the browser, and watches for file changes. This is the easiest way to get a live preview.

### From the monorepo

```bash
# From the root
bun run dev

# Or target the studio package directly
bun run --filter @hyperframes/studio dev
```

## Package Exports

The studio has two entry points:

| Import | Description |
|--------|-------------|
| `@hyperframes/studio` | React components, hooks, and types |
| `@hyperframes/studio/tailwind-preset` | Tailwind CSS preset for studio styling |

Peer dependencies: `react` (19), `react-dom` (19), `zustand` (4 or 5).

## Components

### Layout

```typescript
import { NLELayout, NLEPreview, CompositionBreadcrumb } from '@hyperframes/studio';
import type { CompositionLevel } from '@hyperframes/studio';

// Main NLE (Non-Linear Editor) layout container
<NLELayout>
  {/* Preview, timeline, and editor panels */}
</NLELayout>

// Preview panel
<NLEPreview />

// Breadcrumb navigation for nested compositions
<CompositionBreadcrumb levels={levels} />
```

### Player & Timeline

```typescript
import {
  Player,
  PlayerControls,
  Timeline,
} from '@hyperframes/studio';
import type { TimelineElement } from '@hyperframes/studio';

// Embed the preview player
<Player />

// Playback controls (play, pause, seek, frame-step)
<PlayerControls />

// Timeline editor with scrubber
<Timeline />
```

### Editor Components

```typescript
import { SourceEditor, PropertyPanel, FileTree } from '@hyperframes/studio';

// Code editor (CodeMirror-based) for HTML, CSS, and JavaScript
<SourceEditor />

// Property inspector for selected elements
<PropertyPanel />

// Project file browser
<FileTree />
```

### Full Application

```typescript
import { StudioApp } from '@hyperframes/studio';

// The complete studio application (wraps all components)
<StudioApp />
```

## Hooks

### `useTimelinePlayer`

Manages player state and playback control:

```typescript
import { useTimelinePlayer } from '@hyperframes/studio';

const player = useTimelinePlayer();
// player.play(), player.pause(), player.togglePlay(), player.seek(time)
// player.refreshPlayer(), player.saveSeekPosition(), player.resetPlayer()
```

### `usePlayerStore`

Zustand store for player state:

```typescript
import { usePlayerStore, liveTime, formatTime } from '@hyperframes/studio';

const store = usePlayerStore();
// Access current time, duration, playing state, etc.

// Format time for display
const display = formatTime(liveTime.current);
```

### `useElementPicker`

Element selection from the preview:

```typescript
import { useElementPicker } from '@hyperframes/studio';

const picker = useElementPicker(iframeRef);
// picker.isPickMode, picker.pickedElement
// picker.enablePick(), picker.disablePick(), picker.clearPick()
// picker.setStyle(prop, value), picker.setDataAttr(name, value), picker.setTextContent(text)
```

## Features

### Live Preview

The studio renders your composition in an iframe using the Hyperframes runtime. What you see in the preview is exactly what will be captured during rendering — the same runtime code, the same seek logic, the same clip lifecycle.

Changes to your HTML are picked up automatically through hot reload, so you can edit `index.html` in your editor and see the result in the browser within milliseconds.

<Note>
  The *visual* output of preview matches render exactly. Real-time *playback smoothness* depends on your hardware, because preview actually plays the composition in your browser at 30/60fps. Render doesn't have that constraint — it captures each frame individually via a seek-driven pipeline, so expensive frames make the render slower but never drop. If you see stutter in preview but the rendered mp4 is clean, that's expected. See [Performance](/guides/performance) for the patterns that most often cause it.
</Note>

### Timeline View

The timeline panel provides a visual representation of your composition's structure:

- Each clip appears as a colored bar on its track
- Bar position and width reflect `data-start` and `data-duration`
- Visually higher rows render in front; lower rows render underneath
- Relative timing references (e.g., `data-start="intro"`) are resolved and displayed as absolute positions

This makes it easy to understand the temporal structure of complex compositions with many overlapping clips.

### Timeline Editing

The timeline supports move and trim actions that persist directly back into your HTML source.

For a full breakdown of:

- what timeline editing can do today
- how each action maps to `data-start`, `data-duration`, `data-track-index`, and `z-index`
- which clip types support start trim
- current limitations and mental models

see [Timeline Editing](/guides/timeline-editing).

### Player Controls

The studio includes a full set of playback controls:

- **Play / Pause** — start and stop playback
- **Seek** — click anywhere on the timeline to jump to that point
- **Scrub** — drag the playhead to scrub through the composition frame by frame
- **Frame step** — advance or rewind one frame at a time for precise positioning

### Hot Reload

File changes are detected and applied without restarting the server. The preview maintains its current playback position when possible, so you can tweak an animation at the 5-second mark without having to seek back to it after every save.

## Architecture

The studio is a React application with the following structure:

1. **Iframe preview** — your composition HTML is loaded in an isolated iframe with the Hyperframes runtime injected. This ensures the preview uses the same rendering path as production.

2. **Runtime bridge** — the studio communicates with the iframe via `postMessage` to control playback (play, pause, seek) and receive state updates (current time, duration, readiness).

3. **Timeline component** — parses the composition using `@hyperframes/core` to extract clip timing data and renders the visual timeline panel.

4. **File watcher** — a development server (Vite-based) watches your project files and triggers hot module replacement when changes are detected.

## Tailwind CSS Preset

The studio exports a Tailwind CSS preset for consistent styling:

```typescript
// tailwind.config.ts
import studioPreset from '@hyperframes/studio/tailwind-preset';

export default {
  presets: [studioPreset],
  // ... your config
};
```

## Related Packages

<CardGroup cols={2}>
  <Card title="CLI" icon="terminal" href="/packages/cli">
    Launches the studio via `npx hyperframes preview` — the easiest way to preview compositions.
  </Card>
  <Card title="Core" icon="cube" href="/packages/core">
    Types, parsing, and runtime that the studio uses for preview and timeline rendering.
  </Card>
  <Card title="Producer" icon="film" href="/packages/producer">
    Renders the compositions you build in the studio to finished MP4 files.
  </Card>
  <Card title="Engine" icon="gear" href="/packages/engine">
    The capture engine that powers production rendering of your compositions.
  </Card>
</CardGroup>
