From Figma to every Aceve screen.
Sprout is one source of truth for design decisions. Here's the journey a token takes from a designer's Figma file to running code on aceve.design — and what your role is along the way.
The flow
Every token lives in five places. Hover any stage for who edits it.
- Main Sprout fileDesigner publishes library → fires LIBRARY_PUBLISH webhook automatically.
- Webhook relayVercel edge function receives the Figma event and triggers the GitLab pipeline.
- sprout-tokens CIsync:icons + sync:figma pull the latest from Figma, then Style Dictionary builds all output formats.
- @aceve/sprout-tokensCSS, Swift, Android XML and flat JSON published as one versioned package.
- Every productEach framework pulls the format it needs. One token change cascades to all 30+ Aceve products.
Multi-platform output
One Figma publish produces four consumable formats via Style Dictionary.
All four formats ship in the same @aceve/sprout-tokens package. Each Aceve product imports only what its stack needs — no duplicate token definitions, no manual copy-paste between platforms.
Two repositories, one system
Sprout lives in two GitLab projects with one clear contract between them.
Raw design decisions — colors, spacing, radii, shadows and the icon set — synced from Figma and kept free of any app code. Every release is a version tag, and CI publishes it as the @aceve/sprout-tokens npm package to the GitLab Package Registry.
The Next.js docs site you are reading — pages, components, games and guidelines. It consumes the tokens package but never defines a token itself: if a hex code appears here, it came from the tokens repo. Every merge to main deploys to aceve.design automatically.
How a token change travels
Designer publishes the library in Figma → Figma fires a LIBRARY_PUBLISH webhook → aceve.design/api/figma-webhook extracts publisher and change summary, triggers the GitLab pipeline → sync scripts pull icons and variables → Style Dictionary builds CSS, Swift, Android and JSON → sync bot opens a review MR attributed to the designer → maintainer reviews the diff and merges → npm version tags a release → package published to the registry. Product teams pick it up via npm update or Renovate.
Why the docs site vendors its copy
This site keeps a committed copy of the package in vendor/sprout-tokens instead of installing from the registry. That makes the docs build self-contained — CI needs no registry credentials, and the site always documents the exact token version it was reviewed against. When tokens release, the vendored copy is bumped in a normal MR, so the docs update is visible in a diff like any other change.
The sync pipeline in detail
Five steps from Figma click to reviewable MR — three are fully automatic.
Clicking "Publish library" in the main Sprout file fires a LIBRARY_PUBLISH event. The payload contains who published and a full list of created, modified and deleted components, styles and variables.
aceve.design/api/figma-webhook receives the event, checks the passcode, and pulls out the publisher handle and a human-readable change summary. It then POST-triggers the GitLab pipeline with SYNC_KIND=all and those two variables attached.
The sync job runs npm run sync:figma (pulls all Figma variables), npm run sync:primitive (updates colors, spacing and motion durations in primitive.json), and npm run sync:icons. Style Dictionary then compiles all four output formats (CSS, Swift, Android XML, flat JSON). The verify script runs 13 checks across every platform before anything is committed.
If git diff finds changes, the bot creates a branch (all/figma-sync-{pipeline-id}), prepends a dated CHANGELOG.md entry, and opens an MR. The MR title and description include the publisher name and the change summary so reviewers know exactly what moved in Figma without opening it.
A maintainer checks the diff — token values, new icons, deleted variables — and merges when satisfied. After merging, running npm version patch | minor | major and git push --follow-tags triggers the publish job, which puts the new @aceve/sprout-tokens version on the GitLab Package Registry.
Tokens never land on main unreviewed. If the sync finds no changes, the pipeline exits cleanly — no empty MR is opened. The CHANGELOG.md in the tokens repo gets a new entry on every sync regardless, so the history is always complete.
Follow a token
Pick one. See the same value through five passport-stamps — Figma, JSON, CSS, JS, and a live render below.
- 01Figma VariableSource of truth — designer edits hereMiniSprout / VariablesLightcolor/primary/700#447952
- 02DTCG JSONtokens-repo · auto-synced from Figma
"primary": { "700": { "$value": "#447952", "$type": "color", "$description": "Primary brand. Buttons, links, active state." } } - 03Generated CSSStyle Dictionary build · :root + dark
:root { --sprout-color-primary-700: #447952; } [data-theme="dark"] { /* flips to lime for AA contrast on dark */ --sprout-color-primary-700: #447952; --sprout-accent-default: #BDD78F; } - 04JS API@aceve/sprout-tokens · for swatch grids, charts
import { COLORS } from '@aceve/sprout-tokens'; const aceveGreen = COLORS.brand.find( (c) => c.token === '--sprout-color-primary-700' ); // → { name: "Aceve green / 700", value: "#447952", // token: "--sprout-color-primary-700", // role: "Primary brand. Buttons, links, active state." } - 05Live on aceve.designYou're looking at itReads
--sprout-color-primary-700at runtime — switching theme or bumping the tokens package updates it automatically.
Your role
The same pipeline, four different vantage points.
Why this matters
Three commitments the pipeline keeps.
Where to next
Three places to dig deeper.