Skip to content

junto

Design system for Vamo

Apps on one library
5
PR per change, down from four
1

A shared component library that made five separate apps at Vamo feel like one product.

Vamo means "let's go" in Spanish. junto means "together". I named the library for what it had to do, which was make five separate apps feel like one product.

Problem

I joined Vamo as the first engineering hire. The codebase was four front-end web apps, a mobile app, and an API repo serving all of them. Each of the four web apps carried its own copy of the same components.

The apps served four different groups: customer service, drivers, businesses, and admins. They looked like four different products because they were built like four different products. Styling was inconsistent between them.

The real cost was drift. A fix would land in one repo and not the others, so the same component behaved differently depending on which app you were in. Nobody had decided that. It just happened, four repos at a time.

I proposed building a shared library to my CTO and started on it.

Approach

Three moves, in this order, and the order was the point.

  1. Tokens first, before any component. Spacing, type, sizing, color. Each one is a small decision on its own. Together they are what make separate apps read as one product, and building components before settling them means retrofitting every component later.
  2. Then primitives on top of the tokens. Tables, inputs, buttons. Small surface area, high reuse, and every one of them already existed four times over.
  3. Then a promotion rule for everything after that. A flow moved into junto once it existed in more than one repo. Anything with a single consumer stayed local. The rule kept the library from becoming a place where code goes to sit.

Storybook is how the library stays usable. Every component is visible in isolation, testable, documented, and shareable across teams. It is the answer to "does this already exist", which is the question that produced four buttons in the first place.

Mobile came later. I extended the tokens into the mobile app with AI assistance to translate them across platforms, which got the design system onto a surface I was not going to have time to own myself.

Outcome

The migration removed 12,456 lines across 81 files.

A change that used to mean four PRs across four repos is now one PR in junto and a version bump in each consumer.

The clearest result is not a number. Vamo hired a mobile developer, and that developer now owns the mobile layer of junto. The library outlived my sole ownership and became something another engineer builds on.

What I would do differently

The promotion rule told me when to move a flow into junto. It did not tell me what shape the flow should be in when it got there.

I ported flows over roughly as they existed, on the assumption that consolidating them was the win. It was not the whole win. Once the flows were in one place and I could see them side by side, my CTO and I could tell that several of them needed restructuring, not just centralizing. So we implemented some of them twice: once to unify, again to fix.

I would audit the flows first now, and decide what needed redesigning before writing any of it. Putting four copies of a bad flow into one place gives you one bad flow.