A good-looking app builder isn't a pile of themes. It's a formalized design system, and that's an architecture decision, not a cosmetic one. Here's ours, layer by layer.
Why an app builder needs a design system at all
Start with the scale problem. An app builder doesn't design one app. It designs the possibility space of every app its users will ever create: thousands of them, built mostly by people who aren't designers, about subjects the platform never anticipated. Each of those apps needs to look intentional, stay coherent as it grows, and still look current years later.
A pile of themes can't deliver that. A theme is a frozen set of aesthetic outcomes. It looks right until the user's project deviates from what the theme anticipated: a longer title, a deeper menu, a section combination the designer never tried. Then it degrades, and the user has no principled way to recover, because a theme encodes results, not rules.
A design system encodes the rules. Spacing, typography, color relationships, component behavior, decided once, formally, then applied to every combination of content and configuration, including the ones nobody foresaw. That's why I call it an architecture decision. Like any architecture, it determines what stays true about the output no matter what inputs arrive.
At GoodBarber we were the first app builder to formalize a true design system. The same discipline Material Design brought to Google, or the Human Interface Guidelines to Apple, inside a no-code platform. And I should say it up front: the design system is only the lower half of what we formalized. We had to name the entire app. I'll get to that. First, here's how it's built.
The architecture: three layers, eighteen levels of type
Three layers, each one consuming the one below.
Layer one, Foundations. The invariants, in eight categories: Grid, Spacing, Breakpoints, Layers, Color, Typography, Image Aspect Ratios, Icons. One example of how deep "formalized" goes: gutter spacing isn't a value, it's a behavior. A base gutter that shifts per device, 16px on mobile, 20 on tablet and desktop, with half and double tiers derived from it, all from a single configuration.
Layer two, the Atoms. The smallest reusable design decisions: Color, Font, Image, Gradient, Shape, Shadow, Size, Border, Blur, Overlay, immersive feedback, and the list keeps growing. An atom is a named, constrained choice. A shadow isn't free-form CSS, it's a token picked from a curated range.
Layer three, UI Components, assembled exclusively from atoms: Background, Text Field, Dropdown, Date & Time Picker, Checkboxes & Radio Buttons, Button, Thumbnail, Form. Because components can only speak in atoms, they can't drift apart stylistically.
Typography gets its own paragraph, because it's where most tools are weakest. The system defines 18 semantic levels: Display Headings, Headings, Navbar Headings, Body, Sub-body, Buttons, Badges. A size scale calibrated per device, from mobile to desktop. And hard rules attached: 1.2 line-height, two font families per view maximum. That last rule alone quietly prevents one of the most common ways non-designers hurt their own apps. It's the difference between a font picker and a typographic system: the picker gives you a choice, the system makes your choice work.
Color follows the same philosophy. Four semantic roles per theme, applied across the whole app. The user doesn't color screens one by one. They define what their brand's colors mean, and the system propagates the meaning. Readability constraints live at this level too, structurally rather than by audit.
Beyond the design system: naming the whole app
If that vocabulary rings a bell, it should: the "atoms" and the layered composition come from Atomic Design, the methodology Brad Frost laid out in 2013. The difference lives in the word "formalized". Atomic Design is a discipline that design teams impose on themselves, by hand, project after project. Here, the engine imposes it: the rules are code, applied to thousands of apps built by people who aren't designers. Frost described a method. We compiled it.
And compiling forced us to go further than he did. Atomic Design stops at pages, because beyond that, in a design team, humans take over. An engine doesn't have that luxury: you can't derive what you haven't named. So we extended the hierarchy all the way up, into a true ontology of the app: an App made of Sections, made of Pages, made of Widgets, made of Components, which speak in atoms. A "News" section is a list page and a detail page. The list page is assembled from widgets. Each widget speaks in components and atoms. That complete anatomy is what the rendering engines read when they derive an app.
Here's the detail that matters, though: the back-office doesn't show any of this. Deliberately. An article list page contains exactly one widget, the list, so the editing tool never mentions that widget. You edit the page, period. The ontology is for the machine, not for you. It's a choice we've defended from the start: a strict, structured architecture underneath, and an editing tool that stays simple to understand, instead of turning into a maze just to mirror its own model. (A choice that happens to age well: now that AI agents need to understand the tools they operate, an app that is entirely named and typed is exactly what a machine can read.)
What the architecture guarantees
Three guarantees, and they hold no matter who is building. A designer, a shop owner, or an AI.
Coherence at any scale. Screen forty obeys the same grammar as screen one, because both derive from the same tokens. Apps stay coherent through years of edits by different hands. The failure mode that kills most long-lived interfaces has no mechanism to occur here.
Speed without penalty. In most tools, going fast means accumulating visual debt. Here, every available choice is already systemically valid, so the fast path and the correct path are the same path. That's also the honest answer to AI-speed generation. That's also the honest answer to AI-speed generation. I've written about why AI output converges on the same generic look, and a formalized system is the way out.
Reproducible quality. Good design stops being a lottery that depends on the user's taste and becomes a floor the architecture holds up. The system embodies the judgment, the user supplies the intent. Whose taste got encoded in the system, and why that question matters more than ever, is a separate essay.
One more thing, because "formalized" can sound like "frozen". The system is alive. Our design teams evolve it continuously: trends enter it digested into rules, never copied as-is; components grow variants; old configurations keep working because the engine migrates past formats. That might be its most underrated property: an app built three years ago still looks current, because the system underneath moved for it. (To see these rules at work in actual code, I've opened the engine's hood elsewhere.
How it stays open
The objection every strong system meets: "so everyone's app looks like yours." The answer is graduated escape hatches rather than an all-or-nothing wall.
Customization has three levels. Pick a theme: four semantic colors, done. Override individual colors: deviate where it matters to your brand, inherit everywhere else. Or remap the full design, item by item. Beyond the parameters, custom CSS opens the last mile for the projects that need it.
What makes this different from freeform styling is that every level operates through the system, not around it. Your custom color still lands in a semantic role. Your adjusted spacing still rides the multi-device scaling. You can go remarkably far from the defaults, and you can't, structurally, produce an incoherent app on the way.
In a design system, constraints are what make freedom safe to use.
Mathieu Poli — Head of Frontend Engineering @ GoodBarber. I teach and write about frontend engineering, product design, and AI — and everything that happens when the three meet. · X: @hellomathieup

Top comments (0)