Figma <> Code

Design System

COOKIE FINANCE — OCTOBER 2025

My Role

UX/Product Designer — Design System Audit, Token Architecture, Component Design, Front-end

Tools

Figma, Storybook, React, Tailwind, VS Code, Github, Claude Code, Codex

Team

1 Senior UX Engineer

Duration & Status

5 months, Shipped in October 2025

Industry

Fintech, Design Systems, Internal tools

Context

Cookie Finance provides bookkeeping and tax services for content creators. In 2025, the roadmap was speeding up, and every new feature leaned on the same design system. That Figma file had only 10 components and covered only color and type, so designers built whatever was missing by hand. The catch: we couldn't pause feature work to rebuild it, and much of it already worked.

How I added value

I turned an inherited Figma library into a system engineers could build from. I kept its strong foundation, grew it from 10 to 36 components, and extended its tokens to spacing, radius, and a fuller type scale. I structured components so their properties map straight to React props, and built a few of them in code myself with Claude Code, shipping them to production.

3.6× components

from 10 to 36 figma components with 1,319 variants, and 528 variables

100% code parity

All 36 library components match 1:1 between Figma and code, with everything documented in Storybook

33% fewer

hard-coded colors per 1,000 lines of code as teams adopted the new tokens, even while the codebase doubled

3.6× components

from 10 to 36 figma components with 1,319 variants, and 528 variables

100% code parity

All 36 library components match 1:1 between Figma and code, with everything documented in Storybook

33% fewer

hard-coded colors per 1,000 lines of code as teams adopted the new tokens, even while the codebase doubled

HIGHLIGHTS

A design system that speaks both Figma and code

HIGHLIGHTS

A design system that speaks both Figma and code

HIGHLIGHTS

A design system that speaks both Figma and code

0.1

FIGMA DESIGN SYSTEM WALKTHROUGH

VIDEO

0.2

STORYBOOK DESIGN SYSTEM WALKTHROUGH

VIDEO

0.3

Figma Documentation

IMAGE

0.3

Figma Documentation

IMAGE

0.3

Figma Documentation

IMAGE

The Problem

The design system couldn’t keep up

The Problem

The design system couldn’t keep up

The Problem

The design system couldn’t keep up

The Figma library had only 10 components

When I joined, the Figma library had only 10 components, and its shared values covered only color and type. Anything else had to be designed from scratch.

1.0

Old figma components

IMAGE

1.0

Old figma components

IMAGE

1.0

Old figma components

IMAGE

Our code was built on three libraries

In code, our components sat on three different UI libraries (DaisyUI, Material UI, and Joy UI) plus our own styles. So one component, like a button, could exist three different ways.

Show Annotations

1.1

built on three libraries

IMAGE

Show Annotations

1.1

built on three libraries

IMAGE

Show Annotations

1.1

built on three libraries

IMAGE

THE PROBLEM

Designers kept building one-off components in Figma, while the code was split across three libraries

THE PROBLEM

Designers kept building one-off components in Figma, while the code was split across three libraries

THE PROBLEM

Designers kept building one-off components in Figma, while the code was split across three libraries

THE AUDIT

I decided to go deeper to find the root gaps

THE AUDIT

I decided to go deeper to find the root gaps

THE AUDIT

I decided to go deeper to find the root gaps

I audited Figma, files, and code

I looked at three things: the old Figma library, the feature files designers had actually made, and the code engineers had shipped. Together, they showed what worked, where designers worked around the system, and where design and code didn’t match.

2.0

Three places to audit

IMAGE

2.0

Three places to audit

IMAGE

2.0

Three places to audit

IMAGE

What the audit found

The coded components worked, and the existing Figma components were well built. The gaps were around them:

Figma and code didn’t match

The same component had different names and settings in Figma and in code. The code’s docs only showed components, with no guidance on when to use them or code to copy.

Spacing was never tokenized

The old library had 254 variables, but only for color and type. Spacing, padding, gaps, and corner radius had none, so designers and engineers typed every value in by hand.

Missing pieces got rebuilt

Code had 17 components, but Figma had only 10, so designers redrew the rest by hand, from tabs and date pickers to modals. Modals alone had maybe 100+ different types in figma.

Figma and code didn’t match

The same component had different names and settings in Figma and in code. The code’s docs only showed components, with no guidance on when to use them or code to copy.

Spacing was never tokenized

The old library had 254 variables, but only for color and type. Spacing, padding, gaps, and corner radius had none, so designers and engineers typed every value in by hand.

Missing pieces got rebuilt

Code had 17 components, but Figma had only 10, so designers redrew the rest by hand, from tabs and date pickers to modals. Modals alone had maybe 100+ different types in figma.

Figma and code didn’t match

The same component had different names and settings in Figma and in code. The code’s docs only showed components, with no guidance on when to use them or code to copy.

Spacing was never tokenized

The old library had 254 variables, but only for color and type. Spacing, padding, gaps, and corner radius had none, so designers and engineers typed every value in by hand.

