Codebase Organization
TLDR
The following is the TLDR of how I believe you should organize your code base.
- organize code according to architecture not types of architecture element types
- if in framework that does organize by architecture elment types
- see if you can organize by architecture and then move the organization by element types into the folders representing the architectural components.
- if you can't, follow the framework convention up until you reach natural boundary (e.g.
lib
folder), then switch to organizing by architecture
Major Strategies
There are basically two major strategies people use to organize their codebases.
- around types of architecture components (e.g.
models
,views
,controllers
) - around actual application architecture
Around Types of Architecture Components
Frameworks like Rails and NestJS are examples that follow this strategy where
they have a folder for models
, controllers
, etc.
Organizing your codebase around these types of architecture components has the following advantages.
- you don't have to think very hard when you are trying to figure out where to
put something. Controllers go in the
controllers
folder,models
in the models folder, etc.
This benefit however is not always true because there is generally a boundary
where this falls apart as the framework doesn't provide direction. The lib
folder is often one of these boundaries. The framework provides guidence in
terms of organization right up until that point and then all of the sudden
lib
is just a dumpster full of stuff.
Organizing your codebase around these types of architecture components also
doesn't help people understand anything from the codebase other than that there
are things called controllers
, models
, and views
. But it doesn't give you
any knowledge in terms of how certain controllers, models, or views relate to
one another. You have no idea from the organization of the codebase how to find
a particular part of the application.
Around Application Architecture
An alternative approach that people take is to instead organize their codebase around the actual application architecture.
When you have put that thought in, people coming into the code base can quickly and easily understand the application architecture. They can also quickly navigate to appropriate areas of the code they want to focus on.
This strategy also helps with creating logical commits, which I am a big fan of, and reducing conflicts in source control systems.
People often perceive the fact that you have to think about where to put folders and files in your codebase as a negative thing.
I believe this effort is one of the more valuable activities actually. It is effectively a forcing function driving you to make sure you have a sound application architecture and understand where the piece you are working on should fit within it.
Using techniques like modularization and concepts like the The Onion architecture can help you figure out and evolve your application archicture and your codebase organization.
But with Frameworks
I know from experience fighting against a frameworks inherent design is generally not a great strategy. So how do we organize our codebase around the Application Architecture when we working with a framework like Rails or NestJS?
Simple, we follow the convention of the framework up until we reach that
natural boundary where it stops providing direction, e.g. the lib
folder.
Everything inside that lib
folder we would organize around application
architecture and not by category of architecture component.
This at least gives developers the knowledge around that area of the code. Ideally it would be great if we could get those benefits at the framework level of things as well. However, it just isn't worth fighting against the framework to make it happen.