Standardizing Development in an Era of AI-Generated Code
Impact
Starters as an internal product, adopted team-wide
When AI gave developers full control over the code, we lost the limits that kept projects consistent. I built starters with automatic guardrails, owned by the whole team.
On a recent web and mobile development team, I lived through a shift moving at real speed. For years we'd built products on low-code platforms, where the platform itself enforced how things got built. AI code-generation tools changed that almost overnight — a developer could go from working inside a low-code platform's constraints to having practically full control over the source code. That opened up real possibilities, but it also removed limits that, invisible as they were, had kept projects consistent.
When five or six developers use AI tools to build applications, even the same tool, they are very likely to end up solving the same problems in completely different ways. Not because one solution is better than another — simply because they now have the freedom to choose. The problem shows up when that freedom starts affecting the quality and maintainability of the codebases, things like files nobody uses anymore, functions declared but never called, unnecessary dependencies, duplicated code, inconsistent configuration, different rules across projects, commits that are hard to trace, scripts that work on one developer's machine and fail on another's. It is easy to ignore each of these while building a specific feature, but stacked up, they end up growing the size of the applications, making them harder to maintain, and creating friction for the rest of the team. AI had considerably reduced the cost of producing code. Now we needed to make sure it also reduced, instead of increasing, the cost of maintaining it.
Building guardrails, not restrictions
Instead of trying to enforce a single way of coding, I started working on a set of starters and internal tooling that set a common minimum for our projects. Developers still had the freedom to decide how to solve a problem, but the codebase needed automated mechanisms that prevented the most common mistakes. The starters shipped with type checking, ESLint and quality rules, automated validation, Conventional Commits, dev and build scripts, consistent configuration for web and backend projects, and rules and skills specific to working with development agents. The difference was in where we placed the responsibility. We did not want to tell developers exactly how to write every function — we wanted certain minimum properties of the codebase to be automatically verifiable. If a tool could validate something, there was no reason to turn it into a human discussion during code review.
AI-based development tools brought another challenge. A developer can pick up a team's conventions after months inside an organization; an AI agent does not necessarily have that context. So we started building in rules and skills that carried part of those conventions directly to the tools developers were using, so the project's context did not depend exclusively on every person remembering how a given task should be done. The codebase started describing part of its own rules. The goal was not controlling the agent. It was giving it enough context to produce code compatible with the project from the start.
The starter as an internal product
Over time, the starters stopped being just a set of config files and turned into something closer to an internal product. Developers used them to start new projects, and as they did, new use cases kept surfacing — a script that worked fine on Linux but needed tweaks for Windows, a validation that missed a real scenario the team ran into, a rule that looked useful in theory but caused too much friction in practice. Instead of keeping the starters as a solution defined unilaterally, we opened up their evolution to the team.
We ran a retro to discuss how the starters were actually working on real projects. What stood out was that people who did not usually speak up much in this kind of conversation started sharing their experience, and every developer was using the tools in a slightly different way, which surfaced problems we had not anticipated. The conversation moved from “these are the rules we should use” to “what do we need as a team to work better?” That difference mattered — standardization stopped being something imposed from above and became a shared responsibility, with developers themselves proposing improvements and debating what was actually worth standardizing.
One of the most concrete lessons came from the least interesting details — the scripts had to work across different operating systems. I worked mostly on Linux, while part of the team was on Windows, and something trivial on a Unix environment could behave completely differently on Windows. That forced us to rethink how we designed our scripts, how we handled paths, commands, and system dependencies, and, above all, to stop assuming my local setup represented the rest of the team's. Standardization could not be based only on how the project worked on my machine. It had to work for the actual team.
Result
Adopting the starters let developers start new projects on a consistent technical baseline, without rebuilding every quality, tooling, and configuration decision from scratch, and it shortened the learning curve for people moving from a mostly low-code environment into development based directly on code and AI. But the most important result was cultural. The conversation stopped being about which AI tool each developer used and started being about how to get any tool to produce code that met the team's minimum standards. We did not need everyone using the same agent or solving problems the same way. We needed a common baseline that protected the product's quality regardless of who was writing the code or what tool they used to do it.
What I learned
AI is making code cheaper and cheaper to produce, and that shifts where engineering's real cost shows up. Once writing code stops being the main constraint, maintaining it, understanding it, validating it, and evolving it becomes the new bottleneck. That is why I think teams should not try to control every line their developers or their agents produce. They should build guardrails that let people experiment and move fast without losing the fundamental properties of a good codebase. This was not about standardizing how we coded. It was about standardizing the conditions under which code could enter the product.