Introducing Flint
A vibe coding platform that helped 500+ IBM colleagues turn ideas into working apps, presentations and tools.
Design Lead, Engineer
Flint was an internal natural language-to-application builder, similar to tools like v0 or Lovable, designed to allow non-technical IBM teams to create functional mini-apps from text prompts.
I led product design, design engineering and product strategy from inception through scale, shipping an MVP in four weeks and growing adoption to 500+ internal users within 12 weeks. Inspiring and creating a build and prototype culture internally at IBM.
I worked directly in production code to prototype new interaction patterns, and ran weekly user testing to inform rapid iteration. We collaborated with the new Carbon MCP team to keep outputs aligned with IBM's design system and brand standards.
Flint — Vibe coding platform
Built and scaled to 500+ users in 12 weeks with a two-person team.
Design Lead, Engineer & PM · IBM · 2025
Project Overview
Problem
Non-technical teams across IBM wanted to prototype internal tools to improve workflows, but building even simple applications required engineering support. Existing no-code tools struggled to produce outputs coherent with IBM brand, tooling and enterprise standards, which reduced trust and limited real adoption.
What I designed
Flint — a vibe coding that generated functional mini-apps from prompts and giving users the option to use Carbon design system constraints. I led product design and strategy from 0→1, prototyping directly in production code (and codebase) and running weekly user testing to iterate rapidly and scale up features.
Key insight
Users valued momentum over model sophistication. Fast, editable drafts created trust and engagement, while slower 'higher-quality' generations broke creative flow and ideation. Designing for rapid iteration and visible system feedback proved more important than maximising model reasoning depth.
Impact
→ MVP shipped in 4 weeks
→ 500+ internal users within 12 weeks
→ Average 5–10 apps generated per user
→ Established validation patterns for LLM-generated UI aligned to enterprise design systems
The Challenge
Designers, PMs and sales teams across IBM wanted to prototype internal tools, creative ideas to improve workflows, but building even simple applications required engineering support and core development skills.
This created a core product tension: build for engineers who want production-ready code, or build for everyone else who just wants a fast draft and iteration? Our first instinct was to optimise for power and polish, but that proved to be wrong.
What Broke in the First MVP
We shipped in four weeks. It broke immediately in predictable but instructive ways.
→ Outputs were dense and hard to parse.
→ Generated UIs frequently missed user intent.
→ Latency of roughly two minutes reduced perceived responsiveness.
→ Non-technical users did not understand why they would download code and apps did not persist reliably across sessions.
We found that users valued momentum and iteration more than polish and deep production code. Fast, editable drafts created trust and engagement, while slower 'higher-quality' generations broke creative flow and users ability to create ideas rapidly.
Three Assumptions I Got Wrong
1. Users need help writing better prompts
I assumed non-technical users needed structured guidance based on our user interviews, so I built a Prompt Enhancer but testing showed the opposite and most preferred writing rough concepts in their own words, some experienced a blank-screen effect, and others drafted in external models and pasted results in. The structured enhancer added friction, but we removed it and expanded the input instead.

2. Longer generation time means better outputs
We introduced a 'Deep Thinking' mode that gave the model more time. It improved code quality, but not user experience as the depth in code output overscoped the build.
Users preferred fast first drafts they could refine quickly and point to improvements. More reasoning often overfit to existing components without improving interaction quality. We optimised for speed by default and made deeper generation optional.

3. Community templates would drive growth
I assumed shared templates would accelerate adoption. In testing, users preferred building bespoke apps, but found some value in using repeat templates to understand the structure and prompts. Templates were useful for reference, but not for reuse. Ownership mattered more than remixing, so we deprioritised template-sharing and focused on fast individual iteration.

Scaling Adoption
We filled a 100+ user waitlist in days. Within twelve weeks, Flint had over 500 internal users generating an average of 5 to 10 apps each. Usage was sustained over 12 weeks of daily shipping. Carbon MCP integration ensured all generated components aligned with IBM standards and was starting to be used for client pitches, presentations and by individual sales teams to create bespoke apps. Flint was internal, but outputs were frequently shown in client settings.
The Real Product Reframe
Flint was initially positioned as a production code generator. That framing created anxiety: users questioned code quality, deployment expectations, and engineering standards. A research interview clarified the issue.
“I don’t feel confident showing designs in front of clients if they are not in Carbon and IBM branded.”
Participant in user research
That reframed two things at once. Carbon alignment became a product requirement. We integrated directly with Carbon MCP (which still wasn't generally released yet), IBM Plex Sans, and approved colour tokens to ensure outputs matched IBM standards by default. And we repositioned Flint as a rapid internal prototyping tool, not a production system. That shift reduced pressure around code quality and increased willingness to experiment.

Evaluation Framework & Output Validation
To prevent drift from IBM design standards, we introduced code-level evaluation using Carbon MCP and open-source Carbon references. Generated output was programmatically checked against these references.

Outputs failing validation were either blocked or passed back into the model with structured correction prompts. This created a lightweight evaluation loop: Generate → Validate → Correct → Regenerate.
Recursive Generation: When Flint Began Modifying Itself
We experimented with feeding parts of Flint's own codebase back into the model to generate refactors and small features. That was the moment the project changed scope. We had built a tool for non-technical users to create apps from prompts. What we had not anticipated was that the same loop applied to the product itself.
We tried narrowing context to specific files and summarising architectural state before regeneration. It reduced surface-level errors, but architectural drift remained without manual review. It led directly to the question that shaped Relay: if generative systems can operate across your product surface, what does structured supervision actually require?
What I Took From This
Flint started as a code generation tool. It became an exercise in defining where generative systems are dependable and where they are not. Repositioning it as a prototyping tool unlocked adoption. Carbon alignment unlocked trust and feeding it back into itself clarified its limits.
Recursive generation did not fail loudly but small inconsistencies compounded over time. Stability depended less on model capability and more on where autonomy was allowed. Flint was reliable at scoped component synthesis, and we continued to build for the next model which we need would compoundedly improve UI design, coding ability, motion and MCP capabilities.
Scaling to 500+ users came from aligning with how people work, building communities and listening to how our users were actually using our products and how to think about improving the tight iteration loops, whilst rapidly scaling our services to manage thousands of generations daily.
Tailwind · React · HTML · CSS · Carbon MCP · Agents · Skills · Jan 2026



