Why Vertical Slices Won't Evolve from Clean Architecture

Feature-Orientation Isn’t Just Cosmetic

Why Vertical Slices Won't Evolve from Clean Architecture
Image Credit: SIphotography

Yesterday, a comment on LinkedIn drove me to despair again.

"Side note: The natural evolution of Clean Architecture leads to Vertical Slices when you do fewer projects and more folders. Which speeds up development greatly" - Anton Martyniuk on LinkedIn

If you’re a .NET developer or architect feeling the LinkedIn-fueled confusion, read on, and let me explain why Vertical Slice Architecture don’t just spring from Clean/Onion/Hexagonal Architecture. They challenge its core assumptions.

First, architecture is not a religion. It’s a choice. As professionals, we should constantly question why we structure our projects a certain way. The myth that Clean Architecture somehow becomes Vertical Slice Architecture by merging projects reflects blind copying rather than genuine understanding.

In my opinion, many people promoting 'vertical slice architecture' have simply spotted a new angle for videos and articles. That’s the first problem. Just because someone reads that vertical features might be the next big thing, they rush to pump out tutorials on how to build a vertical slice folder structure from the previously advertised clean/onion/hexagonal approach, complete with all the useless layers. The brutal truth is that it’s still over-engineered junk, just rearranged. This is obviously a ploy to generate clicks with fresh content.

Anyone who has worked on a real project for a real client, not just tinkered with theory on a home PC, knows you can’t just reshuffle your entire structure every time a new buzzword appears.

Understanding the Idea of Vertical Slice Architecture

Second, I highly recommend studying Jimmy Bogard’s 2018 article on Vertical Slice Architecture. He argues that traditional layered approaches are monolithic at their core. As he puts it:

"The problem is this approach/architecture is really only appropriate in a minority of the typical requests in a system. Additionally, I tend to see these architectures mock-heavy, with rigid rules around dependency management. In practice, I've found these rules rarely useful, and you start to get many abstractions around concepts that really shouldn't be abstracted (Controller MUST talk to a Service that MUST use a Repository)." - Jimmy Bogard

As I've said countless times, Clean/Onion/Hexagonal architectures have two major problems:

  1. Code is scattered across technical layers. In real projects, I've seen it a thousand times: layers stuffed with a single line of code or loads of boilerplate. You end up jumping between folders to understand what a feature actually does. And for a simple API call that queries a database, all those extra layers are just over-engineered nonsense.
  2. Dependency Inversion (DIP) creates functional dependencies. People claim it helps testing, but in reality you’re forced to mock everything and introduce pointless complexity. If you really want to test your logic, just keep it pure: data in, compute, data out. No side effects. No messing around. I go into more detail here: https://ricofritzsche.me/applying-functional-core-and-imperative-shell-in-practice/
"Instead, I want to take a tailored approach to my system, where I treat each request as a distinct use case in how to approach its code." - Jimmy Bogard

In other words, if you want a more flexible approach that only does what you actually need for each feature, Vertical Slicing is the right choice. This flies in the face of all the book-selling layered architectures that want one-size-fits-all conformity. The core of Vertical Slicing is to break out of that rigid, encrusted mindset, as Jimmy shows in his example:

Source: https://www.jimmybogard.com/vertical-slice-architecture/

With Vertical Slicing, each request can decide how it wants to handle its logic, which means you no longer need these shared layers like repositories, services, and controllers everywhere. You also don’t have to litter slices with MediatR. Its purpose is to implement the mediator pattern, routing all requests through a central handler. That can be useful if you genuinely need to enforce strict separation between inputs and processing, maybe because you’ve got logging, retries, or transactional behavior that must wrap around every request.

But let’s be real: most use cases don’t need this ceremony. If you're just handling a basic read or write operation, use a transaction script, or a plain SQL query. It’s faster, easier to debug, and doesn’t hide logic behind layers of abstraction.

When MediatR recently switched to a paid license, the community went into full panic mode running around like headless chickens. That alone shows how blindly it was adopted. Tools like this should only be used if they solve a real problem. They should not be used just because they’re trendy, appear in a YouTube tutorial or are recommended in a daily LinkedIn tip.

If the added complexity brings no clear benefit, don’t use it.

The Allure of “Evolving” Clean Architecture into Vertical Slices

Why do so many folks think that trimming the number of projects in a Clean Architecture solution and shuffling folders around suddenly means they’ve adopted Vertical Slices? So-called gurus on LinkedIn or in community chats love to post something like this:

“We refactored our app from the classic Clean Architecture (with separate Domain, Application, and Infrastructure projects) into a single-project structure. Now we group code by feature. Vertical Slices for the win!”

It’s easy to see how this idea took hold. Clean Architecture, popularized by Uncle Bob and passionately embraced in the .NET world, usually involves multiple projects or layers (Web, Application, Domain, Infrastructure). That can feel slow and cumbersome. So developers cut the clutter by removing extra projects and indirections. On the surface, it looks simpler. They might even label folders by feature. Suddenly, people start calling it “Vertical Slice Architecture,” convinced they’ve just evolved Clean Architecture by stripping it down.

Yet these annoying Clean/Onion Architecture templates reappear like cancerous tumors, popping up like metastases. It highlights the helplessness of a generation stuck in pattern propaganda, swamped by tutorials, libraries, and frameworks. Very few want to dig deeper and truly understand what they’re doing, let alone grapple with the domain itself to build real business value. Instead, they hide behind layers of complexity, abstractions and indirections nobody actually needs. For me, code organized purely around technical layers always signals a domain that isn’t understood. And Clean Architecture can never be domain-driven anyway.

