The AI app builder for non developers that refuses to ship AI slop
Most tools in this category ship whatever the model writes. mk0r ships a 2,354-line taste file that tells Claude what not to produce, then makes the agent look at its own output in a real Chromium tab before reporting done. This is the file, read verbatim.
The real problem for a non developer is not the code
Pick any article currently written about this topic and you will see the same list. Bubble. Adalo. Glide. Blink. Base44. Figma Make. Lovable. Thunkable. Each gets a paragraph. Each one handles the code so you, the non developer, do not have to. That is true and also not the interesting part.
The interesting part is what happens after the AI finishes writing. The model's defaults take over. Inter on the body. Gradient button in the middle of a centered hero. Rounded cards in a grid with tiny icons. Three accent colors because it seemed more interesting than one. Lorem ipsum where the empty state should be. None of that is a code problem. It is a taste problem. And a non developer, by definition, has not had ten years of rejecting ugly design.
mk0r solves this the other way around. The taste does not come from the user. It comes from a written file. The user types the prompt. The agent obeys the file.
Six things the agent is told never to ship
None of these are a hunch. They are quoted directly from src/core/vm-claude-md.ts at lines 168 to 176, under the heading ### Anti-Patterns (Never Do These). The file is written into the sandbox as /root/.claude/CLAUDE.md before your first prompt is accepted.
Forbidden by default
- Purple or indigo gradients on a white background
- Uniform rounded cards in a grid with decorative icons
- A centered hero with a gradient button below it
- Every section looking the same with slight color shifts
- Cookie cutter layouts that could belong to any app
- Placeholder images or Lorem Ipsum left sitting in the page
The rest of the taste file, in the agent's own words
The anti pattern list is one of about a dozen sections. The rest tell the agent what to do, not what to avoid. Every rule below is a literal line from the same file.
Three colors, maximum
Black, white, and one dominant accent. Not two accents, not a secondary highlight, not a 'status color' palette. The agent is told to pick one color and stick with it through buttons, links, and highlights.
No decorative icons
Icons only when they serve a function: expand chevrons, close buttons, check or x status, nav arrows. No icons on feature cards, section headers, or how it works steps. No Lucide or Heroicons installed unless explicitly requested.
No Inter, Roboto, Arial
The typography section names those three fonts and tells the agent they are the hallmark of generic AI output. The rule is to pair a distinctive display font with a refined body font, sourced from Google Fonts via CDN.
Asymmetry, not centered grids
The Layout and Composition section pushes the agent toward unexpected layouts, generous negative space or controlled density, and grid breaking elements. Default centered everything is explicitly discouraged.
No exclamation points, ever
The Copywriting section has 'No exclamation points. Ever. They weaken copy.' Plus a filler word ban on very, really, just, actually, basically, simply. Buttons must be specific: 'Save changes', not 'Submit'.
One well orchestrated reveal
On motion, the rule is: one well orchestrated page load with staggered reveals creates more delight than scattered micro interactions. CSS transitions for hover states. Framer motion only if the user asks for complex animation.
Why a rules file beats a template library
Most tools aimed at non developers give you a gallery of starter templates. Each template carries its own defaults. You pick one that looks close to what you wanted, and the AI fills in the blanks. The problem is that the AI anchors on the template. If the template already uses Inter on the body and a purple button in the middle, every new section the AI adds will extend those choices. Your final app is basically the template with more stuff.
A written rule file does the opposite. There is no template to anchor on. Each new section is generated against the same constraints. The color rule is the color rule whether the app is a habit tracker or a budget planner. The typography rule applies whether the user asks for a landing page or an internal dashboard.
That is the difference between a template system and a constraint system. Templates drift. Constraints hold.
Same prompt, two different defaults
User types 'build me a habit tracker'. Tool lands on the 'productivity' template: Inter headings, purple to blue gradient button, three card columns with small checkmark icons, light grey background, 'Track your habits!' with an exclamation point in the hero.
- Inter on the body and headings
- Purple to blue gradient button
- Three cards in a grid with icons
- Exclamation point in the hero copy
- Centered hero, gradient button
The second half of the differentiator: the agent watches itself
A rules file stops the model from shipping generic aesthetics. It does not stop the model from shipping something that looks right but does not render. For that, mk0r uses a Chromium tab.
Inside the E2B sandbox, a headful Chromium is already running on an Xvfb virtual display at :99, resolution 1600 by 900, with remote debugging on port 9222. A Playwright MCP server is bound to 127.0.0.1:3001 and attached to Chromium over the Chrome DevTools Protocol. The agent has access to that MCP the moment your session starts. Here is how it is wired.
The closed verification loop on every UI change
What a turn looks like from the inside
When you type “add a settings panel” and hit send, the agent does not stop at the write step. It keeps going until Chromium confirms the change.
0
decisions the non developer has to make
How to verify this yourself without trusting a screenshot
Open the repo at src/core/vm-claude-md.ts. Jump to line 168. Read the six bullets under ### Anti-Patterns (Never Do These). Then scroll to line 273 and read the five step Browser Testing block. Those two sections are not marketing copy. They are the actual bytes that get written to /root/.claude/CLAUDE.md inside the sandbox before your first prompt is accepted.
The system prompt that tells Claude to read them lives at line 148 of src/core/e2b.ts, exported as DEFAULT_APP_BUILDER_SYSTEM_PROMPT. Every session loads it.
How this compares to the rest of the field
The rest of the field competes on editor ergonomics, template count, or which database connector is one click away. mk0r is not in that race. mk0r is competing on whether the output looks designed and whether it actually renders. The first is owned by a file the user never has to open. The second is owned by a browser the user never has to click.
How the two defaults play out
| Feature | Typical non developer AI app builder | mk0r |
|---|---|---|
| Where the aesthetic rules live | Inside a template gallery, not visible as rules | Plain English in src/core/vm-claude-md.ts, readable by anyone |
| Default font behavior | Inter or Roboto as the default on most starter templates | Agent refuses Inter, Roboto, Arial by name |
| How the AI verifies the result | Preview renders in your browser, you catch the bugs | Playwright MCP opens Chromium, reads DOM, checks console before reporting done |
| What 'AI slop' looks like | Not defined, so the model produces it | Named in the anti pattern list and forbidden by default |
| Code you can own | Proprietary format, export as HTML snapshot at best | Real Vite plus React plus TypeScript plus Tailwind v4, git repo on /app |
| Account required to try | Signup, email verification, often a credit card on file | No. Session key lives in localStorage, no email needed |
Reading the taste file yourself, in three steps
Open src/core/vm-claude-md.ts in the mk0r repo
The file exports globalClaudeMd (lines 19 onward), projectClaudeMd (line 1142 onward), claudeSettingsJson, and a set of skill exports. The first two are what land on the agent's filesystem.
Jump to line 97 and read the Design Constraints block
Colors at 101, Icons at 111, Visual Style at 119, Typography at 143, Color Application at 153, Layout and Composition at 161, Anti-Patterns at 168, Motion at 178. All of it is English, all of it is shipped to Claude.
Jump to line 273 and read Browser Testing
Five numbered steps. The last one is the rule that pairs with the taste file: do not report completion until the browser shows the expected result. That is the loop.
When mk0r is the wrong answer for a non developer
If you want a native mobile app on the App Store, this is not the tool. mk0r produces web apps. React plus Vite plus Tailwind, running on a cloud sandbox, previewable from a URL. A mobile wrapper is a separate path.
If you want a fully visual, drag and drop editor where you see every pixel before clicking save, the absence of an editor will feel odd. mk0r is prompt driven. You describe, you iterate with follow up prompts, and you look at the live preview. If dragging rectangles is what you enjoy, tools with a WYSIWYG canvas are a better fit.
For anyone else, especially anyone who has tried a no code builder and come away with something that looked indistinguishable from every other no code output, the rules file plus the self check is worth the ten seconds it takes to see the difference.
Want the taste file walked through live?
Twenty minutes, vm-claude-md.ts on screen, a running sandbox, and a habit tracker you keep at the end.
Frequently asked questions
What does mk0r actually do that Bubble, Adalo, Glide, and Figma Make do not?
Those tools give you a visual editor and an AI hint box. You still choose the theme, the font, the card layout, and the hero pattern. mk0r ships the opposite: no visual editor, and an opinionated agent that already refuses the aesthetic choices most non developers would accidentally pick. The opinions live in a plain text file at src/core/vm-claude-md.ts. The file is 2,354 lines long, it is written into the sandbox as /root/.claude/CLAUDE.md and /app/CLAUDE.md before your first prompt arrives, and Claude reads both on its very first tool call. When you ask for a dashboard, the agent has already been told not to produce purple indigo gradients on a white background, not to reach for Inter or Roboto, not to put decorative icons on feature cards, and not to center every hero section with a gradient button. That list is quoted below.
Why does a written taste file matter more than a nicer template library?
Non developers do not choose templates in isolation. They choose a template, accept its defaults, then have the AI fill in the blanks. Every default becomes an anchor the AI will pattern match on. If the template already has purple to indigo gradients and Inter, the AI will extend them. mk0r skips the template step entirely. The agent is told, in English, what good looks like and what it is not allowed to produce. That moves the aesthetic decision from a dropdown menu the user did not understand onto a written rule the model applies consistently.
Where exactly is the anti pattern list in the code?
src/core/vm-claude-md.ts lines 168 to 176, inside the Design Constraints section of the globalClaudeMd export. The heading is '### Anti-Patterns (Never Do These)'. The six bullets are: 'Purple/indigo gradients on white backgrounds', 'Uniform rounded cards in a grid with icons', 'Generic hero section with centered text and a gradient button', 'Every section looking the same with slight color variations', 'Cookie-cutter layouts that could be any app', and 'Placeholder images or Lorem Ipsum left in place'. Those lines are shipped to the agent verbatim. You can open the repo and verify the line numbers.
How does the agent verify its own output?
A headful Chromium runs inside the same sandbox on an Xvfb display at :99, 1600 by 900, with its remote debugging port on 9222. A Playwright MCP server is attached to Chromium over CDP at 127.0.0.1:9222. In vm-claude-md.ts lines 278 to 283, under 'Browser Testing', the agent is told after every UI change to 1) navigate to http://localhost:5173 via Playwright MCP, 2) take a snapshot to verify the DOM rendered correctly, 3) check browser_console_messages for runtime errors, 4) confirm the component is imported in App.tsx if the page is blank, and 5) not report completion until the browser shows the expected result. That is a closed loop. The agent writes code, looks at the page in a real Chromium tab, and only hands control back if the render matched its intent.
What happens when the user asks for purple on white anyway?
The rule is scoped by a single sentence above it: 'These rules apply unless the user explicitly overrides them.' If you type 'I want a purple and indigo landing page,' the agent obeys the override. The anti pattern list is a default, not a lock. The point is that a non developer who types 'build me a habit tracker' will not get a purple and indigo habit tracker by accident, because the default is the taste file, not the model's underlying aesthetic tendencies.
Do I need to pick a design system or framework?
No. /app is already a Vite plus React plus TypeScript plus Tailwind v4 project. The dev server is already running on port 5173 with hot module reload. When the agent edits files in /app/src/ the page reloads automatically, and the agent's browser check sees the new render in seconds. You never pick a stack, you never install a framework, and you never open a terminal. The agent does all of that inside the sandbox.
Can I still see or own the code?
Yes. Every prompt commits to a local git repo initialized at /app by ensureSessionRepo in src/core/e2b.ts. You can revert a commit, redo it, and jump between shas using the built in UI. The agent can also push your app to a private GitHub repo that was auto created under m13v/ at session start; the repo url is in /app/.env from turn one. If you want the source, it is real TypeScript on your own private repo, not a Bubble export.
How is this different from just prompting Claude directly?
Prompting Claude in a chat window gives you a model with no agentic tools, no browser, and no opinions about your app. mk0r wraps Claude in three things: the taste file above, a running Vite dev server with Chromium attached, and the Playwright MCP that lets the agent open the app and read the DOM. The agent does not have to imagine the page, it can look at it. That is the difference between 'here is the code you asked for' and 'here is the code, I opened it, it renders, I fixed the bug the console complained about, your turn.'
Is there a signup wall?
No. The landing page writes a session key to localStorage as mk0r_session_key on first visit. POST /api/vm/prewarm fires on page mount to warm a sandbox in the background via a Firestore pool. By the time you have picked a prompt, there is already a booted VM with Chromium, Vite, Playwright MCP, git, and a pre provisioned /app/.env waiting for the claim transaction. No email, no OAuth, no pricing modal before the product.
Describe your app. The file will supply the taste.
No account. No pricing modal ahead of the product. One sentence lands on a sandbox that already knows what not to produce.
Open mk0r