Missing pieces got rebuilt

Code had 17 components, but Figma had only 10, so designers redrew the rest by hand, from tabs and date pickers to modals. Modals alone had maybe 100+ different types in figma.

THE PROPOSAL

I proposed moving to Shadcn as our solution

THE PROPOSAL

I proposed moving to Shadcn as our solution

THE PROPOSAL

I proposed moving to Shadcn as our solution

Why shadcn made sense

Replacing all three libraries with Shadcn, one open-source library we’d own, would fix the bloat and the mismatch at once.

We only built for web

There were no plans for an iOS app, so a web-first React library fit everything we were building.

We only built for web

There were no plans for an iOS app, so a web-first React library fit everything we were building.

We only built for web

There were no plans for an iOS app, so a web-first React library fit everything we were building.

We only built for web

There were no plans for an iOS app, so a web-first React library fit everything we were building.

We’d own the source code

Instead of styling around three libraries, we'd fix and extend components directly, with far less work patching what we had.

We’d own the source code

Instead of styling around three libraries, we'd fix and extend components directly, with far less work patching what we had.

We’d own the source code

Instead of styling around three libraries, we'd fix and extend components directly, with far less work patching what we had.

We’d own the source code

Instead of styling around three libraries, we'd fix and extend components directly, with far less work patching what we had.

Figma kits already existed

Third-party Figma files mirrored shadcn’s components, so design-to-code parity started near 1:1.

Figma kits already existed

Third-party Figma files mirrored shadcn’s components, so design-to-code parity started near 1:1.

Figma kits already existed

Third-party Figma files mirrored shadcn’s components, so design-to-code parity started near 1:1.

Figma kits already existed

Third-party Figma files mirrored shadcn’s components, so design-to-code parity started near 1:1.

Management said "No"

What we had already worked, and migrating would cost too much while the roadmap was speeding up. It was a fair call, so I had to build on the code we already had.

THE CHALLENGE

Make Figma and code match, and grow the system to cover what features needed, on top of the code we already had

THE PROBLEM

Make Figma and code match, and grow the system to cover what features needed, on top of the code we already had

THE PROBLEM

Make Figma and code match, and grow the system to cover what features needed, on top of the code we already had

token hierarchy

Rebuilding our token structure

token hierarchy

Rebuilding our token structure

token hierarchy

Rebuilding our token structure

Before — Old semantic didn't scale well

Old names reused words like “primary” and “default” for different things, so a name couldn’t tell you what it styled. They didn’t fit code neatly either. A script converted each Figma name for code and dropped the word “default,” so a code name could no longer be traced back to Figma. On top of that, DaisyUI and Material UI each had their own “primary.” So in code, “primary” could point to three different colors, depending on which library drew the component.

Show Annotations

3.1

Old token names

IMAGE

Show Annotations

3.1

Old token names

IMAGE

Show Annotations

3.1

Old token names

IMAGE

After — New semantic scales well in code

Every name now reads left to right: what it styles, for which component, in which state. bg-btn-brand-hover is the brand button’s background on hover, and engineers use that exact name in code.

Show Annotations

3.2

New token names

IMAGE

Show Annotations

3.2

New token names

IMAGE

Show Annotations

3.2

New token names

IMAGE

FIgma Components

Growing the library from 10 to 36 components

FIgma Components

Growing the library from 10 to 36 components

FIgma Components

Growing the library from 10 to 36 components

Button: Rebuilding it to have fewer variants

The old button had 585 variants, because every new option added another version. Its “Theme” setting also mixed two things: color and importance. I split it into four clear settings: size, color, hierarchy, and state. I turned icons into simple on/off toggles and added the focus and loading states it never had. The result: 216 variants that cover more.

4.0

OLD FIGMA BUTTON

VIDEO

4.1

NEW FIGMA BUTTON

VIDEO

Input: One component per field type

The old input tried to be four fields at once, switching between text, select, date, and password. I split it into four separate components, one per field, to match how they’re coded. Then I gave the text input the states it lacked: hover, focus, error, and read-only.

4.2

OLD FIGMA INPUT

VIDEO

4.3

NEW FIGMA INPUT

VIDEO

Chip: Added hover and outline styles

The old chip had one style, six colors, and no way to remove it. Our Sr. UX engineer wanted chips to do more, so we added an outline style for filters, a hover state so people know it’s clickable, a remove button, and eight colors.

4.4

OLD FIGMA CHIP

VIDEO

4.5

NEW FIGMA CHIP

VIDEO

Alert: Designing it to stand out

The old alert had a solid base: three colors and an optional action. But there was no way to dismiss it, and no layout for longer, two-line messages. With our Sr. UX engineer, I redesigned it to stand out from the page with an accent border, added a close button, and gave it one-line and two-line layouts, plus success and brand colors.

4.6

OLD FIGMA ALERT

VIDEO

4.7

NEW FIGMA ALERT

VIDEO