Where Did the Confusion Come From?

Why does so much of the .NET community mix up these two approaches? .NET developers have leaned heavily on Clean/Onion Architecture. It was drilled into our heads that a “proper” enterprise app has strict layers, clear separations and dependency inversion. Over time, as projects ballooned, this layered approach started feeling painful with tons of indirection, endless tiny projects or folders. Then came Vertical Slice Architecture, claiming to soothe these pains by focusing on features. Many devs only knew the layered mindset, so they took Vertical Slices and treated them like a new structure only for Clean Architecture. They flattened the structure but never fully embraced a feature-first mentality.

The problem isn’t helped by some high-profile voices mixing terms. LinkedIn and blogs are full of posts on “Combining Clean Architecture with Vertical Slices” or “domain- centric design and separation of core business logic within each vertical slice.” People read that and assume “Oh, Vertical Slices is just a simpler Clean Architecture.” They miss the nuance that a truly vertical-sliced app packages code differently at its core.

Then there’s the jargon soup. “Feature Folders,” “Vertical Slices,” “Modular Monoliths,” and so on exploded around the same time in the .NET scene. Some folks lumped them all together. ASP.NET Core’s feature folders might group controllers and views by feature, but that doesn’t mean your backend is sliced. And using MediatR for requests doesn’t magically make your code feature-oriented either if everything else is layered. Tools and templates all came out around the same time, leaving a blur of “best practices” with no clear boundaries.

It also doesn’t help that Clean Architecture had loads of examples, like the Jason Taylor template. Into that gap poured a bunch of half-baked experiments. People refactored their apps and blogged “We switched to vertical slices,” but often kept some Clean Architecture remnants. Readers saw a hybrid and assumed it’s a natural evolution path.

Finally, if you have a massive Clean Architecture project and you’re sick of wading through layers to add features, grouping code by feature is an intuitive next step. Teams do this gradually: they start grouping commands and queries for Orders or Customers, and maybe put validators and mappers there too. Eventually they merge projects. At some point, the structure looks pretty feature-centric, so it’s tempting to say “We evolved into vertical slices.” But usually, some leftover shared repository or service layer remains. People see this half-and-half and think Vertical Slices Architecture is just Clean Architecture 2.0, rather than an entirely different way of structuring and thinking about the code.

In the end, it’s no wonder the .NET LinkedIn crowd lumps them together. But remember: vertical slicing isn’t simply Clean Architecture upgraded. It’s a different mindset, emphasizing feature independence over strict layer decoupling. Both aim to manage complexity, but they tackle it in nearly opposite ways: one organizes by layer, the other by feature.

Productivity and Clarity: The Real Benefits of Vertical Slices

So, why do so many developers find the Vertical Slice Architecture appealing in the first place? If applied correctly, there are clear advantages to this approach over simply flattening your project structure.

Firstly, you benefit from laser-focused development. When you implement a feature as a vertical slice, all related elements are kept together in one place. There's no need to click around between multiple projects or folders to follow the logic. Developers who have tried this often say that it makes their solutions far easier to navigate, debug and maintain because the entire feature is neatly packaged. This means more time is spent on real, meaningful coding.

Secondly, real vertical slices mean fewer merge conflicts and safer changes. Since each feature is isolated, developers working on different slices rarely edit the same files. Adding new functionality typically involves creating new files rather than amending existing ones. This reduces the risk of accidental breakages and promotes stability by adopting an append-only coding style that leaves existing, tested logic untouched.

Another clear advantage is high cohesion. Each vertical slice forms a logical, independent unit that is straightforward to understand. Rather than trying to understand the entire application's layering scheme, you focus on one straightforward section at a time. This dramatically reduces cognitive load, particularly for newcomers, who can focus on learning one feature area rather than grappling with an entire intricate architecture.

Vertical slices also make the codebase and the team more scalable. Adding new features is straightforward: just add another slice. Even if your application as a whole grows significantly, each slice will remain manageable. Teams naturally divide into feature-based areas, which aligns perfectly with agile delivery methods. Each slice can evolve independently, adopting different technologies or storage solutions where appropriate. Such freedom is almost unheard of in traditional layered architectures.

Lastly, there is strong alignment with agile practices and the domain itself. Vertical slices naturally correspond to user stories or specific use cases, ensuring that your architecture directly reflects the delivery of business value. Seeing a complete feature come to life in one place can be highly motivating for teams. When scaled up, this approach blends well with the concept of Bounded Contexts in Domain-Driven Design (DDD) each slice or group of slices represents a clearly defined domain capability rather than abstract technical layers.

You may find that the same logic is used in different places. For example, two features might perform similar validation separately. Clean Architecture proponents prefer centralized logic and adhere strictly to the DRY principle, whereas vertical slices sometimes intentionally tolerate duplication in order to maintain independence. However, after spending over 30 years coding, modelling and designing real-world systems, I have become deeply skeptical of DRY. It is often the root of all evil. The real key is pragmatism: extract genuinely shared logic, but never force abstractions prematurely. Protecting slice autonomy is far more important than blindly chasing DRY.

Despite of a few potential pitfalls, vertical slicing brings tremendous clarity and maintainability, especially in large, evolving code bases. Teams that fully embrace this approach consistently report faster development cycles and fewer pointless debates over 'Where should this code go?' Vertical slicing reduces cognitive load, streamlines feature development and finally gives every piece of code a logical and sensible home.

Cheers!