cadence-tokens
v2.0.1
Published
The Cadence motion token system: three motion personalities (Snappy, Standard, Cinematic) as data, with emitters for CSS custom properties, DTCG, flat JSON, Framer Motion, After Effects (a TOKENS Motion control layer script), a Flow easing library, and Ri
Maintainers
Readme
cadence-tokens
The Cadence motion token system as a package: three motion personalities (Snappy, Standard, Cinematic) with emitters for CSS custom properties, DTCG, flat JSON, Framer Motion, and Rive view-model defaults.
The values were tuned live in Cadence, a motion design system explorer where the same tokens drive twenty UI components in real time. The site imports this package, so what you install is not a copy of the system; it is the system.
Install
npm install cadence-tokensThe package version is the token system's version. A tuning change is a release.
Use it from JavaScript
import { presets } from 'cadence-tokens'
const { tokens } = presets.snappy
// Framer Motion, directly:
<motion.div animate={{ y: 0 }} transition={{ duration: tokens.duration.base, ease: tokens.ease.enter }} />
// Or the physics spring, which is not time-based: its settle emerges from
// stiffness, damping, and mass.
<motion.div animate={{ scale: 1 }} transition={{ type: 'spring', ...tokens.spring }} />Durations arrive in seconds and easing as four-number bezier arrays: Framer Motion's own units, and the same resolved values the Cadence demos run. Each preset also carries ambient, the field vocabulary that drives the Motion Tiles grid.
Use it from CSS
Each personality ships as a complete stylesheet of custom properties:
@import 'cadence-tokens/dist/standard/cadence.css';
.panel {
transition: transform var(--cadence-duration-base) var(--cadence-ease-enter);
}The files
| File | What it is |
| --- | --- |
| src/index.js | The data and every emitter, as pure functions. |
| src/audit.js | The audit: what a token set says about itself, as a report. See below. |
| dist/cadence.tokens.json | The canonical document: all three presets, both vocabularies. |
| dist/cadence.resolver.json | The reduced-motion answer as a Design Tokens Resolver Module 2025.10 document, pointing at cadence.tokens.json beside it. |
| dist/cadence.rive.json | Per-preset view-model defaults for Rive, with the clock math and binding-unit notes. |
| dist/<preset>/cadence.css | One personality as --cadence-* custom properties. |
| dist/<preset>/cadence.motion.js | One personality as a ready Framer Motion module. |
| dist/<preset>/cadence.tokens.jsx | One personality as a runnable After Effects script: creates or updates the TOKENS Motion control layer in the active comp. Re-running a different preset's file retimes the comp. |
| dist/cadence.flow.txt | The five named curves as an easing library for Flow, the After Effects plugin. One file, not per preset: presets re-point slots at the same curves. |
| dist/cadence.figma.json | The interaction tokens as one Figma variable collection with the three personalities as modes, on Figma's native motion types: TIMING durations and delays (seconds), one EASING variable per curve carrying a real cubic-bezier, FLOAT scale and spring parameters. Shaped on Figma's own collection/modes/valuesByMode vocabulary so plugins and scripts map it one to one. |
cadence-tokens/tokens.json and cadence-tokens/rive.json resolve as export paths if you prefer importing the documents to reading files.
Audit the set
The judgment Cadence applies to a token set travels with the set, so you can run it in your own CI on the file you were handed instead of coming back to the site for it.
Point it at a file somebody exported from Token Lab, in either the DTCG or the
flat shape. (Not at dist/cadence.tokens.json in this package: that one is the
combined document carrying all three presets at once, which is a different kind
of file and not something importTokens reads.)
import { importTokens, auditTokens, auditToMarkdown } from 'cadence-tokens'
import { readFileSync } from 'node:fs'
// The .tokens.json a designer handed you, not this package's own document.
const result = importTokens(readFileSync('cadence.tokens.json', 'utf8'))
if (!result.ok) throw new Error(result.error)
const { deviations } = result
const { findings, measurements, counts } = auditTokens(result.state, { deviations })
process.stdout.write(auditToMarkdown(result.state, { deviations }))Nothing it reports is an error. Every result is a finding (the set contradicts
itself), a note (legal, and worth seeing), or an off-system row (one
component running a literal in place of a token, which says nothing about the
set). It never blocks, never repairs, and never refuses, because a wide range is
a legitimate choice and a tool that stamped "invalid" on one would be lying about
what it knows.
The bars come from two places and nowhere else: the set measured against itself (a duration ladder that runs backwards, a spring wildly out of proportion to the set's own durations, two easing slots that draw one curve), or one cited external number. These three presets are not an authority; a set that looks nothing like them is not thereby wrong.
The report prints the values it judged, because it is written for the engineer who has to implement the set rather than for the person who exported it.
Two vocabularies, one preset
The interaction tokens (duration, easing, delay, scale, spring) describe event-driven motion: a press, an enter, an exit. The ambient values (speed, easing exponent, spread, cell, gap) set a clock over a field of tiles. The two keep different shapes on purpose; the named preset is the unit they share. A Snappy press and a Snappy field are the same personality in two grammars.
Limitations
- The DTCG export targets the Design Tokens Format Module 2025.10, the first stable release. Durations and delays carry the object value that release requires,
{ "$type": "duration", "$value": { "value": 200, "unit": "ms" } }, always inms. - DTCG has no delay or spring type. Delays serialize as
duration(a delay is a duration measured from a trigger); the three spring parameters serialize asnumberleaves under aspringgroup. Both round-trip through Cadence's own importer. - The ambient vocabulary is not DTCG at all. There is no token type for a period divisor or an ease exponent, and inventing
$typeswould be costume, not compliance. Those values ship as plain numbers. - Reduced motion ships as an answer, not a gap. The CSS file carries a
prefers-reduced-motionblock andcadence.resolver.jsoncarries a reduced context (Design Tokens Resolver Module 2025.10), both replacing every duration with 10ms and every delay with 0. Easing, scale, spring and the duration scalar are deliberately unchanged: at 10ms a curve shape and a start scale are not perceived, and a physics spring has no duration to flatten, so its consumers switch to a timed branch instead, which a token file cannot express. - The Framer Motion module omits the duration scalar: a transition takes a concrete duration, not a base times a multiplier.
cadence.rive.jsonnames the view-model contract of the shipped Cadence files (PathEffectVM, its properties, its instance names). It documents what your bindings should expect; it does not create them.- The values themselves were tuned by ear against real components, not derived. Treat them as a working system, and retune where your components disagree.