storybook build

Bringing our work from Figma to production

storybook build

Bringing our work from Figma to production

storybook build

Bringing our work from Figma to production

Built with our UX engineer

Once the Figma library was in shape, I collaborated with the Sr. UX engineer to translate each component into Storybook. Now each component’s page shows its options, explains when to use it, and gives engineers code they can copy, with every Figma setting under the same name in code.

5.0

STORYBOOK OVERVIEW

VIDEO

Button: Figma settings became props

The four Figma settings (size, color, hierarchy, state) became four props in code, so a designer’s choices translate straight into an engineer’s code.

5.1

BUTTON IN STORYBOOK

VIDEO

Chip, badge, and avatar: coded by me

I built these three myself, in React with Claude Code, and made their Storybook pages. Each one uses the same settings in Figma and in code.

5.3

CHIP IN STORYBOOK

VIDEO

5.4

BADGE IN STORYBOOK

VIDEO

5.5

AVATAR IN STORYBOOK

VIDEO

Plot twist

Then I had to put it down

Plot twist

Then I had to put it down

Plot twist

Then I had to put it down

I had to move to feature work

The library was built, the core components were in code, and new features were starting on the system. Then the company's priority shifted fully to new roadmap features. With two designers at most, I moved from system work to feature work, usually as the only designer on several features at once.

6.0

Message from management

IMAGE

6.0

Message from management

IMAGE

6.0

Message from management

IMAGE

Which caused our work to be incomplete

This meant we had to stop mid-rollout. The old components were never fully replaced, so old and new components still live side by side in code today.

6.1

Old vs new components

IMAGE

6.1

Old vs new components

IMAGE

6.1

Old vs new components

IMAGE

outcome

Even unfinished, the system made a difference

outcome

Even unfinished, the system made a difference

outcome

Even unfinished, the system made a difference

Hand-built UI fell from 45% to 24%

On the new system, designers hand-built about half as much of each file.

7.0

figma design system report

IMAGE

7.0

figma design system report

IMAGE

7.0

figma design system report

IMAGE

Token adoption kept spreading

At launch, 87% of new UI used the new colors. Even after work on the system stopped, hard-coded colors per 1,000 lines of code fell 33%, while the codebase doubled.

7.1

token adoption report

IMAGE

7.1

token adoption report

IMAGE

7.1

token adoption report

IMAGE

7.2

hard-coded colors report

IMAGE

7.2

hard-coded colors report

IMAGE

7.2

hard-coded colors report

IMAGE

Figma and code match 1:1

Coded components more than doubled, from 17 when I joined to 38. Today, all 36 library components match 1:1 between Figma and code, documented in Storybook.

7.3

Figma and Code Parity report

IMAGE

7.3

Figma and Code Parity report

IMAGE

7.3

Figma and Code Parity report

IMAGE

retrospective

This project deepened my love for design systems

retrospective

This project deepened my love for design systems

retrospective

This project deepened my love for design systems

Lessons from the hard parts...

This project tested everything I knew about design systems, but ironically it made me love it even more. Also, a big shout-out to our Sr. UX engineer: I learned so much from her, and none of this would have been possible without her. Here’s what I’m taking with me:

Make the case with data, not taste

I pitched shadcn on instinct, so “what we have works” won easily. Next time, I’d lead with the cost, like how many components were built by hand.

Make the case with data, not taste

I pitched shadcn on instinct, so “what we have works” won easily. Next time, I’d lead with the cost, like how many components were built by hand.

Make the case with data, not taste

I pitched shadcn on instinct, so “what we have works” won easily. Next time, I’d lead with the cost, like how many components were built by hand.

Make the case with data, not taste

I pitched shadcn on instinct, so “what we have works” won easily. Next time, I’d lead with the cost, like how many components were built by hand.

Old components must be retired

New colors reached 87% of new UI, but new components reached only 30% because old ones were recolored instead of replaced. Retiring the old version has to be part of the plan.

Old components must be retired

New colors reached 87% of new UI, but new components reached only 30% because old ones were recolored instead of replaced. Retiring the old version has to be part of the plan.

Old components must be retired

New colors reached 87% of new UI, but new components reached only 30% because old ones were recolored instead of replaced. Retiring the old version has to be part of the plan.

A design system is never finished

The rollout paused when priorities shifted, which showed me a design system is a living product. Small, regular checks that Figma and code still match beat a big relaunch later.

A design system is never finished

The rollout paused when priorities shifted, which showed me a design system is a living product. Small, regular checks that Figma and code still match beat a big relaunch later.

A design system is never finished

The rollout paused when priorities shifted, which showed me a design system is a living product. Small, regular checks that Figma and code still match beat a big relaunch later.

A design system is never finished

The rollout paused when priorities shifted, which showed me a design system is a living product. Small, regular checks that Figma and code still match beat a big relaunch later.

© 2026 All rights reserved

© 2026 All rights reserved

Portfolio made with <3

Portfolio made with <3