We’re live on Product Hunt — click here to upvote

Building Custom Design Systems with RapidNative's AI

RI

By Riya

26th Jul 2026

Last updated: 26th Jul 2026

Most AI app builders treat design as an afterthought. You write a prompt, a screen appears, and it looks... fine. A slightly different shade of blue on every screen. A "Button" component that's actually five slightly-different-buttons scattered across the app. Typography that drifts because the model forgot what font it picked on screen one.

That's not a design system. That's a mood board.

At RapidNative, we treat a custom design system as a first-class product of every AI generation — not a happy accident. When you describe a mobile app in natural language, we don't just spit out screens; we scaffold a real token layer, seed a coherent visual style, and hand the LLM a set of semantic colors it must use for every subsequent component. The result: apps that look intentional, consistent, and unmistakably yours from screen one.

This post is the technical tour: how RapidNative generates a custom design system, why we mix LLM creativity with deterministic seeding, and how the pipeline keeps every generated React Native screen visually coherent.

What "Design System" Actually Means Inside a Generated App

Before we get to the AI part, it's worth pinning down what a design system is in a modern React Native app — because the answer determines what the AI has to produce.

A functional design system has four layers:

  1. Design tokens — the atomic values (colors, spacing, radii, font sizes) expressed as variables, not hardcoded hex codes.
  2. Semantic aliases — meaningful names layered on top of tokens (primary, background, foreground, muted, destructive) so components stay legible.
  3. A theming mechanism — the plumbing that lets a single class name (bg-background) resolve differently in light vs dark mode.
  4. Component conventions — the "rules" that make a button look like a button on every screen (radius, padding, typography, focus state).

Skip any of these four and you get "screens that happen to look similar." Nail all four and you get a design system — one that scales as the AI writes more screens.

Every project generated by RapidNative ships with this stack pre-installed, using NativeWind (Tailwind CSS for React Native) as the styling engine and CSS custom properties as the token layer.

The theme.ts File: Where a Custom Design System Begins

When RapidNative scaffolds a new project, it drops a theme.ts at the root of the codebase. That single file is the source of truth for the entire design system. Here's the shape:

import { vars } from 'nativewind';

export const lightTheme = vars({
  '--background': '255 255 255',
  '--foreground': '23 23 23',
  '--primary': '24 24 27',
  '--card': '255 255 255',
  '--muted': '245 245 245',
  '--accent': '229 231 235',
  '--destructive': '239 68 68',
});

export const darkTheme = vars({
  '--background': '23 23 23',
  '--foreground': '250 250 250',
  '--primary': '250 250 250',
  '--card': '38 38 38',
  '--muted': '38 38 38',
  '--accent': '64 64 64',
  '--destructive': '248 113 113',
});

Colors are stored as space-separated RGB triplets — the format NativeWind expects so it can compose alpha values (bg-primary/50 at runtime). A ThemeProvider at the app root wraps everything in a <View style={themeVars}>, so those CSS variables cascade to every child. When a component says className="bg-background text-foreground", it resolves against whichever theme is active.

That's the foundation. But the interesting question is: where do those RGB values come from? How does the AI decide that this project's primary should be 24 24 27 (near-black) and not 59 130 246 (Framer blue) or 239 68 68 (destructive red)?

The answer depends on which model is writing the code.

Two Models, Two Design Philosophies

RapidNative's multi-LLM pipeline uses different models for different jobs — most recently Claude Sonnet 4.5 for high-quality generation with vision, and Zhipu's GLM family for speed and cost efficiency on lightweight tasks. Both are excellent coders, but they have very different design instincts.

Claude tends to be an intentional designer. Give it a prompt like "a fintech app for tracking freelance invoices" and it will actually think about what a fintech app feels like — trustworthy, restrained, monospace-adjacent typography, a serious color palette. You can hand Claude the design responsibility and it'll usually produce something coherent.

GLM, in our testing, is a stronger executor than it is a designer. Left to its own devices, it defaults to Tailwind-purple with a slate background — a pleasant but generic aesthetic that starts to feel same-y across projects. It's fast and cheap, but it needs more scaffolding to produce a distinctive design system.

That difference shaped a decision we made deep in the pipeline: for GLM-generated projects, we don't let the model invent the design system from scratch. We compose it deterministically and hand it over as a completed theme.ts that GLM is instructed to emit verbatim.

The Deterministic Style Seeder

Inside tools/project-templates/fullstack/ai/prompts/glm-design-directive.ts, we run a small function called buildThemeFile(). It's one of the least glamorous files in the codebase, but it's what keeps GLM projects from looking identical.

