← Back to all Posts

How to organize files in a project

It depends on the project, the size and how it should scale. But there are some common patterns that can be used.

What type of Softwaresystem are you building?

There are mainly two big types of software systems:

In Monoliths all the code is in one big application. In Microservices the code is split into multiple applications.

Each Microservice can be considered as a Monolith. So the same rules apply to both. The only difference they make how the code is split into multiple applications. The Development can happen in one big repository or in multiple repositories.

In the following we only consider Monoliths or a single Microservice.

Lets start with a simple example

We assume the following project structure, which comes as a default for the kind of applcation we want to build.

├── src
│   ├── Console
│   │   ├── Users
│   │   │   ├── CreateUserCommand
│   │   │   └── DeleteUserCommand
│   │   └── Blog
│   │       ├── CreatePostCommand
│   │       └── DeletePostCommand
│   └── Http
│       ├── Users
│       │   ├── CreateUserController
│       │   ├── EditUserController
│       │   └── DeleteUserController
│       └── Blog
│           ├── CreatePostController
│           ├── EditPostCommand
│           └── DeletePostCommand
└── tests
    ├── Users
    │   ├── UserCanBeCreatedTest
    │   ├── UserCanBeUpdatedTest
    │   └── UserCanBeDeletedTest
    └── Blog
        ├── PostCanBeCreatedTest
        ├── PostCanBeUpdatedTest
        └── PostCanBeDeletedTest

As you can see we have points of entries into the system. The command line where you can execute a command and the http interface where you can send a request to.

This structure is very common and can be found in many projects. But it has some drawbacks, which can occur when the size of the project increases.

Domain Driven Design

If we start having more and more features, we will end up with a lot of files in the same folder. This can make it hard to find the right file. We can solve this by grouping the files by the domain they belong to.

├── Users
│   ├── src
│   │   ├── Console
│   │   │   ├── CreateUserCommand
│   │   │   └── DeleteUserCommand
│   │   └── Http
│   │       ├── CreateUserController
│   │       ├── EditUserController
│   │       └── DeleteUserController
│   └── tests
│       ├── UserCanBeCreatedTest
│       ├── UserCanBeUpdatedTest
│       └── UserCanBeDeletedTest
└── Blog
    ├── src
    │   ├── Console
    │   │   ├── CreatePostCommand
    │   │   └── DeletePostCommand
    │   └── Http
    │       ├── CreatePostController
    │       ├── EditPostController
    │       └── DeletePostController
    └── tests
        ├── PostCanBeCreatedTest
        ├── PostCanBeUpdatedTest
        └── PostCanBeDeletedTest

In this example we have two domains. Users and Blog. Each domain has its own folder. This makes it easier to find the right file. You could also add a Comment Feature to the Blog. Then the Comment Feature would be in the same folder as the Post Feature of the Blog Domain.

Tests near Features

Some people don't like how after they make changes to their code, they have to go to the tests folder and make the same changes there. This can be solved by grouping the tests with the features they test.

├── Users
│   └── src
│       ├── Console
│       │   ├── CreateUserCommand
│       │   ├── CreateUserCommandTest
│       │   ├── DeleteUserCommand
│       │   └── DeleteUserCommandTest
│       └── Http
│           ├── CreateUserController
│           ├── CreateUserControllerTest
│           ├── EditUserController
│           ├── EditUserControllerTest
│           ├── DeleteUserControllerTest
│           └── DeleteUserController
└── Blog / ...

This way you can find the tests for a feature right next to the feature. This makes it easier to find the right test and also makes it easier to see if a feature is tested.

One drawback is, that you have production and testing code mixed together. But this is not a problem if you remove the tests before you deploy the code. (In this case quite easy, because you can remove all files ending with Test)

My Homepage ·Contact · Privacy Policy
© 2025 Julius Kiekbusch