Another Developer

Simple and effective folder structuring with Node.js

Published 8 september 20194 min read0 Comments
TL;DR
  • Use an src folder.
  • Organize your folders by domain.
  • Keep filenames simple in the domain folder.
  • Keep things simple.
And/or read on...

When opening the project; "Ah, models, api’s, routers are all neatly organized, NICE!". And then you expand a folder…

Why are there so many files

Oh dear! The folders are so big, I cannot find anything and everything is all over the place. How am I suppose to to fix this issue?
- Some Node.js developer, somewhere

Use an src folder

When I create a Node.js project, I always create an src folder which I use as a container for all the other folders. When you create all the folders on the root of the project and you want to find something in all your project folders, then node_modules and other system folders are pretty annoying. Off course you can do , -*/node_modules/* in your Sublime search string, but still it’s annoying to type that every time. When you have an src folder, you can just search in that folder.

Organize your folders by domain

Do you know what happens when you’ve organized your project by technical components and it becomes pretty big… Let me tell you, you are scrolling a lot.

Scrolling

I do not like to scroll a lot and search for related files when working on a feature.

So you might not want to do this:

src
│    server.js       # Server entry point
└─── api             # Contains all business logic
└─── initializers    # Initialize app components
└─── jobs            # Jobs definitions
└─── models          # Database models
└─── processors      # Event/MQ handlers for async tasks
└─── routes          # Express routes for all the endpoints of the app

This might look nice at first, but as your app grows, this happens:

src
│    server.js       # Server entry point
└─── api             # All the business logic is here
│   └─ customersApi.js
│   └─ deliveriesApi.js
│   └─ inventoryApi.js
│   └─ ordersApi.js
│   └─ productsApi.js
│   └─ transactionsApi.js
└─── initializers    # Initialize app components
│   └─ customersInitializer.js
│   └─ deliveriesInitializer.js
│   └─ inventoryInitializer.js
│   └─ ordersInitializer.js
│   └─ productsInitializer.js
│   └─ transactionsInitializer.js
└─── jobs            # Jobs definitions
│   └─ customersJobs.js
│   └─ deliveriesJobs.js
│   └─ inventoryJobs.js
│   └─ ordersJobs.js
│   └─ productsJobs.js
│   └─ transactionsJobs.js
└─── models          # Database models
│   └─ customerModel.js
│   └─ deliveryModel.js
│   └─ inventoryModel.js
│   └─ orderModel.js
│   └─ productModel.js
│   └─ transactionModel.js
└─── processors      # Event/MQ handlers for async tasks
│   └─ customersProcessor.js
│   └─ deliveriesProcessor.js
│   └─ inventoryProcessor.js
│   └─ ordersProcessor.js
│   └─ productsProcessor.js
│   └─ transactionsProcessor.js
└─── routes          # Express routes for all the endpoints of the app
    └─ customersRouter.js
    └─ deliveriesRouter.js
    └─ inventoryRouter.js
    └─ ordersRouter.js
    └─ productsRouter.js
    └─ transactionsRouter.js

All these folders will grow at the same speed your application will grow. And eventually when you need to modify something on your customers feature, you are working in many folders at the same time.

So instead, you might want to go for domain-driven folders like this:

src
│    server.js       # Server entry point
└─── adapters        # Generic components (DB connection, Agenda/Bull initialization, Express initialization)
└─── customers       # All components related to customers
└─── deliveries      # All components related to deliveries
└─── inventory       # All components related to inventory
└─── orders          # All components related to orders
└─── products        # All components related to products
└─── transactions    # All components related to transactions

Now when you are working on the customer feature, everything is within hand’s reach, and this scales better than organizing your folder by technical type.

Keep filenames simple in the domain folder

I use simple filenames:

  • api.js: contains all functions which are called from the router or relatd resources)
  • index.js: exports the api, the router and the initializer
  • initializer.js: initializes the store
  • jobs.js: contains all jobs
  • processor.js: contains all Event/MQ handlers for async tasks
  • router.js: contains the Express/Koa router
  • store.js: contains all database functions

All my domain folders contain the same filenames:

src
│    server.js       # Server entry point
└─── adapters        # Generic components (DB connection, Agenda/Bull initialization, Express initialization)
│   └─ agenda.js
│   └─ db.js
│   └─ express.js
└─── customers       # All components related to customers
│   └─ api.js
│   └─ index.js
│   └─ initializer.js
│   └─ jobs.js
│   └─ processor.js
│   └─ router.js
│   └─ store.js
└─── deliveries      # All components related to deliveries
│   └─ api.js
│   └─ index.js
│   └─ initializer.js
│   └─ jobs.js
│   └─ processor.js
│   └─ router.js
│   └─ store.js
└─── inventory       # All components related to inventory
│   └─ api.js
│   └─ index.js
│   └─ initializer.js
│   └─ jobs.js
│   └─ processor.js
│   └─ router.js
│   └─ store.js
└─── orders          # All components related to orders
│   └─ api.js
│   └─ index.js
│   └─ initializer.js
│   └─ jobs.js
│   └─ processor.js
│   └─ router.js
│   └─ store.js
└─── products        # All components related to products
│   └─ api.js
│   └─ index.js
│   └─ initializer.js
│   └─ jobs.js
│   └─ processor.js
│   └─ router.js
│   └─ store.js
└─── transactions    # All components related to transactions
    └─ api.js
    └─ index.js
    └─ initializer.js
    └─ jobs.js
    └─ processor.js
    └─ router.js
    └─ store.js
Keep things simple

Coding and naming things is hard as codebases grow and become more complex. Complexity slows you down in the long run, only choose complex solutions if you are 99% to 100% sure it will pay off. Therefore:

  • Keep folders simple.
  • Keep filenames simple.
  • Keep folders and filenames similar across domains.
  • Be consistent, predictive and boring (sorry).

Where I work we have switched from a technical folder structure to a domain-driven folder structure with great results. We work with small teams (3-5 developers) on projects and we never needed complex architectures. I am also using this folder structure for personal hobby projects.

Key Takeaways
  • Use an src folder.
  • Organize your folders by domain.
  • Keep filenames simple in the domain folder.
  • Keep things simple.

Thanks for reading! I hope you enjoyed the read. If you have any questions and or remarks, please comment below or get in touch.

This is my first blog, any pointers or tips are very welcome!

Buy me a coffeeBuy me a coffee
Buying me a coffee will help me to finance this hobby project and to keep me awake ofcourse :)

Follow me on Twitter if you want to get my latest updates