Here's what it does, step by step:

  1. Take the project's UUID. Every project has one, generated at creation time.
  2. Hash it with FNV-1a. A fast, non-cryptographic hash — the goal isn't security, it's a stable random-looking number derived from the project.
  3. Bucket the hash into one of 8 visual style archetypes. These are: Editorial, Bento Grid, Full-Bleed Media, Minimalist List, Data-Dense, Soft Rounded Consumer, Brutalist, and Glass/Layered Depth. Each has its own layout rules and component defaults.
  4. Pick a brand hue from 15 pre-selected HSL angles. These angles are curated — no muddy browns or eye-searing yellows — spanning coral (8°), amber (35°), teal (170°), cobalt (220°), violet (260°), rose (340°), and points in between.
  5. Derive accent hues from the primary via fixed offsets (150°, 165°, 180° on the color wheel), so the secondary and accent colors always harmonize.
  6. Convert HSL to RGB triplets in the exact format NativeWind expects.
  7. Emit the complete theme.ts file as a markdown code block inside the system prompt, which GLM copies verbatim into the project.

The result is that two projects with the same prompt produce different design systems — but each one is internally consistent and visually distinctive. Project A gets an Editorial layout with a warm coral primary. Project B gets a Bento Grid with a cool cobalt primary. Neither looks like the default Tailwind purple.

This is the difference between "AI wrote you an app" and "AI wrote you a designed app." The style itself is deterministic; the code inside each style is where the LLM's creativity lives.

For Claude-generated projects, we skip the seeder and give Claude a system prompt that positions it as "an award-winning mobile product designer" with explicit rules: build a coherent palette, respect visual hierarchy, avoid clichés (no gradient headers, no purple everything). Claude is trusted with more design autonomy because it earns it.

Semantic Colors: Why bg-background Beats bg-white

Once the token layer is in place, the AI has one hard rule for generating every screen: use semantic classes, never hardcoded colors.

That means the LLM is instructed to write:

<View className="bg-background border-border">
  <Text className="text-foreground font-semibold">Weekly Summary</Text>
  <Text className="text-muted-foreground">Last 7 days</Text>
</View>

Instead of:

<View style={{ backgroundColor: '#ffffff', borderColor: '#e5e7eb' }}>
  <Text style={{ color: '#171717', fontWeight: '600' }}>Weekly Summary</Text>
  <Text style={{ color: '#6b7280' }}>Last 7 days</Text>
</View>

The two snippets render identically on screen one. But on screen twelve, the second approach has drifted — the LLM has forgotten which grays it picked and started improvising, and now your app has seven shades of "muted text." The first approach can't drift, because there's exactly one --muted-foreground variable and it's defined in one place.

We also explicitly ban StyleSheet.create() in the system prompt for the same reason. NativeWind's className-driven approach forces every color decision through the token layer. If a user later wants to change the primary color from cobalt to teal, they edit one line in theme.ts and every screen updates.

This is what makes a custom design system maintainable — not just pretty on day one, but coherent on day ninety when the AI has generated forty more screens.

Typography as a Design System Pillar

Colors get most of the attention when people talk about design systems, but typography does more heavy lifting. A well-chosen font stack is often what makes an app look "expensive."

Every RapidNative theme exports a themeFonts object alongside its colors. The default is Inter — a safe, boring, always-good sans-serif — but the pipeline can swap in fonts from expo-google-fonts and load them via a useFonts() hook in the app's root _layout.tsx.

The style seeder pairs each of its 8 visual archetypes with a typography personality:

  • Editorial gets a serif heading font (Playfair Display or Fraunces) with Inter body copy — the New York Times look.
  • Bento Grid and Data-Dense get Space Grotesk headings — geometric, technical.
  • Brutalist goes monospace for headings (JetBrains Mono) — the terminal aesthetic.
  • Soft Rounded Consumer stays on Inter but with heavier weights and looser tracking.
  • Full-Bleed Media uses Inter Display for oversized headlines.

Because font selection is baked into the theme file the AI receives, every generated screen respects the typography contract without the LLM needing to re-derive it each time.

Bringing Your Own Brand

