Heelix / Winning Group / Project note
One repo, three platforms, and an AI that needed house rules
How I restarted Heelix from a blank repository as the sole frontend engineer for web, iOS and Android, while the wider engineering team challenged every architectural decision and AI-assisted coding changed how we worked.
- Role
- Lead Frontend Architect
- Period
- 2026–present
- Disciplines
- Greenfield Architecture · Cross-platform Engineering · Frontend Platform Engineering · Feature-Sliced Design · Design Systems · Developer Experience · AI-Assisted Engineering
- Technologies
- React · React Router · React Native · Expo · Expo Router · Nx · TypeScript · Tailwind CSS · NativeWind · TanStack Query · Zustand · Zod · React Hook Form · Clerk · Storybook · Figma Code Connect · ESLint · Vitest · Bitbucket Pipelines · Google Cloud
I had been waiting eleven years for this
Near the end of 2025, my engineering manager asked the frontend group what we would build if we were starting a fresh product that needed to run across web, iOS and Android.
There were plenty of answers.
Not long afterwards, he asked whether I wanted to create the new Heelix frontend. I had already been planning to ask for it.
I had been waiting eleven years for that question.
My previous major ground-up rewrite was Appliances Online in 2015. I love a blank repository: the slightly terrifying moment when every architectural decision is still available and none of the bad ones have had time to become “the way we do things.”
Winning Group had several lead-level frontend engineers, so being selected meant a lot without making the project a competition. Those engineers, along with my manager, would go on to challenge the decisions rather than politely wave them through. The immediate working team is smaller: I’m currently the sole frontend engineer, alongside a .NET backend engineer and a project manager who also helps with QA.
The existing Heelix product was about five years old. Its web application used PHP, with separate native iOS and Android applications. The problem wasn’t the people who had built it. The team and technology model around it had changed: there was no longer an in-house PHP developer or dedicated native engineers, and mobile changes regularly depended on outsourcing.
We could no longer comfortably own all three surfaces.
This wasn’t a project that needed another framework upgrade. It needed a new beginning.
The argument started before the repository did
Before the new repository had its first real file, we were already arguing about what belonged inside it.
The brief required web, iOS and Android. Several experienced frontend engineers looked at that problem and reached different answers. Angular with Ionic was the safer organisational choice: Winning Group understood Angular deeply, Ionic promised more shared UI, and future maintenance would begin from familiar ground.
I understood the attraction. I had spent years working deeply with Angular and could have chosen the path I already knew well.
React Router with Expo asked us to accept two rendering models, more architectural decisions and separate web and native implementations for much of the interface. My engineering manager had also felt the frustration of trying to assemble an opinionated application from React’s less-opinionated ecosystem.
These were not weak objections.
The disagreement wasn’t React good, Angular bad. It was familiarity now versus platform direction later. Maximum sharing versus appropriate platform behaviour. WebView convenience versus a genuinely native rendering path. Lower initial decision cost versus more control over the foundation.
I had opinions, but an opinion is much more useful after you have tried to build with it.
So I built six working prototypes.
Expo Web. React Router with Expo. React with Ionic. Angular with Ionic. React behind Capacitor. Angular behind Capacitor.
The prototypes made the compromises tangible. I was not trying to prove that React was better than Angular. I was trying to work out which compromises we wanted to live with.
React Router matched an authenticated web product backed by existing .NET APIs without adding a Node server the product didn’t need. Expo reduced the native infrastructure we would need to own, and React Native gave mobile a genuinely native path. In return, we accepted that much of the web and native UI would be built separately.
I did not choose the stack that shared the most code. I chose the one that shared the right code.
Once we accepted that a browser was not an iPhone, the architecture became much clearer.
Sharing logic without pretending a browser is an iPhone
A browser is not an iPhone.
Heelix shares domain models, Zod schemas, API contracts, state and business logic, authentication interfaces, routing abstractions, icon sources and design language. Those are useful things to keep consistent.
It doesn’t force every layout, navigation pattern, interaction or visual component through one universal implementation. When a shared concept needs different rendering, .web and .native files provide it behind the same interface. React Router and Expo Router remain free to behave like the platforms they serve.
Authentication works the same way. Product features depend on Heelix-owned interfaces rather than importing Clerk everywhere. Web and native can then use different SDK details without spreading them through the product.
Everything lives in one Nx workspace, but one repository was useful only if it made ownership and dependencies more visible. The first broad shared library started collecting unrelated concerns almost immediately. I split it before “shared” became another word for “nobody is quite sure where this belongs.”
The architecture supports web, iOS and Android, with web currently the leading surface while the native foundations continue to grow. Shared architecture is not the same thing as feature parity.
Choosing what to share answered one question. The next was where all of that code should live.
The architecture was wrong, and that was useful
I chose Feature-Sliced Design because its vocabulary matched the questions I wanted the codebase to answer. Is this a page, a widget, a user action, a domain entity or genuinely shared infrastructure?
That language helps a future developer navigate by product responsibility. It also gives an AI agent a better chance of putting code somewhere sensible.
Then the architecture proved me wrong.
The first structure didn’t include a proper pages layer. A complete reporting page ended up inside features because, during early delivery, that location seemed close enough. Once the reporting work became real, it was obvious that route composition, reusable report behaviour and product actions had been pushed into the wrong shape.
I added the pages layer. Route files became thin connectors. Shared reporting behaviour moved into an entity.
A greenfield architecture is not valuable because every first decision is right. It is valuable because the wrong decisions are still cheap enough to change.
Defending the original structure would have been easier for my ego and worse for the project.
Feature-Sliced Design began as documentation. As the workspace grew, the meaningful parts became Nx tags, ESLint boundaries and pull-request checks. A feature can’t import a page. Mobile can’t import a web-only library. Product features can’t reach directly into Clerk.
The enforcement isn’t perfect. Some mixed-platform projects limit how precisely tags can describe intent, and a passing lint command cannot certify good architecture. It can, however, stop an accidental dependency from becoming tomorrow’s accepted example.
The folder structure gave the code a language. The design system needed to do the same for the interface.
When Figma stopped being a handoff
Design often moves in one direction. A team creates a component in Figma, engineering interprets it, small differences accumulate and eventually the design file and production code become two related but different versions of the truth.
My engineering manager and project manager gave me time to build the foundations before asking for a large wall of visible UI. That let us connect a Figma UI Kit, shared primitives, Storybook, Figma Code Connect and generated web and native icons before the differences multiplied.
The first time I could select a component in Figma and see its real React implementation connected to it, the design stopped feeling like a picture of the product. It started feeling like part of the product.
Figma could point towards the code. Storybook could show the code back to design.
Code Connect maps design properties to real component props. Storybook exposes implemented states, responsive viewports and themes. Tokens, typography and primitives give design and engineering a shared language. Icons keep one SVG source while becoming components suited to web and native.
Then that connection changed the AI workflow.
When Cursor receives a Figma design through the connected tooling, it doesn’t have to guess everything from pixels. It can see existing primitives, component APIs, supported variants, tokens, icons, Storybook states and the rules describing where the implementation belongs.
The design system became something the AI could see, not merely something we hoped it would respect.
That doesn’t make implementation automatic. An agent can still choose the wrong primitive, miss a product rule or create a local variation the system doesn’t need. Human review decides whether the result belongs.
Some Code Connect mappings and native counterparts are still evolving. Even so, this was the moment the design system stopped being a catalogue of components and became part of the development engine.
Once the components, tokens and variants were visible, AI finally had something better than screenshots and good intentions to work from.
Thirty years of writing code, and then the job changed
My first programming experiments happened before Pentium-era computers. One involved putting marks on physical paper, scanning them into a computer and trying to make a cube appear.
I was among the first people in my city to connect to the internet. I started building during the early days of HTML, then moved through Flash, interactive work, games, native iOS applications, large frontend systems and enterprise architecture.
For most of that time, being a programmer meant writing the instructions yourself.
AI changed that assumption.
I increasingly think of my role as moving from writer towards editor: not an editor who tidies the machine’s punctuation, but an architectural editor who defines the system, frames the problem, provides context, rejects the wrong shape and accepts responsibility for the result.
AI is good. It has genuinely transformed how I work.
It accelerates UI implementation, forms, styling, API integration, repetitive code, refactoring, documentation and debugging exploration. It can move an idea from a plan towards production-quality software remarkably quickly.
After almost thirty years of programming, I don’t need to prove that I can spend an afternoon wiring a form. I’d rather spend that afternoon deciding whether the form belongs there, what it may depend on and whether the next engineer will understand it.
That leaves more of my day for system design, architecture, product modelling, boundaries, review, maintainability and long-term direction. The job didn’t become less technical. It moved upwards.
Before the repository existed, I gave the same architecture prompt to Copilot, ChatGPT, Gemini, Claude and Cursor. Their answers informed my research. I still created the Nx workspace, installed the applications and established the first foundations manually. Cursor became the approved ongoing tool through Winning Group’s privacy-mode business account. I experimented with Claude Code personally, but it wasn’t the company workflow for this repository.
Heelix is fully AI-assisted. It is not AI-architected.
I began with a few instructions, not an enormous governance manual. As failure patterns repeated, some lessons became clearer context, others became reusable rules, and important boundaries became ESLint, Nx and CI enforcement.
Cursor presents changed files for review one at a time. I inspect them, request corrections or edit manually, run the checks and only then commit and create the pull request.
The system has limits. Context becomes stale. Too many rules can conflict or consume attention. AI can follow the words while missing the intention, and locally correct code can still be structurally wrong.
The more code AI helped create, the less interested I became in short-lived prompting tricks. I became more interested in architectures that remain stable and maintainable while implementation volume increases.
The job didn’t move me away from engineering. It moved a larger part of my day towards the engineering work I value most.
Producing code faster was no longer the difficult part. Preserving a system worth inheriting was.
The platform I want the next engineer to inherit
Product work has already tested those ideas.
The Vibe survey shares one core behaviour across a home-page modal and a dedicated route. Anonymous reporting keeps insufficient responses distinct from loading, no access, empty data and failure. A product-specific trend chart became a focused SVG implementation because precise geometry and product meaning mattered more than a large dependency’s unused features.
These are small examples, but they reveal whether the architecture preserves the product or merely organises its files.
Heelix is currently in SIT and staging rather than production. Web is the most advanced surface, while the native foundations continue to develop alongside testing, Code Connect coverage and architectural enforcement.
The deeper test is inheritance.
Can another frontend engineer enter the repository and understand where a feature belongs, what it may import, which components already exist, why web and native responsibilities differ, what the AI may change and how the work is verified?
Appliances Online taught me how to begin a frontend platform. Heelix is teaching me how to begin one in an era when code can be produced faster than any one engineer could write it.
The product may pause, change direction or accelerate. Its architecture should not require me to personally retell the story every time work resumes. It needs to support human and AI contributors without becoming dependent on my memory.
AI can produce more code than I ever could alone. That is useful, but it is not the part of Heelix I’m most proud of.
I’m proud of the boundaries around that code: where it belongs, what it may depend on, how it connects to design and how someone else will eventually understand it.
Eleven years ago, I built the beginning of Appliances Online largely by writing the frontend myself.
With Heelix, the implementation process has changed completely.
The responsibility has not.