Looks Like AI Is Building It transitions-ui-generation
Make any UI look like an AI is building it: a dotted wireframe traced from the element's own structure (outline, boxes, text lines, icon paths, with guides, corner handles and size labels), then the real UI revealed behind a scan line on a smooth ease-out. Two modes, one dependency-free runtime that works with any framework.
Works with Claude Code · Cursor · Codex · GitHub Copilot · Gemini CLI
Overview
What you get
- A dotted wireframe that follows the component’s outline, text and icons.
- A top-to-bottom scan that gradually reveals the real interface.
- Two modes: a clean wireframe reveal, or a reveal with logs and style panels.
- A dependency-free runtime for vanilla JavaScript, React, Next.js, Vue and Svelte.
Good fit
- Revealing an AI-generated card, chart or component after its content is ready.
- Showing how an interface comes together on a product page or in a demo.
- Giving an occasional result reveal a distinctive animation.
Not for
- Small elements such as badges or single buttons, especially under about 120px tall.
- Frequently appearing content such as list rows or repeated page transitions.
- Pending requests: show a loading indicator first, then play when the result is ready.
Tutorial
When to use a generation animation
When an AI feature returns a summary card, a chart or a component, the result usually appears immediately. To give that reveal a visible sequence, you can draw its dotted wireframe first, then reveal the real interface. Transitions UI Generation adds this animation to an already rendered element.
There are two distinct moments: while the request is pending, show a normal loading indicator; once the result has rendered and its layout is settled, play the generation animation. The runtime draws from existing UI. It does not generate content, and its animation is not a measurement of the AI’s actual progress.
Use it for an occasional result reveal or a product demo. Avoid repeated playback on buttons, badges, elements under roughly 120px tall, frequent page changes and list rows.
How the wireframe becomes the real interface
The runtime measures the target’s outline, internal boxes, text lines and icon paths, then draws an overlay at those positions. If you change the component’s structure, the next run measures the new layout. You do not need to draw a separate animation for each component.
| Phase | What changes on screen |
|---|---|
| Dot field | Dots spread from the centre, with falling dots and a sweeping probe line |
| Construction | Guides, corner handles and size labels appear |
| Outline | Dots progressively trace the target’s perimeter |
| Parts | Boxes, text lines and icon paths are drawn in document order |
| Reveal | A scan line reveals the real element from top to bottom as the wireframe clears |
Drawing takes 2400ms by default; the reveal brings the total to about 2.6 seconds. During the run, the runtime owns the target’s opacity, clip-path and filter, then restores their previous inline values. Avoid adding another entrance animation to that element.
From installation to the first run
First give your coding agent the skill, then verify the runtime with a small framework-free page. The example requires a modern browser with ES module support. Skill installation requires a Node.js/npm environment that can run npx; the upstream skill does not declare a minimum Node.js version, so follow the installer’s requirements.
-
Install the skill in your terminal. Run this in your project and follow the installer prompts to select your coding tool. If prompted to select skills, include
transitions-ui-generation.# Terminal command: install instructions for your coding agent npx skills add Jakubantalik/transitions.dev -
Tell your coding agent what to animate and when. Send the following as a chat instruction, not a shell command. The skill proposes the target, mode and trigger for confirmation before wiring the runtime.
transitions generate Add the skeleton generation animation to ResultCard. Play once per new result, after the response has rendered and fonts are loaded. Use the skill's ui-generation.js and ui-generation.css, importing CSS globally. Cancel on component unmount and keep reduced-motion support.Send
transitions generate previewto see both modes first. For text panels, sendtransitions generate textsand describe the empty space around your target. -
Prepare a complete browser example. Take
ui-generation.jsandui-generation.cssfrom the official runtime directory and place them beside thisindex.html. Installing the skill teaches the agent how to use it; the page still needs to load both runtime files.<!doctype html> <html lang="en"> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Generation animation example</title> <link rel="stylesheet" href="./ui-generation.css"> <style> body { margin: 0; padding: 80px 24px; background: #f6f6f6; } #result { max-width: 360px; margin: auto; padding: 32px; border-radius: 20px; background: white; font-family: sans-serif; } </style> <body> <article id="result" aria-label="Summary card"> <h2>This week's summary</h2> <p>Organised 12 notes and found 3 tasks.</p> <button type="button">View result</button> </article> <script type="module"> import { generate } from "./ui-generation.js"; // Wait for fonts and settled layout before measuring the target await document.fonts.ready; const element = document.querySelector("#result"); const run = generate(element, { mode: "skeleton" }); await run.finished; // The real interface has now been revealed console.log("Animation complete"); </script> </body> </html> -
Open the page over HTTP. Run this in the example directory and visit
http://localhost:8765. This preview command requires Python 3; it is a static server for the example, not a runtime dependency.# Serve over HTTP instead of opening the HTML directly, so ES modules load python3 -m http.server 8765You should see the card’s dotted structure followed by the real card. In your application, call the runtime after the result renders. Also wait for images if they affect the element’s dimensions.
Modes and useful options
| Mode | What appears | When to choose it |
|---|---|---|
skeleton | Dotted wireframe and UI reveal | Result cards and panels; the default when unsure |
skeleton-texts | Wireframe, agent log, motion CSS panel and step line | Product demos and launch pages with empty space |
Text panels appear only where the layout has room. A dense layout may show just the step line or no texts. For several cards, prefer skeleton with staggered delay values.
| Option | Default | Practical use |
|---|---|---|
mode | "skeleton" | Choose either mode |
duration | 2400 | Drawing time in ms; upstream recommends 1600–3600 |
delay | 0 | Delay before starting; stagger multiple targets by about 260ms each |
steps | Four English steps | Step-line copy in text mode; supply translated copy on other-language pages |
done | "Ready" | Final message during the reveal |
title | Derived from the element | Motion CSS header; otherwise uses aria-label or a heading |
maxParts | 60 | Maximum parts to trace, keeping larger parts first |
keys | 5 | Key elements that receive guides and size labels |
Replace the generate call in the example to try a customised step line:
const run = generate(element, {
mode: "skeleton-texts",
steps: ["Planning layout", "Drawing structure", "Writing styles", "Adding motion"],
done: "Summary card ready",
title: "Summary card",
});
These are presentation steps, not backend progress. steps and done are not a translation interface for the entire panel either. If every panel label must be translated, inspect the runtime’s fixed strings too.
generate returns { finished, cancel, element }. finished is a Promise for the completed reveal; cancel() stops immediately and shows the element. A new generate call on the same element cancels the previous run. Add data-t-generate-skip to a child to exclude it from the drawing.
Troubleshooting
Why do the wireframe text lines miss the real text?
Fonts or images probably had not loaded when measurement started. Await document.fonts.ready, wait for images that affect layout, then call generate.
Why is there no animation?
Check that both JS and CSS loaded and that the target exists with visible dimensions. An element with display: none cannot be measured; trigger after opening its tab or accordion. With reduced motion enabled, seeing only a short fade is expected.
Why are there two entrance animations?
Check for your own opacity, clip-path or filter animation on the target. Let the generation runtime own these properties during playback and remove conflicting entrance transitions.
Why are the text panels missing?
skeleton-texts needs empty space beside or below the target. Verify it in a spacious single-card layout before deciding whether your product needs text mode. Use skeleton when space is tight.
Why does the wireframe drift while scrolling?
The overlay lives on the page; a target moving inside a scroller can separate from it. Prefer playing once when the element enters view and avoid continuously scrolling the target during playback.
Why does the server report a window or DOM error?
Call the browser runtime on the client. In SSR frameworks, wire it in the client lifecycle. If you need to isolate the import from server execution, dynamically import inside an effect or mount hook, then wait for fonts and settled layout.
Further usage and official references
For demo pages, the attribute API plays each element once as it enters view. This suits existing content; for asynchronous results, explicitly call generate after rendering the result.
<section data-t-generate="skeleton" data-t-generate-delay="200">
<h2>Your result is ready</h2>
<p>Place the rendered card content here.</p>
</section>
<script type="module">
import { auto } from "./ui-generation.js";
// Register viewport-triggered playback after fonts are ready
await document.fonts.ready;
auto();
</script>
In React, Vue or Svelte, start on the client after layout settles and call run.cancel() on unmount. If the component could unmount while waiting for fonts, check that it still exists after the wait before starting an animation on it.
Preserve the runtime’s prefers-reduced-motion: reduce branch: it skips drawing and fades the element in over about 200ms, while finished still resolves. The overlay is aria-hidden and takes no pointer input. Do not tie business requests or result availability to the animation’s completion callback.
- Official skill instructions: commands, API, framework wiring and usage boundaries.
- Skeleton reference: details of each drawing phase.
- Text-mode reference: logs, CSS panels and layout rules.
- Official demo file: download the runtime directory and serve over HTTP to preview both modes.