Why I'm a Fan of Feature-Based Folder Structure — Since the Beginning

Suman SharmaSuman Sharma

When you start a new project, the first real architectural decision is not which framework you pick—it is how you organize the codebase.

I have tried both camps. Tutorials almost always teach function-based folders (components/, hooks/, utils/). That is where most of us begin. But I became a fan of feature-based structure early, and I have not gone back for anything beyond a small prototype.

This post is my take on function-based vs feature-based organization—what each looks like, when each wins, and why I default to features.

Developer workspace with code on screen representing project organization

The two approaches in one sentence

  • Function-based: group files by what they are (components, hooks, utils).
  • Feature-based: group files by what they belong to (signup, checkout, dashboard).

Same React app. Completely different mental model.

Function-based organization

In a function-based structure, directories are organized by the role each file plays. Components live with components. Hooks live with hooks. Utilities live with utilities.

A typical React src/ folder:

src/ ├── components/ ├── hooks/ ├── utils/ ├── services/ └── types/

Why people love it

  • Easy to find “all components” or “all hooks” in one place.
  • Encourages reuse—you see shared UI building blocks immediately.
  • Clean and predictable when the codebase is small.
  • Great for solo devs or tiny teams moving fast on one flow.

Where it breaks down

I have watched this pattern fall apart on real products:

  • A components/ folder with 200 files and no context.
  • A “shared” hook that only checkout uses—but lives three folders away from checkout.
  • Five developers editing the same giant directories and creating merge conflicts.
  • Onboarding that starts with “search the whole repo and guess where things live.”

Function-based structure optimizes for finding similar file types. It does not optimize for shipping a feature end to end.

Feature-based organization

In a feature-based structure, top-level folders map to product areas or modules. Each feature owns its components, hooks, utils, and often its API calls and types.

src/ ├── signup/ │ ├── components/ │ ├── hooks/ │ └── utils/ ├── checkout/ │ ├── components/ │ ├── hooks/ │ └── utils/ ├── dashboard/ │ ├── components/ │ ├── hooks/ │ └── utils/ └── profile/ ├── components/ ├── hooks/ └── utils/

Open checkout/ and you have everything for checkout. That is the whole point.

Why I am a fan—and have been from the start

Feature-based folders match how product teams actually work:

  • You think in features, not file types. “I am building profile settings” maps to one directory.
  • Teams can work in parallel. Checkout and dashboard rarely step on each other.
  • Boundaries stay obvious. Harder to accidentally couple unrelated domains.
  • Onboarding gets faster. New devs learn one feature slice at a time instead of the entire tree.
  • Scaling feels linear. Add a feature → add a folder. The structure grows with the product.

On client work and startup codebases, this saved me more time than any lint rule ever did.

The honest downsides

Feature-based is not free:

  • You may duplicate small helpers across features (until you extract shared code deliberately).
  • Reusable UI can be harder to discover if nobody maintains a shared/ or ui/ layer.
  • Too many tiny features → folder sprawl. Not every screen deserves its own top-level module.

Side-by-side comparison

Function-basedFeature-based
Best forSmall apps, solo devs, short timelinesLarger apps, multiple devs, long-lived products
Finding codeBy file typeBy product area
Team parallelismWeak—everyone touches components/Strong—teams own feature folders
ReuseNatural for generic UINeeds a deliberate shared/ layer
OnboardingSimple at first, confusing laterSlightly more setup, clearer long term
My defaultPrototypes & demosProduction apps

Function-based in practice (the good version)

Function-based is not wrong for a hackathon or a landing page. I still use it when:

  • The app has one main flow and fewer than ~20 components.
  • I am the only developer and will ship in a week.
  • The goal is speed, not a two-year roadmap.
src/ ├── components/ ├── hooks/ └── pages/

Keep it flat. Do not over-engineer folder depth for a weekend project.

Feature-based in practice (how I structure Next.js apps)

For App Router projects, I align routes and colocated code with features:

src/ ├── app/ │ ├── (auth)/ │ │ ├── login/ │ │ └── signup/ │ └── (dashboard)/ │ ├── analytics/ │ └── settings/ ├── features/ │ ├── auth/ │ │ ├── components/ │ │ ├── hooks/ │ │ └── api/ │ ├── analytics/ │ └── settings/ └── shared/ ├── components/ui/ ├── lib/ └── types/

Routes handle URLs. features/ holds domain logic. shared/ is for code that is genuinely cross-cutting—not a dumping ground for “I did not know where to put this.”

That hybrid keeps feature boundaries without banning reusable primitives.

When I switch strategies

Project stageWhat I use
MVP / proof of conceptFunction-based or minimal folders
First paying customersStart splitting into features/
Multiple engineersFeature-based with explicit shared/
Design system heavyshared/components/ui + feature folders

The mistake is picking function-based because a tutorial did—and never revisiting the decision when the team doubles.

The hybrid approach (what most mature codebases become)

Almost every large codebase ends up hybrid:

  • Feature folders for product logic.
  • Shared / ui / lib for primitives and cross-cutting utilities.
  • App router segments that mirror feature names where it helps.

You do not have to be purist. You have to be intentional.

Conclusion

Function-based organization wins on day one: it is simple, familiar, and easy to grep.

Feature-based organization wins on day three hundred: when the app has real modules, real teams, and real merge conflicts.

I have been team feature-based since the beginning because I optimize for where the project is going, not just where it starts. If you are building something meant to last—with more than one developer or more than one major flow—organize by feature. Your future self (and your teammates) will thank you.

If you are still on function-based folders and the components/ directory is starting to feel like a junk drawer, that is usually the signal. Split one feature out, see how it feels, and grow from there.

Contact

Get in Touch

Want to call me? book a call and I'll respond in the available time slot. I will ignore all soliciting.

GitHub
LinkedIn
youtube