# Compositions
A composition is an HTML document that defines a video timeline.
## Structure
Every composition needs a root element with `data-composition-id`:
```html
```
## Nested Compositions
Embed one composition inside another:
```html
```
## Listing Compositions
Use `npx hyperframes compositions` to see all compositions in a project.
## Variables
Two attributes with different shapes and different jobs:
- **`data-composition-variables`** on the `` root — a JSON **array of declarations** (`{id, type, label, default}` per entry). Defines the schema: which variables exist, what type they are, and what defaults to use when no override is provided.
- **`data-variable-values`** on a sub-comp host element — a JSON **object keyed by variable id** (`{"title":"Pro","price":"$29"}`). Carries per-instance overrides for that one mount of the sub-composition.
They aren't redundant — one is "what variables does this composition have?" and the other is "what values should this particular embed use?" Inside any composition script, `window.__hyperframes.getVariables()` returns the merged result. Layering, lowest to highest precedence:
1. Declared defaults from `data-composition-variables`
2. Per-instance overrides from the host's `data-variable-values` (sub-comp embeds only)
3. CLI overrides from `npx hyperframes render --variables '{...}'` (top-level renders only)
```html
```
```html
```
The runtime layers `data-variable-values` over the sub-comp's declared defaults on a per-instance basis. The same `getVariables()` call works at the top level too — the CLI flag `--variables` provides the override, declared `default`s fall through for missing keys.