John Roest

Package Structure

Mon Sep 08 2025

Package structure, keep it simple!

When you generate a new Spring Boot project, the framework immediately sets up a default package structure for you. It's simple, clean, and at first glance it might look a little too basic. Many developers, especially those who like to organize things "their way," are tempted to move files around, create custom folders, or break away from the conventions.

But here's the thing: the default structure is not arbitrary. It's carefully designed to work with how Spring Boot scans your code, wires your beans, and loads configurations. And beyond the technical side, there's a very human advantage---consistency.

Imagine joining a new company, opening a Spring Boot repository, and instantly recognizing the structure. You don't have to ask, "Where are the controllers? Why are there three different folders for configuration? Why is the main class sitting in some random subpackage?" Instead, you just get it. You know where to look, because the structure is exactly what you've seen in countless other Spring Boot projects. That recognition saves hours in onboarding and makes the learning curve much less steep.

The Default Structure in Practice

A typical Spring Boot project generated with Spring Initializr looks something like this:

src/main/java/com/example/demo
    DemoApplication.java
    controller/
    service/
    repository/
    model/

At the top level, you've got your DemoApplication class, which boots up the entire application. Then, by convention, you group your code into clear responsibilities:

  • controller for your REST controllers,\
  • service for your business logic,\
  • repository for your data access,\
  • model for your domain objects or entities.

Of course, you can add other folders if you need them---config, security, dto---but the core idea stays the same. Every Spring developer knows this pattern.

Now imagine a new developer joins the team. Within minutes, they can open controller/ and see how your endpoints are structured. They don't need a 30-page onboarding document explaining your "special" folder layout. The project feels familiar, which lets them focus on learning your business logic instead of fighting your file system.

Why Consistency Beats Creativity

Breaking away from the default often starts with good intentions. Maybe someone wants to separate "API" controllers from "UI" controllers, so they create rest/ and web/ folders. Then someone else prefers handlers/ instead of controllers/. A few months later, you've got a patchwork of naming conventions that only the original authors understand.

Fast forward a year. Half the team is new, and nobody remembers why certain packages exist. Now, instead of clarity, the structure has become another barrier.

By sticking to the defaults, you give your future teammates a common language. The names may not be perfect, but they are universal. When you open a controller package in a Spring Boot app, you already know what to expect. That predictability is worth far more than the short-term satisfaction of inventing a custom structure.

Technical Benefits

There's also a technical reason to keep the defaults. Spring Boot automatically scans for components starting from the package of your main application class. If you place @SpringBootApplication in the root package, everything below it is detected without extra configuration.

For example:

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

If this class sits in com.example.demo, then all subpackages---controller, service, repository---are included in the component scan. That means your @RestController and @Service beans just work.

But if you scatter your classes into packages outside the base package, you'll need to add explicit @ComponentScan annotations. That extra work makes your project harder to maintain and less intuitive for new developers.

Sustainable Development

A codebase isn't just for the people who write it today. It's for the people who will maintain it five years from now, when the original authors may no longer be around. By following a common, well-understood structure, you reduce the risk of "tribal knowledge" being lost.

It also helps with tooling and documentation. Many tutorials, guides, and Stack Overflow answers assume you're using the default Spring Boot layout. When your project looks the same, you can apply those resources without translation.

Conclusion

Spring Boot's default package structure is more than just a starting point---it's a best practice baked into the framework. It keeps your project predictable, lowers the onboarding curve for new developers, and aligns seamlessly with Spring's component scanning.

Sticking to the defaults isn't about limiting creativity. It's about removing unnecessary friction, so your team can spend less time navigating folders and more time solving real problems.

The next time you spin up a new Spring Boot project, resist the urge to reinvent the wheel. The conventions are there for a reason, and following them makes life easier for everyone---today and years down the road.