Deterministic seeding solves the "cold start" problem — every new project gets a distinctive design without user input. But most real users have an existing brand they want to match. RapidNative supports several routes for bringing your own design system to the AI:

  • Image-to-app: Upload a screenshot of an existing app (yours or a reference you like) and Claude's vision model extracts the palette, typography feel, and layout patterns into a fresh theme.ts.
  • Whiteboard-to-app: Sketch a wireframe on a canvas and the AI infers the structural design system from your drawing — what's a card, what's a list, what's a primary action.
  • Figma imports: Bring a Figma design and the vision pipeline extracts colors, typography, and component structure into a coherent React Native design system.
  • PRD-to-app: Drop in a product requirements document that includes brand guidelines and the AI weaves those constraints into the generated theme.
  • Prompt overrides: You can always just tell the AI: "Use a warm cream background, forest green primary, Playfair Display for headings." It respects those inputs and threads them through the token pipeline.

In every case, the extracted or specified brand values end up in the same theme.ts file. The pipeline downstream doesn't care how the tokens got there — it treats a user-provided palette identically to a seeded one.

Point-and-Edit: Refining the System After Generation

A design system is never done. The interesting work happens after the AI generates the first pass, when you want to nudge the primary color a shade darker or tighten the card padding.

RapidNative's point-and-edit workflow is built for exactly this. Click an element in the preview, describe the change in plain English ("make this button pill-shaped and use the accent color"), and the AI edits the underlying component and — critically — updates the theme tokens if the change is systemic.

If you ask to change one button, it changes one button. If you ask to change all buttons, or shift the accent color everywhere, the AI edits theme.ts and lets NativeWind's CSS variables cascade the change through every screen automatically. That's the payoff of building on tokens: system-wide edits are one-line diffs.

Why This Beats Templates and Hand-Rolling

The two obvious alternatives to "AI-generated design system" are (1) pick a React Native template with a design system baked in, or (2) hand-code your own.

Templates get you speed but not fit. You end up with an app that looks like every other app built on that template. Small differences accumulate — one primary color you don't quite like, one component structure that doesn't match your data model — and you either live with them or spend weeks refactoring. Our team wrote about this in more depth in Why AI-Generated Code Beats React Native Templates.

Hand-rolling gets you fit but costs time. Building a design system from scratch — tokens, semantic aliases, theme provider, dark mode, typography stack, component conventions — is a two-to-four-week project before you write your first real screen. Most solo builders and small teams don't have that runway.

RapidNative sits in the middle: you get a fit-for-purpose design system that's specific to your project (either seeded distinctively or matched to your brand) and you keep the ability to hand-edit any part of it because it's just a theme.ts file and standard NativeWind classes. Nothing proprietary, no vendor lock-in — the code exports cleanly and looks like something a good React Native engineer would have written.

What This Means for Design Consistency at Scale

The real test of a design system isn't screen one. It's screen thirty, generated three weeks after screen one, when the LLM has forgotten most of the context.

Because RapidNative pins the design system in a file the AI has to reference — not just remember — that thirtieth screen still uses the same primary, the same muted foreground, the same card radius, the same heading font as screen one. The AI's job on any given screen is to pick which tokens to use, not to invent new ones.

That single architectural choice — tokens as source of truth, LLM as consumer, not author — is what makes AI-generated apps feel like products instead of collections of coincidentally-related screens.

Try It Yourself

Design systems are the difference between an app that looks AI-generated and one that looks intentional. If you've been burned by generic-looking output from other AI builders, RapidNative's approach is worth an hour.

Describe an app, describe a brand, or upload a reference — start building free with 20 credits and no credit card. If you want to dig deeper into how our AI thinks about styling before you jump in, our post on how RapidNative generates NativeWind styles from natural language is a good next read.

The best design system is the one that keeps up with how fast you can ship. Let the AI build yours.

Start now

Ready to build your app?

Turn your idea into a production-ready React Native app in minutes.

Free tools to get you started

Questions

Frequently asked questions

What is RapidNative?

RapidNative is an AI-powered mobile app builder. Describe the app you want in plain English and RapidNative generates real, production-ready React Native screens you can preview, edit, and publish to the App Store or Google Play.

Can I export the code?

Yes. RapidNative generates clean React Native and Expo code that you can export at any time. No lock-in, no proprietary format. Hand it to your developers or keep building inside RapidNative.

Is RapidNative free to use?

Yes. You can build apps on the free plan with no credit card required. Paid plans unlock unlimited AI generations, code export, and direct publishing to the App Store and Google Play.

Do I need to know how to code?

No. Most users build apps by describing what they want in plain English. Developers can drop into the code whenever they want more control, but coding is optional.

How long does it take to build an app?

Most users have a working first screen in under a minute. A full MVP usually takes a few hours instead of the weeks or months traditional development requires.