DEV Community

Cover image for 🏗️ Designing a Project File Structure: Practical Guide Inspired by Clean Code Architecture
Farhan Shahriar
Farhan Shahriar

Posted on

🏗️ Designing a Project File Structure: Practical Guide Inspired by Clean Code Architecture

Designing a good file structure for your project is one of the trickiest yet most critical tasks. A well-thought-out structure keeps your project maintainable and helps you avoid constant refactoring headaches as the application grows.

There’s a design principle that guides us here, known as Clean Code Architecture. Though this is an advanced concept that we'll explore in detail later, it offers powerful insights into how and why to organize your code.

Right now, we’re building a Monolithic application. This means everything lives in a single deployable unit, rather than splitting into microservices. Monolithic architecture is often structured following what’s formally called Layered Architecture, but most developers simply know it as monolithic.

Let’s walk through the practical steps to structure your project so it stays clean, understandable, and scalable—even before fully adopting Clean Architecture.

đź—‚ Recommended Project Folders & Why They Matter

Here’s a practical breakdown of folders and files you should create, along with why each exists:

app/
Holds core application logic like custom errors, database connection code, the main app file, and global routes.
Note: This folder is separate from your server.js file.

routes/
Contains all your route definitions. Helps keep your HTTP layer organized and modular.

models/
Where you define data models (e.g., using Mongoose, Sequelize, etc.) that map to your database.

controller/
Each route typically has an associated controller function. This folder stores all controllers to keep your business logic separate from route definitions.

service/
We never want controllers to talk directly to the database. Instead, services handle database interactions or external API calls.
This cleanly separates business logic from database logic, making your code easier to test and change.

middleware/
Custom middleware functions live here. Examples: authentication checks, logging middleware, request validation, etc.

util/
Utility functions or helper scripts that don’t fit elsewhere.

db/
Contains scripts or configurations related specifically to database setup or migrations.

config/
Holds configuration files—for example, environment-specific settings, third-party service configs, etc.

log/
Store application logs here (especially if you use tools like Winston or Morgan).

error/
All your custom error classes or handlers live here, making error management consistent.

test/
Write your automated tests here—unit, integration, or end-to-end.

server.js
Your application's entry point. Sets up and starts the HTTP server.

.env & default.env
Store secrets, API keys, and environment-specific variables that should never be committed to source control.

Inside the app/ folder, you’ll often create an app.js file which sets up the Express app instance, applies middleware, and mounts your routes.
âś… Why this structure helps
Keeps concerns separated (routing, business logic, database logic, configs, etc.)

Makes it easy for new developers to find what they’re looking for.

Encourages writing testable, maintainable code.

Supports gradual migration to clean architecture principles (like Use Cases and Domain layers) if your project grows.

đź§Ş Going further: When you're ready for Clean Architecture
Clean Architecture takes these principles to the next level:

Defines domain, application, infrastructure, and presentation layers.

Enforces dependency inversion so core business logic doesn’t depend on frameworks or databases.

Makes your system highly testable and flexible.

But don't rush—start simple, then refactor gradually as complexity grows.

✍️ Final Thoughts
A clear, intentional file structure isn’t just about neat folders—it’s a foundation for scaling your project, onboarding team members, and keeping bugs away.

By following this practical approach inspired by clean architecture, you’ll save countless hours and future-proof your codebase—even if you’re building a monolithic application today.

Top comments (0)