Self-hosted service
jasontaylordev/CleanArchitecture avatar
jasontaylordev/CleanArchitecture

jasontaylordev/CleanArchitecture: a .NET 10 solution template, not a framework

Clean Architecture Solution Template for ASP.NET Core

20,605 stars4,287 forksC#MIT

At a glance

What is it?
The Clean Architecture Solution Template scaffolds an ASP.NET Core 10 app with Angular, React or Web API only, wired to Aspire and EF Core. It is a starting point you own, and the trade-offs show up the moment you delete the sample domain.
Who is it for?
Adopt it if you are starting an ASP.NET Core 10 solution and want the layer boundaries, MediatR pipeline and test scaffolding decided before the first feature lands. Skip it if you want a framework that stays in your dependency graph, or if you are on .NET 8 or 9 and unwilling to switch to the net9.0 or net8.0 branch, because main targets .NET 10.0.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly C#, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What the Clean Architecture Solution Template actually solves

Starting a layered ASP.NET Core solution is mostly a naming exercise that nobody enjoys. You create a Domain project, an Application project, an Infrastructure project, a Web project, then argue about where the interfaces live and whether the DbContext belongs in Infrastructure. This template performs that argument once and hands you the result. It is a dotnet new template, so the output is source code in your repository, not a NuGet package you reference.

The intended audience is a team beginning an enterprise ASP.NET Core application that expects the codebase to outlive the first feature set. The README frames the goal as a straightforward and efficient approach to enterprise application development. That is the honest scope: it is scaffolding for people who have already decided on layered architecture and want the plumbing pre-decided. If you have not made that decision, the template will not make it for you.

One consequence is easy to miss. Because the template copies files rather than linking a package, there is no upgrade path. Fixes that land on main do not reach your solution. You either re-scaffold and diff, or you carry the code forward yourself.

How the generated solution is put together

The repository layout separates src/, tests/, templates/, build/ and docs/. The generated solution follows the usual dependency direction: Domain holds entities and value objects, Application holds use cases and interfaces, Infrastructure implements persistence, and the Web project hosts the API. MediatR carries requests through the Application layer, FluentValidation validates them, and AutoMapper maps between domain types and DTOs. These are the libraries the README lists under Technologies.

What is more distinctive is the host. The template generates an AppHost project, and the documented run command targets it rather than the Web project. Aspire orchestrates the application, which is why the README says the dashboard opens automatically with application URLs and logs. That changes the local development loop: you start the AppHost and read service state from the dashboard instead of attaching a debugger to a single web process.

Database choice is a template parameter, not a runtime configuration. The README lists postgresql, sqlite and sqlserver, with sqlite as the default. The prerequisites note that Docker Desktop or Podman is only required when using SQL Server or PostgreSQL, and not required for SQLite. That is a deliberate onboarding choice: the default path needs no container runtime at all.

The project also keeps Architecture Decision Records under docs/decisions/. Those records are the closest thing to a statement of intent, and they are worth reading before you start deleting things.

Installing the template and running a first solution

The template is distributed through NuGet and installed with the dotnet CLI. The README gives this as the install step, and it makes ca-sln available as a template short name afterwards.

bash
# requires the .NET 10.0 SDK or later
dotnet new install Clean.Architecture.Solution.Template

To see the options the template exposes, including anything not covered in the README table, run the help command.

bash
dotnet new ca-sln --help

Creating a solution takes two parameters. --client-framework accepts angular, react or none and defaults to angular. --database accepts postgresql, sqlite or sqlserver and defaults to sqlite. The output flag names the directory. This example produces an API-only solution on SQLite, which needs neither Node.js nor a container runtime.

bash
dotnet new ca-sln -cf none -db sqlite -o YourProjectName

If you want the full stack, the README's own example pairs an Angular client with PostgreSQL. Note that this variant does require Node.js and a container runtime.

bash
dotnet new ca-sln -cf angular -db postgresql -o YourProjectName

Run the generated solution by targeting the AppHost project. According to the README, the Aspire dashboard opens automatically and shows the application URLs and logs.

bash
dotnet run --project .\src\AppHost

The first real task is not writing a feature. It is opening the generated WeatherForecast sample, following it from the Web endpoint through the Application handler to the Infrastructure persistence code, and then deleting it. That path is the template's actual documentation of its own conventions.

Where the template gets in your way

The sample code is the first obstacle. Templates need a working example, and this one ships a weather forecast slice. It touches every layer, which makes it a good tour and a bad thing to leave in place. Removing it is manual work across several projects, and nothing in the README describes a cleanup command.

