Leading a frontend team across different stacks
Topics: leadership · teams · frontend
I lead a frontend team of eight engineers in an environment with roughly 30 repositories. Some use React, some Next.js, TanStack Start, or Astro. Even inside the same framework, versions, data access, and build setup differ.
It would have been easy to write a plan to standardize everything. It also would have been easy for that plan to consume months without fixing the problem the team faces each day.
The problem is not that two repositories use different libraries. It is that an engineer may open one for the first time and not know how to run it, where the types live, which checks are required before merge, or who can review the change. I started with that experience, not the package list.
Understand why a difference exists
The first thing I need is a small map of active repositories: stack, runtime version, development and test commands, deployment path, owner, and current rate of change.
That map separates two kinds of difference. One is intentional: a project needs a specific build or runtime for a reason that still exists. The other is historical: a setting remains because nobody has needed to change it.
I do not treat them alike. I document the intentional difference and leave it alone. A difference that repeatedly causes failures or slows every new contribution becomes improvement work.
An active repository deserves more attention than a stable one that changes twice a year. Upgrading the second may make the version table look cleaner, but it does not make the team faster. I spend the effort where it will return time on the next piece of work.
Standardize the route into the code
The code does not need to look the same for the way into it to be predictable. The first things we standardize are the commands:
- one clear development command;
- one formatting and lint command;
- one test command;
- one known production build.
When an engineer enters a new repository, reading package.json should not be an open-ended investigation. The internals may differ, but the starting point is familiar.
I apply the same idea to the README. I do not need a long document that records the project's full history. I need prerequisites, startup, local environment variables, current owners, and the checks required before merge.
Those details look small. Across dozens of repositories, the time returns to the team every week.
Keep one review standard
I cannot force the same implementation style onto an older Astro project and a new Next.js application. I can ask for the same level of thought.
In review, I care about these questions:
- Did only the intended user behavior change?
- What happens when a request fails or data is incomplete?
- Can the screen be used with a keyboard?
- Was the expected data volume considered?
- Can the change be rolled back safely?
Those questions travel across repositories. A small React style preference belongs to the formatter or the local project agreement.
I also ask reviewers to explain the reason. “We do not write it this way” is useless in a team with multiple stacks. “This request can return older data after the filter changes” describes a risk that remains useful when the library changes.
Do not make the team lead the queue
At first, the lead may be the person with the broadest context. If every pull request waits for that person, the lead becomes a bottleneck.
Each active repository needs a primary owner and someone else who can review and release it. A small, reversible change does not need my approval. A decision that changes a shared contract or becomes a pattern for future projects deserves a short written decision before implementation grows expensive.
I review changes that need a wider view: work across repositories, architecture that will guide new projects, or a high-risk path. The rest stays with the team under a clear standard.
This does not lower quality. Knowledge stops being held by one person, and engineers learn to judge a change rather than wait for a judgment.
Let review cross repository boundaries
In a monorepo, engineers see nearby code almost by accident. In a polyrepo, someone can work for months without seeing what changed around their area. I encourage reviews outside the usual ownership boundary when a pattern can help another project.
I do not assign those reviews randomly. I choose one where the reviewer can learn a neighboring part of the system or contribute experience the author does not have. One review like that can teach more than a long architecture presentation.
Repeated decisions also need a home. If the same architectural reason has been explained in three pull requests, it becomes a short reference the team can find. Coding agents can read that reference too.
Stop the differences from growing
I do not rewrite every old repository. New work still needs a known starting point: default stack, data-access pattern, test setup, and deployment path. A project can depart from that path when there is a reason worth the future cost.
That rule prevents a simpler problem than migration: creating today the repository the team will have to repair tomorrow.
For older code, I connect improvements to product work. If a feature needs a React upgrade or data-layer change, the migration becomes part of the feature and reaches production with it. A project to “update everything” without a product reason often begins with energy and stops halfway through.
Where coding agents fit
I use Codex, Claude, Cursor, and other tools every day, but they do not solve repository differences automatically. An agent that does not know the commands or boundaries repeats the mistakes of a new engineer, only faster.
We give it the same context the team needs: repository-local instructions, custom skills for repeated design decisions, clear limits on what can change, and checks that do not vary by task.
Some workflows connect through MCP and E2E tests. The point is not to make the agent write more code. The point is to make it verify a change inside our way of working. I review the result with the same questions: did it understand the problem, did it change more than requested, and does the test prove the real behavior?
How I know the system improved
I do not measure the percentage of repositories using the same tool. The practical measure is how long it takes an engineer to make a small, safe contribution in a repository they have not seen before.
If they can find the start command, know who reviews, understand the required checks, and reach a first pull request without a rescue session, the environment is helping. If they remain blocked while every repository uses the same React version, standardization did not solve the important problem.
Leading this kind of team is not a cleanup project that ends. It is ongoing work to reduce surprises: standardize what repeats, document intentional differences, and remove the differences the team pays for.