Why We Separated the Admin Panel and Customer App into Different Repositories — Gains and Tradeoffs
Introduction
When building the DVD rental system, the first thing we struggled with was whether to put the admin panel and customer app in the same repository or separate them.
We ultimately chose separate repositories, but the decision wasn’t “clear from the start.” It was a decision made by deliberating, comparing, and accepting the tradeoffs.
Initial Thinking
The Temptation of a Monorepo
At first I thought “wouldn’t it be easier to put everything in one repository?”
- Could share DB definitions (Flyway migrations)
- Could reuse common utility classes
- Could unify CI/CD
For small-scale projects, a monorepo is sufficient. Many OSS projects do this.
However, we considered this
When thinking about the future vision of this system, something felt off.
- Admin panel: Spring Boot + Thymeleaf (server-side rendering)
- Customer app: Spring Boot + Vue 3 (SPA + REST API)
The tech stacks are fundamentally different. The frontend build pipelines, deployment strategies, and access control layers are different.
Putting them in the same repository would complicate pom.xml and package.json management.
Furthermore, there’s a vision to expand into a comprehensive platform like DMM in the future. With that broader view, “separating them from the start” felt more natural.
Three Questions Used as Decision Criteria
Question 1: Is the deployment unit the same?
The admin panel and customer app don’t necessarily need to deploy at the same time. We want to avoid admin feature additions affecting the customer-facing production environment.
→ If deployment units are different, separate repositories are simpler
Question 2: How to separate access permissions?
When the project becomes team-based, managing permissions when back-office staff and customer frontend developers touch the same codebase is cumbersome.
→ With separate repositories, GitHub access permissions can be controlled per repository
Question 3: Won’t it constrain future technology choices?
The customer app uses Vue 3, but we might want to switch to React someday. The admin panel uses Thymeleaf, but we might move to a Next.js-based approach in the future. With them in the same repository, one side’s dependencies constrain the other.
→ Repository separation is reasonable for maintaining loose coupling
Actual Structure
dvd-rental-admin/ ← Admin panel (Spring Boot + Thymeleaf + TypeScript)
dvd-rental-customer-app/ ← Customer app (Spring Boot + Vue 3)
dvd-rental-doc/ ← Design documents (shared resource)
Documents are consolidated in the dedicated dvd-rental-doc repository.
Shared DB definitions (ER diagrams, table specs) are placed there and referenced by both repositories.
Actual Pain Points with Separate Repositories
Let me be honest. There are downsides.
Double management of DB migrations
The Flyway in the admin side and the Flyway in the customer app side both target the same DB but are managed separately. Currently, we manage them centrally on the admin side and the customer app only does reads and API calls.
More processes to start locally
To run both locally:
- Admin panel: port 8081
- Customer backend: port 8082
- Frontend (Vite): port 5173
- PostgreSQL: port 15433
4 processes need to be started. Once you’re used to it, it’s fine, but initially it’s somewhat tedious.
No code sharing
When you want to reuse common DTOs or constants, with separate repositories you either manage them through a Maven repository as a shared library, or you copy them. Currently we’ve intentionally designed both repositories to be loosely coupled, so we have a “no-copy shared code” policy.
What We Gained
- Can design branch strategy and CI/CD independently per repository
- Technology changes (framework migration, etc.) are easier
- Release cycles for admin panel and customer app can be independent
- GitHub access permissions can be controlled per repository
Summary
“Should we use separate repositories” depends on team size, future expansion policy, and differences in tech stack. This time, the deciding factors were: “deployment units are different,” “tech stacks are fundamentally different,” and “don’t want to constrain future technology choices.”
There are many cases where a monorepo is the right answer. The important thing is being able to explain “why we chose that structure” in your own words.