Skip to main content

How to Modularize a Frontend for Real

Good modularization reduces blast radius and improves understanding. When it turns into folder theater, it only increases navigation cost.

Andrews Ribeiro

Andrews Ribeiro

Founder & Engineer

The problem

When a frontend grows, the urge to “modularize everything” shows up.

That can help a lot.

But it can also produce a cosmetic renovation:

  • more folders
  • more index.ts
  • more re-exports
  • more sophisticated names

and almost no real improvement in how the codebase evolves.

If the change does not reduce:

  • blast radius
  • cross-imports
  • reading cost
  • fear of touching the code

then it probably still is not real modularization.

Mental model

A good module creates a change boundary.

That means:

  • people changing the inside do not need to understand everything outside
  • people using it from the outside do not need to know its internal details
  • dependencies enter through more predictable points

Short version:

modularizing is not splitting the frontend into more pieces. It is making each piece depend on less context so it can stay healthy.

What good modularization usually gives you

1. More local reading

Someone opens a flow and can understand:

  • where it starts
  • what composes the screen
  • where the main logic lives
  • what is internal detail

Without architectural tourism across twenty random files.

2. A smaller public surface

A good module exposes little and hides a lot.

If everything can be imported from anywhere, the boundary is weak.

3. A smaller radius of change

When you change something inside a module, the goal is not to trigger side effects across too many areas.

If any adjustment forces you to touch half the application, the structure still is not helping.

Signs of architectural theater

Some smells show up quickly:

  • deep folders with little real criteria
  • barrels at every level
  • generic names like core, common, base, utils
  • one feature importing internal details from another feature
  • sophisticated structure with the same dependency mess underneath

That creates the feeling of architecture, but not real safety.

Simple example

Imagine an admin frontend.

The theatrical version:

  • modules/
  • shared/
  • core/
  • common/
  • presentation/
  • domain/
  • infra/

Everything exists.

But:

  • billing components import onboarding utilities
  • a search hook depends on a global store with no boundary
  • API details leak into screens

The more honest version:

  • each important area has its own folder
  • there is a clear entry point
  • details stay more local
  • shared stays small and strict
  • cross-imports are the exception, not the rule

It may look less “architected” in a screenshot of the tree.

But it is usually more sustainable.

A practical way to start

If the codebase is already large, better modularization rarely starts with a heroic migration.

It usually works better like this:

  1. choose an important and painful flow
  2. identify what is actually the public entry point of that slice
  3. reduce direct imports into internal details
  4. group together what changes together
  5. leave the rest for later

That is how real modules tend to appear little by little.

The role of dependency discipline

A lot of modularization fails because the tree changes but dependency rules stay loose.

If any file can import any other file:

  • shared grows the wrong way
  • modules lose their boundary
  • refactors become risky

Even without a formal tool, it already helps a lot to make agreements explicit, like:

  • one feature does not import internal details from another feature
  • the design system does not know domain logic
  • shared does not become a dump for everything left over

How a senior thinks

People who have suffered through large frontend codebases usually judge modularization by real effect:

  • did it become easier to change?
  • did reviews become more local?
  • did imports become more predictable?
  • does the team understand better where each thing belongs?

That bar is much better than any purely aesthetic argument about the directory tree.

Interview angle

This topic shows up in:

  • frontend system design
  • questions about scaling a React codebase
  • discussions about legacy and refactoring

Weak answer:

I would organize the frontend by modules.

Strong answer:

  • explains which boundary should be protected
  • shows how to reduce coupling
  • talks about public surface, dependency, and blast radius

That shows you are not confusing folders with architecture.

Closing thought

Modularizing a frontend is worth it when the system becomes more predictable both for the people building it and the people maintaining it.

If the new structure only produces more layers, more names, and more re-exports, it may be serving architectural ego more than the product.

Good modularization does not make the tree look sophisticated. It makes change feel less dangerous.

Quick summary

What to keep in your head

Practice checklist

Use this when you answer

You finished this article

Next article How to Evolve a Large Frontend Without Rewriting Everything Previous article When to Create a Custom Hook and When to Stop

Keep exploring

Related articles