How do you redesign a vibe-coded MVP without rewriting it?
You redesign a vibe-coded MVP without rewriting it by separating how the app looks from how it works, then changing only the look. The logic, data and flows users already validated stay in place. The redesign happens in three layers: design tokens, shared components, and the screens built from them.
This works because AI builders rarely produce unstructured code. Apps from Lovable and v0 are usually built with Tailwind CSS and shadcn/ui components, so colors, radii and spacing already flow through a theme, even when individual screens ignore it. Your job is to make every screen obey that theme, then change the theme. For where this fits in a product's life, see our MVP design and development guide.
Why do vibe-coded apps look inconsistent?
Vibe-coded apps look inconsistent because each prompt produces a plausible screen on its own, and nobody designs the whole. The tool fixes the button in front of it by writing a new one, so over time you get several buttons, several modals and several spacing systems that almost match.
- Hard-coded values. Colors and sizes typed directly into a screen instead of read from the theme, so changing the theme misses them.
- Forked components. A shared Button exists, but half the screens use a copy with small edits.
- The default look. The starter theme ships untouched, so the app looks like many others built the same way.
- Missing states. Empty, loading and error states were never asked for, so they're blank screens or raw messages.
- Copy in several voices. Every prompt wrote its own labels, and they don't agree on tone or terms.
None of these need new logic. They need a system, and the discipline to route every screen through it. Our guide to how polished MVP design should be helps you decide how far to take it.
How do you audit the interface before redesigning?
You audit the interface by capturing every screen in every state, then grouping repeated elements so you can count the duplicates. The audit sets the scope: an app with two button variants needs a light pass, one with nine needs a component pass first.
Capture every screen and state
Walk the app as a new user, a returning user and an admin. Screenshot each screen, plus its empty, loading and error versions, and any modal or toast.
Group repeated elements
Put all buttons side by side, then all inputs, cards, modals, tables and navigation. Note every variant that differs without a reason.
Find the hard-coded values
Ask a developer, or your coding tool, to list colors, font sizes and spacing typed directly into screens rather than read from the theme. This is the hidden work in a reskin.
Mark the core flow
Highlight the screens on the path to your product's main job. They get redesigned and shipped first.
How do design tokens make a reskin possible?
Design tokens make a reskin possible because they turn hundreds of style decisions into a few named values that every component reads. Change the primary color token once and every button, link and focus ring follows. Without tokens, a redesign means editing each screen by hand.
In a typical shadcn/ui setup, tokens are CSS variables such as background, foreground, primary, muted, border and radius, defined in the main stylesheet and mapped to Tailwind. On Tailwind v4 they sit in an @theme block in CSS; older projects map them in a tailwind.config file. Start by moving every hard-coded value you found into one of these tokens, which should change nothing visually.
Then design the new direction in Figma using variables with the same names as the code tokens. Define color for light and dark modes, a type scale, a spacing scale, radii and shadows. When the names match, handing the design to code is a list of value changes, not an interpretation exercise.
What to put in your AI tool's instructions so it stops undoing the redesign
If you keep prompting after the redesign, the builder can drift back to old habits. Most AI builders and coding agents read project-level instructions, so write the rules down where the tool will see them.
Useful rules: use only theme tokens for color, spacing and radius, and never hard-code values. Use the existing components in the shared components folder; extend them with a variant instead of creating a copy. Every list and data view needs an empty, loading and error state. Button labels start with a verb and use the product's terms.
Review new screens against the inventory anyway. Instructions reduce drift; they don't remove it.
How do you run the component pass?
You run the component pass by choosing one canonical version of each repeated element, giving it the variants the product needs, and replacing every copy with it. Do this before reskinning screens, because every component you fix improves every screen that uses it.
Work from the most-used element down: buttons, inputs and form fields, then cards, modals, tables and navigation. For each one, design the variants in Figma (primary, secondary, destructive, sizes, disabled and loading), update the shared component in code, then swap the forked copies for it. Check each swap with before-and-after screenshots so nothing breaks quietly.
Pros
- Keeps the logic, data and validated flows untouched
- Each change ships on its own, so the product keeps moving
- Later screens inherit the system without extra design work
- Works with the AI builder or a coding agent still in use
Cons
- Can't fix a broken data model or tangled component tree
- Hard-coded values make the first pass slower than expected
- Needs someone to review drift for as long as you keep prompting
How do you reskin a Lovable app screen by screen?
You reskin a Lovable app screen by screen once tokens and components are in place: apply the new layout and hierarchy to each screen in the core flow, add its missing states, rewrite its copy, and ship it before moving on. The same method works for apps from v0, Bolt or any React codebase.
- Sign-up and first run. The first screens decide whether people stay, so they get the most care, including the empty state a new account sees.
- The core job. The screens where users do the thing they came for, with loading and error states designed rather than left to defaults.
- Results and sharing. Where users see value and show it to others.
- Billing and settings. Plain, consistent and trustworthy, especially anywhere money is involved.
- Everything else. Secondary screens usually need little beyond the new components.
Rewrite the copy as you go, not at the end. Interface text is part of the design, and AI-written labels are often the most generic part of the app. If your product has AI features, our guides to AI product UX and AI chat interface design cover the patterns those screens need.
When is a rewrite cheaper than an MVP redesign?
A rewrite is cheaper than an MVP redesign only when the problem sits under the screens: a data model that can't express your product, a component tree so tangled that each change breaks something unrelated, or core flows users have rejected. If the flows work and only the look fails, reskinning is almost always cheaper.
Approach | Choose it when | What stays |
|---|---|---|
Reskin | Flows work; visuals and consistency don't | Logic, data, flows, most code |
Restructure some screens | A few flows confuse users; the rest are fine | Data, logic, the design system |
Rewrite | Data model or code structure blocks every change | What you learned, copy, and user data via migration |
Most apps end up mixed: a reskin across the board and a few restructured screens. If you're unsure which side you're on, vibe coding vs hiring a team lists the structural warning signs. Our product design service covers redesigns where we also ship the code.
