Inherited the front end of a 150K-user app, mostly vibe coded

koolcodez2 pts0 comments

Inherited the frontend of a 150K-user app, mostly vibe coded - Kool Codez

A while ago I was in London, having a coffee with an old colleague. We had worked together on an option trading project I am still proud of, a rewrite of an old, obsolete Redux Saga monster that we turned into a genuinely good codebase despite the complex domain.

He told me things were still going great there, and then I proceeded to tell him that things feel a little rough on the team I am on now. He stopped me half way through my complaints about code quality, AI slop, and so on and simply asked:

How many users do you have right now?

150K.

We still only have a few traders. You can’t say your team is not doing it right with those numbers.

I know context matters, as we are now in different spaces, but regardless of that it still made me think about where to draw the line. When to accept or reject a change. What matters for the business.

The genuine answer is I am not sure. But this conversation keeps coming back to me from time to time, so I wanted to tell you what my current project situation is and how I am dealing with it.

The starting point

About six months ago I joined the team that builds the company’s internal AI app. it is the product the whole business runs on, which obviously gets a lot of attention, especially from the C suite.

The code is just not there. I am not saying that to be unkind, and I will admit further down that I contributed to some of it. It is what happens when a small team builds something fast, leans on AI a lot, and never gets a quiet week to clean up, because there is always another feature due and people waiting on it.

It was started in early 2025, heavily vibe coded. I was told that backend engineers would often implement features end to end, which meant touching the frontend too. There is a quote about AI that I find really amusing and it goes something like:

the AI generated code looks truly amazing until it is about your area of expertise.

Anyway, here is roughly what I found.

The web app, a TypeScript React app, was still on react-app-rewired. If you don’t know that, it is like being in the middle ages. Builds took about ten minutes.

Linting was set up from a random template and never integrated into the git workflow or CI/CD pipeline. So no linting really, and no editor linting set up either.

A few trivial unit tests. No working end to end suite.

TypeScript, but with any in a lot of places, with hand rolled client types that had drifted from the real responses.

No server state manager. Every component that fetched data reimplemented its own loading and error handling.

Forty or more open pull requests at any time. Spend a couple of days on a feature and you would come back hundreds of commits behind, so conflict resolution was the norm.

A hand rolled event bus where any component can fire an event and any other can be listening (reimplementing redux?!?). Of course event names being hard coded at each registration, so "my-event" -> "mY-event" drifting.

localStorage used to cache things it should not have, including base64 avatar images that just kept growing. At one point we started getting production errors because we hit the localStorage size limit.

One god context holding everything. Artifacts, uploaded files, presets, integrations, all in the same place.

4 different ways to upload files. Each with its own slightly different flavour (smelling vibe coding? lol).

The core component several thousand lines long, almost all of it callbacks, effects, state and flags, with a thin layer of actual UI at the very end.

Poor design system in place. Custom Tailwind tokens all over the place, no consistency for sizes, colours, spacing.

At times I am in shock at how things even work.

The obvious thing to do with all of this is nothing. It works, people use it, and nobody wants to take on the responsibility of making fundamental changes and risking regressions.

JK I don’t care. I just can’t spend every day in a codebase that feels like hell. The space is cutting edge, the project is exciting, but man, that repo is not fun, and I want to have fun at work and ship fast and confidently.

One thing about how I work, because it shapes the rest. I think vibe coding on the job is irresponsible. Shipping code that nobody on the team understands into a product this many people depend on is a bet you eventually lose, and someone else usually pays for it. I use AI constantly, but as a tool, with rules, going back and forth with it and reading everything before it lands.

I will not ship code I do not understand into something this many people depend on. I need to be able to hold it in my head. That is not principle for its own sake, it is the only way I can move fast without making things worse.

So here is the adventure

First thing I did was move to vite. Sorry webpack but your days are gone. It took me about a week and a half, and it cut builds from around ten minutes to barely two, with...

vibe still things team code from

Related Articles