LmCast :: Stay tuned in

Cube

Recorded: Sept. 20, 2026, noon

Original Summarized

Cube — JavaScript animation library for UI motion

cube

APIReactFAQAgents
GitHub

Four motions.No dials
Cube is a JavaScript animation library with no dials. rise, leave, morph and reveal each ship with the duration, curve and stagger chosen for that job. Web Animations API underneath, zero dependencies.

click to switch
$npm i cube-motion

Read the API

Save
Saved

rise640ms · 70ms stagger
Entrance. Opacity and a 12px lift, siblings staggered.

leave320ms · 40ms stagger
Exit. Opacity and a 12px drop, held until you remove the node. Half the entrance.

morph220ms · 130ms lead
State change. Text keeps shared leading letters and blurs the rest in and out. Icons crossfade as whole faces. The parent’s width follows.

Sync
Synced

revealrise, when in view
Below the fold. Hidden until it enters the viewport, then rises once. Scroll the box.

API
cube.jsimport { rise, leave, morph, reveal } from "cube-motion";

rise(".hero", { targets: "children" }); // staggered entrance
leave(toast); // staggered exit, holds the end state
morph(oldIcon, newIcon); // one state into the next
reveal(".card"); // rise when scrolled into view

React
ReactVueSolidSvelteimport { Rise, Morph, Reveal } from "cube-motion/react";

<Rise as="section" targets="children" className="hero"> // stagger children
<h1>Four motions.</h1>
<button onClick={save}>
<Morph active={saved} off="Save" on="Saved" />
</button>
</Rise>

<Rise show={open} className="toast">Saved</Rise> // rises in, leaves before unmount

<Reveal as="ul" targets="children" className="cards">{cards}</Reveal><script setup>
import { Rise, Morph, Reveal } from "cube-motion/vue";
</script>

<template>
<Rise as="section" targets="children" class="hero"> <!-- stagger children -->
<h1>Four motions.</h1>
<button @click="save"><Morph :active="saved" off="Save" on="Saved" /></button>
</Rise>
<Rise :show="open" class="toast">Saved</Rise> <!-- rises in, leaves before unmount -->
<Reveal as="ul" targets="children" class="cards">
<li v-for="card in cards" :key="card.id">{{ card.title }}</li>
</Reveal>
</template>import { Rise, Morph, Reveal } from "cube-motion/solid";

<Rise as="section" targets="children" class="hero"> // stagger children
<h1>Four motions.</h1>
<button onClick={save}>
<Morph active={saved()} off="Save" on="Saved" />
</button>
</Rise>

<Rise show={open()} class="toast">Saved</Rise> // rises in, leaves before unmount

<Reveal as="ul" targets="children" class="cards">{cards}</Reveal><script>
import { rise, leave, morph, reveal } from "cube-motion/svelte";
</script>

<button onclick={save}>
<span class="faces" use:morph={saved}>
<span class:inactive={saved} aria-hidden={saved} inert={saved}>Save</span>
<span class:inactive={!saved} aria-hidden={!saved} inert={!saved}>Saved</span>
</span>
</button>

{#if open}<div class="toast" in:rise out:leave>Saved</div>{/if}

<ul use:reveal={{ targets: "children" }} class="cards">…</ul>

Why no dials

lead ●├────────┤ 130
morph ●├────────┤ 220
leave ●├────────┤ 320
rise ●├────────┤ 640Numbers, not optionsDuration, curve and distance are fixed for each job. Stagger and delay control when the motion starts.
rise ● toast ○
leave ● dialog ○
morph ● reorder ○
reveal ● height ○Jobs grow, dials neverCube covers entrances, exits, state changes and scroll reveals. Use another tool when you need timelines, gestures or layout animation.
cube
├─ element.animate()
├─ IntersectionObserver
└─ reduced-motionPlatform underneathWeb Animations API and IntersectionObserver. Nothing to polyfill, no frame loop, nothing fighting the browser.

FAQ
Why not Motion or GSAP?They give you every dial. Cube gives you four decisions already made. Reach for them when you need a timeline, gestures or layout animation.
Does Cube have dependencies?The core has zero runtime dependencies and uses the browser’s Web Animations API. React, Vue, Solid and Svelte are optional peer dependencies for their adapters.
Where did press go?Press feedback is three lines of CSS: a transition on scale and :active { scale: 0.97 }. CSS also answers keyboard activation, which a pointer listener never did, so the function was retired and its place went to leave.
What about springs?Cube uses a fixed cubic-bezier curve, not a spring solver. There are no spring options.
What happens with reduced motion?Opacity changes stay; translation, scale and blur go. rise and leave become fades, morph a crossfade. reveal applies the reduced-motion preference when an element enters view.

MIT · Daniel White
Agent reference

Cube is a JavaScript animation library designed for creating sophisticated user interface motion, distinguished by its approach of offering four predefined motions without relying on traditional dials for granular control. The library leverages the Web Animations API as its foundation, ensuring zero runtime dependencies and no reliance on custom frame loops or external polyfills. This design philosophy centers on simplifying complex animation tasks by offering specific, established motion patterns: rise, leave, morph, and reveal, each customizable with settings for duration, curve, and stagger.

The library implements four core motion types. The rise motion handles entrances, involving opacity changes and a vertical lift, often applied in a staggered manner to sibling elements. The leave motion manages exits, executing a drop and opacity change, and crucially, holding the element in its final state until it is removed. The morph motion facilitates state transitions, smoothly altering the visual properties, such as text or icons, by smoothly transitioning between states, often involving crossfading. Finally, the reveal motion is designed for content that appears when in view, such as elements below the fold, causing them to rise upon scrolling into the viewport.

Cube eschews traditional animation dials by fixing the duration, curve, and distance parameters for each motion type, shifting the control mechanism toward managing stagger and delay to dictate when the motion initiates. This systematic constraint allows the library to focus on providing ready-made solutions for common UI scenarios, rather than offering the exhaustive, timeline-based control provided by other animation tools like GSAP, which are better suited for complex gestures or detailed timelines.

The library integrates seamlessly across major frontend frameworks, providing adapter packages for React, Vue, Solid, and Svelte, enabling developers to implement these motions within their existing component structures. For instance, the integration allows for declarative specification of these animations, such as using Rise for staggered entrances, Morph for state changes, and Reveal for scroll-based visibility effects.

The library addresses modern accessibility concerns, particularly reduced motion preferences. For motion types like rise and leave, Cube facilitates these preferences by converting opacity changes into fades and morphing into crossfades. The reveal motion incorporates reduced motion handling by applying these preferences when an element enters the viewport. Furthermore, the library operates without spring solvers, utilizing a fixed cubic-bezier curve, and it relies on CSS transitions for press feedback, moving away from complex gesture-based solutions for basic interaction responses. Ultimately, Cube positions itself as a focused tool for handling common UI animations by abstracting away low-level browser complexities, relying instead on the efficient Web Animations API and IntersectionObserver.