Explore vertical slice architecture, a modern approach to simplify codebases and accelerate feature delivery. Learn to build more maintainable web apps.
January 6, 2026 (12d ago)
A Guide to Vertical Slice Architecture in Modern Web Apps
Explore vertical slice architecture, a modern approach to simplify codebases and accelerate feature delivery. Learn to build more maintainable web apps.
← Back to blog
Vertical Slice Architecture for Modern Web Apps
Explore vertical slice architecture, a modern approach to simplify codebases and accelerate feature delivery. Learn to build more maintainable web apps.
Introduction
Vertical slice architecture organizes your code by business feature instead of technical layer. That means each feature—like “Create User” or “Submit Order”—contains its UI, API endpoint, business logic, and data access in one place. The result is faster feature delivery, fewer integration bugs, and an easier onboarding experience for new developers.
Why layered architectures slow teams down
For years, many teams used layered or N-tier architectures: a presentation layer, a business logic layer, and a data access layer. On paper this is clear, but in practice it often leads to high coupling and low cohesion. A single feature change—say, adding a “favourite” button—can require edits across UI, business logic, and database code, creating a fragile web of dependencies.
The ripple effect of changes
Developers end up bouncing between unrelated parts of the codebase to complete one task, increasing cognitive load and the risk of regressions. A recent survey of enterprise teams reported widespread cross-layer coupling, with changes to a single endpoint causing broad test failures across suites1.
This produces real consequences for modern development:
- Slow feature delivery — more time spent navigating the codebase than delivering value.
- Higher risk of bugs — small changes can trigger regressions in unrelated areas.
- Hard onboarding — new hires must understand the entire system before contributing.
- Reduced effectiveness of AI tooling — scattered context limits helpful suggestions.
For a comparison of software architecture patterns, see our guide on software architecture patterns.
What is vertical slice architecture?
Vertical slice architecture flips the mental model from horizontal, technical concerns to vertical, business-focused slices. Think of your app more like a pizza: each slice contains everything needed to support one end-to-end feature. That includes UI components, API handlers, business logic, and data access code.
This structure groups code by what it achieves for the user, not by its technical role. The result is much higher feature cohesion and a simpler developer experience.
Feature cohesion and developer experience
When all code for a feature lives together, developers find, change, and test functionality faster. A single directory can contain everything needed to understand and modify a feature, reducing context switching and mental overhead. This approach is used in production on apps such as Life Purpose App and MicroEstimates.
Group code that changes together. Organize your code around features to align engineering work with business value.
See our post on the concentric circle model for related thinking on domain-centric design.
Vertical slices vs layered architecture
| Aspect | Layered Architecture | Vertical Slice Architecture |
|---|---|---|
| Primary organization | By technical concern (UI, business logic, data) | By business feature (e.g., “Create User”, “Submit Order”) |
| Coupling | High across layers; changes ripple | Low between features; changes isolated |
| Cohesion | Low; feature code scattered | High; feature code grouped together |
| Team workflow | Hand-offs between specialists | Cross-functional, autonomous teams |
| Testability | Requires many mocks and integrations | Features tested end-to-end in isolation |
| Cognitive load | High; must understand entire layer | Low; focus on single slice |
Managing dependencies between slices
Keep slices independent and avoid direct calls between features. If functionality must be shared, use deliberate, well-defined patterns rather than creating a web of ad hoc dependencies. This isolation lets teams work in parallel with fewer merge conflicts and a lower risk of accidental breakage.
Business impact of vertical slices
Adopting vertical slices is a business decision as much as a technical one. Teams see measurable improvements in speed, quality, and maintainability when they organize around features rather than layers.
Ship faster, spend less
When each feature is self-contained, teams can build, test, and ship without coordinating across multiple horizontal layers. A study cited improvements in delivery time, bug rates, and integration failures for teams adopting vertical slices2. Organizing code this way also lowers long-term maintenance costs: it’s easier to find and fix bugs when the relevant code is co-located.
Organizing by feature ties engineering efforts directly to value delivered. Each slice is a testable and shippable unit of product.
Faster onboarding and team autonomy
Vertical slices flatten the learning curve for new hires. Give a new developer one small slice and they can contribute quickly without understanding the entire application. This model supports small, cross-functional teams that own features end-to-end, improving autonomy and predictability.
AI-friendly codebases
AI coding assistants work best with tight, relevant context. When a slice contains the UI, API, and data code for a feature, AI tools can provide much more accurate suggestions because the context window is coherent and focused. In layered systems, the scattered context often produces generic or incorrect suggestions from AI tools like GitHub Copilot3.
How to structure a vertical-slice TypeScript project
Below is a practical example using Next.js, React, and Node.js. The key idea is to keep each feature self-contained so developers don’t need to jump between many directories to follow a request’s flow.
Example feature folder
For a “Create Blog Post” feature you might have:
src/features/CreateBlogPost/index.ts— barrel exportCreateBlogPost.tsx— React component and formCreateBlogPost.api.ts— API route handlerCreateBlogPost.command.ts— business logic to create a postCreateBlogPost.types.ts— TypeScript types for the featureCreateBlogPost.repository.ts— database code for posts
This mirror of business capabilities makes it easy to find the code you need and to reason about feature changes.
Commands vs queries
Separate files by intent: commands mutate state and handle validation, while queries focus on efficient reads. This lightweight split is inspired by CQRS but keeps things pragmatic and approachable.
Handling shared code without creating new layers
Use a disciplined shared or core directory for generic, cross-cutting concerns only — things like authentication middleware, logging utilities, UI primitives, or a database client. Avoid placing business logic in shared, because that introduces hidden coupling between features. If logic is business-specific, keep it inside the relevant slice.
Testing vertical slices
Vertical slices change how you test. Instead of many brittle unit tests that rely on mocks, prefer feature-level integration tests that exercise the slice end-to-end. This gives higher confidence that the feature actually works in concert.
Test the feature, not the layers
A typical integration test flow for a CreateBlogPost slice:
- Set up a predictable database state (in-memory DB or test container).
- Make an HTTP request to the slice’s API endpoint with a valid payload.
- Assert on the response status and body.
- Verify the database record was created with correct values.
This approach reduces the number of fragile unit tests and improves coverage of real behaviour. In practice, teams have seen measurable improvements in end-to-end coverage when moving to feature testing4.
On the front end, use React Testing Library to simulate user interactions for the slice’s UI and assert the expected UX after the API call completes.
Common pitfalls and how to avoid them
Vertical slices bring clarity, but there are anti-patterns to watch for.
- The “fat” slice — one slice grows to cover many features. Fix by splitting into smaller, single-purpose slices.
- Leaky business logic — rules placed in
sharedlibrary. Fix by moving business rules back into the slice they belong to. - Inconsistent slice structure — different folder layouts across features. Fix by agreeing on project conventions for naming and structure.
Avoid premature abstraction
Prefer duplication over the wrong abstraction. Wait for a stable pattern across several features before extracting shared code. Premature abstractions often add hidden coupling and complexity.
Practical migration strategy for legacy apps
Don’t rewrite everything. Build new features as vertical slices, and refactor small, contained parts of the legacy app into slices using a strangler approach. This incremental path modernizes the codebase without halting feature delivery.
At Clean Code Guy, we help teams adopt pragmatic patterns like vertical slices to build software that lasts. Our AI-Ready Refactors and Codebase Audits provide expert guidance to modernize your application safely. Learn more at https://cleancodeguy.com.
Frequently asked questions
Q1 — How is vertical slice architecture different from microservices?
Vertical slices organize code inside a single application by feature. Microservices split an entire system into separate services. A monolith organized into vertical slices is easier to break into microservices later, since each slice maps cleanly to a candidate service.
Q2 — Is it okay to share code between slices?
Yes, for truly generic technical concerns in a disciplined shared or core folder. Keep business logic inside slices. When two slices need similar business rules, prefer duplication until a stable pattern emerges.
Q3 — Can I introduce vertical slices into a legacy app?
Yes. Start by building new features as slices and refactor small, self-contained legacy features into slices over time using a strangler pattern.
AI writes code.You make it last.
In the age of AI acceleration, clean code isn’t just good practice — it’s the difference between systems that scale and codebases that collapse under their own weight.