At a fast-iterating startup, the timing never feels right to build a component library: standardizing components conflicts with the rapid, constant changes needed to find product-market fit. Ramp's engineering team faced this directly. By the time they started building one, Ramp already had a product with components that had been iterated on for years inside the main codebase, tweaked ad hoc as part of ordinary feature work, with no separation between business logic and design decisions.

Rather than keep the components inside the main repository and rely on discipline to avoid drive-by edits, Ramp's team drew what they called a hard boundary: a separate repository, published as its own npm package, with a hand-crafted changelog and proper versioning so consuming teams could adopt changes on their own schedule. Values inside the library were also given semantic names, a "destructive" color instead of a specific red, so the visual decision and the code that consumed it were no longer the same thing.

To drive adoption, the team treated the internal package like an open-source project, building its own documentation site out of the library's own components, which forced the team to dogfood Ryu as a real second consumer. They also chose depth of adoption over breadth of coverage: it was better to have five components fully adopted everywhere than twenty-five components nobody used, so new code defaulted to the new library while old components were migrated over incrementally rather than rewritten all at once.

Isolate the library in its own repo and package

A separate repository makes every design change a deliberate, reviewed contribution rather than a side effect of feature work.

Semantic naming decouples the visual decision from the implementation, so colors or spacing can change without breaking consumers.

Building the documentation site out of the library itself creates a real second consumer that surfaces integration bugs early.

Treating an internal package like open source, with a changelog and versioning, lets teams adopt changes without a forced rewrite.

A shared system stays coherent when editing it takes a deliberate step: isolate it in its own repo, and let consumers ask for abstract properties instead of raw values.

Ramp's engineering team described the library as still being actively built out as of November 2021, calling it "day 973" of the company's life, with adoption driven incrementally by favoring components that were fully used over ones that merely existed. The isolation and semantic-naming approach became the pattern the team continued to extend across the company's core app, blogs, and internal tools rather than a one-time migration.

FOLLOW THE EVIDENCE

The sources

  1. Bootstrapping a UI component library builders.ramp.com