Block registry
Ready-made lower thirds, callouts, intros, end cards, cursors and caption styles, and the miraiclip CLI.
Coming in the next release
@miraiclip/registry is built and tested, and ships in the next SDK release.
A block is one ready-made piece of a video, such as a lower third, a tooltip callout, an intro card or a caption style, described as plain JSON. Adding a block to a project produces ordinary commands: an HTML clip you can move, retime, keyframe and edit like any other, or a style applied to caption clips.
These are different from the React component blocks, which are pieces of editor UI.
npx @miraiclip/registry catalog
npx @miraiclip/registry add lower-third-classic --project video.miraiclip.json --at 2 --set name="Ada Lovelace" --set role=FounderBuilt-in blocks
The package ships 59 blocks. They work offline.
| Category | Blocks |
|---|---|
lower-third | lower-third-classic, lower-third-pill, lower-third-minimal, lower-third-gradient |
callout | callout-tooltip, callout-step-badge, callout-highlight-box, callout-arrow-label |
intro | intro-kinetic-headline, intro-logo-reveal |
title | title-chapter, title-centered |
outro | outro-cta |
cursor | cursor-arrow, cursor-highlight, cursor-hand, cursor-halo, cursor-dot, cursor-ring, cursor-click |
progress | progress-bar |
background | background-gradient |
caption-style | caption-bold-pop, caption-karaoke, caption-boxed, caption-minimal |
scene | scene-hook-typed, scene-word-slam, scene-statement, scene-before-after, scene-prompt-cards, scene-product-hero, scene-ui-zoom, scene-feature-trio, scene-feature-wall, scene-chat-thread, scene-notifications, scene-steps, scene-image-montage, scene-stat, scene-quote, scene-wordmark-outro, scene-doc-cold-open, scene-doc-title, scene-doc-still, scene-doc-character, scene-doc-quote, scene-doc-case-file, scene-doc-chapter, scene-doc-hits, scene-doc-reveal, scene-course-title, scene-course-syllabus, scene-course-lesson, scene-course-projects, scene-course-instructor, scene-course-outcomes, scene-course-enroll |
overlay | overlay-film-look |
Launch scenes
The scene blocks are full-frame, animated scenes for launch films and promos. Every scene keeps moving and ends with a short blur-push, so a 0.3 s dissolve between scenes reads as one continuous move:
- a typed hook question;
- a word slam on the beat;
- tilted prompt cards;
- a 3D product shot;
- three feature cards;
- an image montage;
- a counting stat;
- a wordmark reveal with a call to action.
Each scene takes the brand as fields: primary, secondary, bg, ink and font. Each also has a look field: light, dark (a deep tint of the brand colour) or brand (the brand colour with white type). Alternate looks in a long film so it changes light. Image fields take image asset ids. Scenes are sized in container units, so they work in 16:9, 9:16 and 1:1:
import { blockCommands, getBuiltinBlock } from "@miraiclip/registry";
const brand = { primary: "#155eef", secondary: "#f97316", bg: "#ffffff", ink: "#101828", font: "Plus Jakarta Sans" };
for (const command of blockCommands(getBuiltinBlock("scene-hook-typed")!, {
trackId: "scenes", createTrack: true, startUs: 0,
values: { ...brand, before: "Still juggling", highlight: "ten tools", after: "to win one client?" },
composition: { width: 1920, height: 1080 },
})) project.dispatch(command);Film scenes, formats and styles
The scene-doc-* blocks are for trailers and documentaries. They are slow, cinematic and led by type:
- a cold open in the dark;
- a title that tracks in between two hairlines;
- a still with a Ken Burns move and a caption;
- a character card;
- a pull quote;
- a case file with a stamp;
- a chapter card;
- three trailer hits cut on the beat;
- a title reveal to close.
They take the same fields as the launch scenes, plus display, the title typeface. overlay-film-look lays grain, a vignette and 2.39:1 letterbox bars over a whole film from its own top track. FILM_SCENES exports every scene, and DOC_SCENES and FILM_OVERLAY export the new ones.
The scene-course-* blocks (COURSE_SCENES) are for course and programme promos:
- a course title with its level, length and format;
- a syllabus that ticks off module by module;
- a lesson playing in a player frame;
- the projects you'll build;
- the instructor;
- skills and a certificate;
- an enrol card to close.
They sit on a faint notebook grid instead of the launch scenes' floating UI.
Every scene is tagged with the formats it suits: format:launch, format:course, format:trailer, format:documentary or format:explainer. FORMAT_INFO describes each format's beat order and its opening and closing scenes. FILM_STYLES holds nine reference looks: brand, academy, documentary, hype, midnight, paper, terminal, pop and editorial. Each style sets a palette, a body font and a title font, plus grain, letterbox, pace, the join between scenes (dissolve, dip or cut) and words for a music search. An assistant picks the format and style that fit a brief, or builds a custom style from the same tokens.
The React template's assistant builds films from these scenes. Its plan_film tool sets the format and style, and its add_scene tool then offers only that format's scenes and fills in the style's colours and fonts (or the brand's, from get_brand).
miraiclip show <block> prints a block's JSON, including its fields and their defaults.
The CLI
The package installs a miraiclip command.
| Command | What it does |
|---|---|
miraiclip catalog [--category <c>] [--search <text>] [--json] | List blocks |
miraiclip show <block> | Print one block |
miraiclip add <block> --project <file> [options] | Add a block to a project file |
miraiclip build <out-dir> [--blocks <dir>] [--name <name>] | Write a static registry: the built-ins plus your own blocks |
Every command except build takes --registry <url> to read blocks from a static registry instead of the built-ins.
add options
| Flag | Default | What it does |
|---|---|---|
--project <file> | MIRAICLIP_PROJECT, else video.miraiclip.json | Project file to edit |
--at <seconds> | 0 | Start time |
--duration <seconds> | the block's default | Length on the timeline |
--track <id> | overlays | Track to place it on. Created if it doesn't exist |
--id <clip id> | the block name, made unique | Clip id |
--set key=value | the block's defaults | A field value. Repeat for each field |
--x, --y, --scale | the block's defaults | Placement: centre as fractions of the frame, and a scale multiplier |
--captions all|<id,id> | all | Caption-style blocks only: which caption clips to style |
--print | off | Print { "commands": [...] } instead of editing the file, for an agent's apply_commands |
add writes the file in one step, as one transaction.
In code
Blocks are pure planners: a block plus where it goes becomes core commands.
import { blockCommands, captionStyleCommands, getBuiltinBlock } from "@miraiclip/registry";
const callout = getBuiltinBlock("callout-tooltip")!;
project.transaction(() => {
for (const command of blockCommands(callout, {
trackId: "overlays",
createTrack: true,
startUs: 4_000_000,
values: { text: "Click Save" },
composition: project.getState().doc.settings,
})) project.dispatch(command);
});
// Caption styles apply to existing caption clips
const style = getBuiltinBlock("caption-boxed")!;
for (const command of captionStyleCommands(style, ["cap-1", "cap-2"])) project.dispatch(command);blockCommands options
| Option | Default | Meaning |
|---|---|---|
trackId | required | Track for the clip |
startUs | required | Start time |
composition | required | { width, height } of the project. Sized blocks are designed at 1080p and scale to fit |
createTrack | false | Add the track first, as a video track on top |
id | the block name | Clip id |
durationUs | the block's default | Length |
values | the block's defaults | Field values. An unknown field, or a value of the wrong type, throws |
transform | the block's default placement | { x?, y?, scale?, rotation?, opacity? }. scale multiplies the fitted scale |
In a portrait or square composition, a block's default position is kept inside the frame with a 4% margin. Positions you pass are used as given.
| Function | Returns |
|---|---|
builtinBlocks(), getBuiltinBlock(name) | The built-in blocks, validated |
searchBlocks(blocks, { text?, category? }) | Blocks matching text in the name, title, description or tags |
resolveFieldValues(block, values) | Every field's value, with defaults filled in |
parseBlock(json) | A validated block. Throws on bad input |
fetchRegistryIndex(url), fetchRegistryBlock(url, name) | Read a static registry |
buildRegistry(blocks, { name? }) | A map of file path to JSON, ready to write to a folder |
Write a block
{
"name": "badge-new",
"title": "Badge — new",
"description": "A small 'New' badge for the corner of a product shot.",
"category": "callout",
"tags": ["badge"],
"fields": [
{ "key": "label", "label": "Label", "type": "text", "default": "New" },
{ "key": "color", "label": "Colour", "type": "color", "default": "#22d3ee" }
],
"content": {
"kind": "html",
"template": "<div style=\"background:{{color}};color:#000;font:800 40px sans-serif;padding:12px 24px;border-radius:999px\">{{label}}</div>",
"widthPx": 240,
"heightPx": 80,
"durationUs": 3000000,
"transform": { "x": 0.85, "y": 0.15 }
}
}| Field | Default | Meaning |
|---|---|---|
name | required | Lowercase slug, unique in the registry |
title, description | required | Shown in the catalog |
category | required | One of the categories above |
tags | [] | Extra search words |
version | "1.0.0" | Block version |
aspects | ["any"] | Shapes it is designed for: 16:9, 9:16, 1:1 or any |
fields | [] | { key, label, type, default, description? }. type is text, number, color or boolean. HTML blocks fill {{key}} placeholders |
content | required | { kind: "html", template, durationUs, widthPx?, heightPx?, animated?, transform? } or { kind: "caption-style", style } |
preview | none | Image or video URL, relative to the registry root |
Give widthPx and heightPx at the 1080p reference size. Leave both out for a full-frame block that fills any composition, and size its content in vmin units.
Your own registry
A registry is a folder of static JSON: index.json lists the blocks, and each block is blocks/<name>.json. Any web host can serve it.
npx @miraiclip/registry build ./public/blocks --blocks ./my-blocks --name acme
npx @miraiclip/registry catalog --registry https://acme.example.com/blocksbuild validates every block, includes the built-ins, and fails on duplicate names.