The second issue is version coupling. The main branch is on .NET 10.0, and the README lists separate branches for net9.0, net8.0, net7.0, net6.0, net5.0 and netcore3.1. A team pinned to .NET 8 gets the net8.0 branch, which will not carry the same library versions or the same Aspire wiring as main. Choosing a branch is choosing a different template, not a different tag of the same one.

The third is the absence of an upgrade mechanism, already noted but worth stating as a limitation rather than a design note. Once generated, the code is yours. There is no supported way to pull a later fix into an existing solution short of re-scaffolding and comparing.

Finally, the template is opinionated about libraries. MediatR, AutoMapper and FluentValidation are not optional extras in the generated code; they are how the Application layer is structured. A team that has standardized on a different mediator or prefers explicit mapping will spend its first week removing dependencies rather than adding features.

Ardalis/cleanarchitecture and the difference in approach

The most direct alternative in the .NET space is Ardalis/cleanarchitecture, which appears in the related searches alongside this project. The two share a name and a general layering philosophy, but they are packaged differently. This project is installed as a dotnet new template and produces a solution you own outright, with the AppHost and Aspire orchestration included and an Angular or React client as a first-class option.

Ardalis's template is also distributed as a template, but it is built around a different set of supporting libraries, notably the specification pattern and guard clause packages from the same author, and it does not center on Aspire for the local host. The practical difference for a team is which opinions you inherit. If you want the mediator-plus-mapping pipeline with a SPA client and an Aspire dashboard, this template matches. If you want specifications and a leaner dependency set, the other one does.

Neither is a framework. Both hand you source files. That shared property matters more than the differences when you are estimating the cost of adopting either.

Maintenance, licensing and the cost of staying current

The repository is not archived, and the last push was on 2026-09-19. The most recent release listed is v10.8.0 from 2026-03-23, preceded by v10.7.2 and v10.7.1 earlier that month. The gap between the last release and the last push suggests work continues on main between tagged versions.

The maintenance cost lands on you, not the maintainer. Because the template copies code, your ongoing expense is the effort of tracking upstream changes manually. Dependabot-style updates to MediatR, AutoMapper, EF Core or Aspire will not arrive through the template; you update them in your own solution. The repository does carry a Directory.Packages.props file, which indicates central package version management is used in the generated solution, so version bumps are at least centralized in one file rather than scattered across project files.

The licence is MIT, stated in the README and present as a LICENSE file at the repository root. MIT is permissive and places few conditions on redistribution or commercial use, but it also means no warranty. If your organization has rules about which licences may enter a product, MIT is normally on the approved list, though the dependencies the template pulls in have their own licences and those are not covered by this one. That is a question for your legal team, not something the README answers.

Editorial conclusion

Adopt it if you are starting an ASP.NET Core 10 solution and want the layer boundaries, MediatR pipeline and test scaffolding decided before the first feature lands. Skip it if you want a framework that stays in your dependency graph, or if you are on .NET 8 or 9 and unwilling to switch to the net9.0 or net8.0 branch, because main targets .NET 10.0. Before committing, install the template, scaffold with -cf none -db sqlite, and read the files under docs/decisions/ to see whether the recorded choices match how your team actually wants to work.

Frequently asked questions

What are the drawbacks of using jasontaylordev/CleanArchitecture?

The generated solution includes sample weather forecast code that you have to remove by hand, and there is no upgrade path because the template copies files rather than referencing a package. The main branch also targets .NET 10.0, so teams on older runtimes must use a separate branch with different library versions.

How do I install and use jasontaylordev/CleanArchitecture?

Install the .NET 10.0 SDK or later, then run dotnet new install Clean.Architecture.Solution.Template. Create a solution with dotnet new ca-sln, choosing the client with --client-framework and the database with --database, and run it with dotnet run --project .\src\AppHost.

Which databases and client frameworks does the template support?

The README lists angular, react and none for --client-framework, and postgresql, sqlite and sqlserver for --database. Angular and SQLite are the defaults, and SQLite is the only option that does not require Docker Desktop or Podman.

Does the template work on .NET 8 or .NET 9?

Not on the main branch, which the README states is on .NET 10.0. Separate branches exist for net9.0, net8.0, net7.0, net6.0, net5.0 and netcore3.1, and those are separate snapshots rather than tags of the current template.

What licence does jasontaylordev/CleanArchitecture use?

The README states the project is licensed under the MIT License, and a LICENSE file sits at the repository root. The licence covers the template itself, not the third-party libraries the generated solution depends on.

Official sources

  1. jasontaylordev/CleanArchitecture on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/jasontaylordev-cleanarchitecture.svg)](https://hysenlabs.com/projects/jasontaylordev-cleanarchitecture)