A Svelte 5 port of Stageshow, Benji Taylor's MIT kit for framed faux product UI: a believable interface, cropped with intent, as one still or a short scripted demo.
Everything upstream is here: 69 scenes, the kit's 42 stylesheets carried over unchanged,
his 44 brand marks, and the design tokens the whole kit is built on. The scenes' own 83
stylesheets were consolidated into 69. Nothing from React ships — svelte
is the only peer dependency.
pnpm add svelte-stageshow
Published on npm as svelte-stageshow, MIT. Verified by installing from the registry into a fresh project, not from a local tarball.
Upstream, Stageshow is a skill an agent reads rather than a library you call. This port
keeps that: stageshow/ in the repository is the skill, with the same rules and
the same fifteen references, rewritten for Svelte.
npx skills add maven-ammar/svelte-stageshow --skill stageshow
The agent reads stageshow/SKILL.md, builds the scene from the kit, films it and
checks its own work against the frames.
Two components and a stylesheet. Stage sets the design size and scales to its
container; Window draws the chrome. Your product's own markup goes inside.
<script lang="ts">
import { Stage, Window } from 'svelte-stageshow'
import 'svelte-stageshow/style.css'
</script>
<Stage width={720} height={340}>
<Window url="acme - invoices">
<!-- your product, built from the kit's parts -->
</Window>
</Stage>
Add a script and the stage plays it on a loop: an Act aims at
elements by name, changes state, waits for paint, and moves the cursor.
async function script(a: Act<State>) {
await a.click({ at: 'share' }) // the cursor arcs there and presses
await a.set({ open: true }) // resolves once it has painted
await a.wait(2000) // the payoff holds
await a.click({ at: 'close' })
await a.set({ open: false })
}
width and height are the design size. The stage scales down to
fit its container and only grows past the design size with fill.
| prop | type | default | what it does |
|---|---|---|---|
| width | number | required | Design width. |
| height | number | required | Design height. |
| initial | S | — | Scene state at the start of each loop. Statics can leave it out. |
| script | Script<S> | — | Loops while on screen. Leave it out for a static illustration. |
| poster | S | initial | The still frame shown under reduced motion, or with no script. |
| play | Play | loop | How the script runs. |
| cursor | CursorConfig | — | Which pointer the scene uses, and how it behaves. |
| compact | CompactConfig | — | A second, smaller design for narrow containers. |
| keys | KeysAt | bottom | Where keycaps from |
| hover | string[] | — | Targets shown hovered in a still. |
| theme | Theme | light | Light or dark, from the same scene code. |
| palette | Palette | accent | One accent, or mono. |
| fidelity | Fidelity | standard | How many real words a look uses. |
| greys | 'warm' | 'cool' | — | Swaps the warm canvas and well for cool ones. Light theme only. |
| tokens | LookTokens | — | A look as values: any |
| accent | string | — | The accent colour for this stage. |
| ground | Ground | — | What the scene sits on. |
| fill | boolean | false | Grow past the design size to fill the container, up to 2x. |
| speed | number | 1 | Plays the script faster above 1, slower below. |
| specimen | boolean | false | Renders the stage as a specimen rather than a scene. |
| unframed | boolean | false | Drops the stage's own frame. |
| deterministic | boolean | false | CSS transitions off, a virtual 60fps clock drives waits, tweens and typing, so the same frame index renders the same DOM. |
There is no kind prop: the chrome follows from what you pass, and the traffic
lights sit in the same place in every window.
| prop | type | what it does |
|---|---|---|
| url | string | Snippet | The address. A string, or a snippet. |
| tabs | Url[] | Tab titles; the first is the active tab. |
| nav | boolean | Back and forward buttons before the address. |
| title | string | App windows: the title. |
| sidebar | Snippet | A full-height sidebar. The traffic lights sit in its top. |
| sidebarStyle | 'flush' | 'floating' | How the sidebar meets the window edge. |
| toolbar | Snippet | Controls on the right of the bar. |
| lead | Snippet | Controls on the left of the bar, after the title. |
| chrome | 'native' | 'glass' | 'terminal' | 'card' | 'hairline' | Which chrome to draw. |
| lights | 'color' | 'grey' | 'white' | Traffic light treatment. |
| lightsSize | 'standard' | 'large' | Bigger lights for the newer macOS window. |
| barSize | 'standard' | 'tall' | Bar height. |
| receded | boolean | Draws the window as if it were behind another. |
| body | object | Props for the content column; |
A look is a theme, a palette and how many real words the scene uses. The kit's colours, type, radii and spacing are all design tokens, so you can map your own design system onto them and the demo will use your real colours and corner radii instead of looking like a mock-up.
Pass a theme from a prop, or any --ss-* token through tokens.
getLook, setLook and useLook read and write the
surrounding look when a scene is nested inside another.
All 69 scenes are working Svelte components and live in the gallery — open the first one. Each was rendered and compared against Benji's own output: 71 comparisons, 71 matched, scored at a named settled mark rather than the last frame of the animation.
MIT. Stageshow is Benji Taylor's; this port keeps his licence and notices. The design language, the kit and the scenes are his. Ported by Maven — source, release, upstream.