Introducing Slicekit: ship the product, not the plumbing
Why we built a premium, opinionated full-stack SaaS boilerplate around .NET 10 and React, and an honest account of what a template can and cannot do for you.
Every SaaS begins the same way. Before a single feature ships, someone spends a fortnight wiring up authentication, a database, a typed client between the API and the UI, background jobs, logging, and a CI pipeline. None of it is the product. All of it has to exist before the product can. It is necessary, it is very nearly identical on every project, and it is almost never the work anyone set out to do.
That is the plumbing tax. The first weeks of a new product go to rebuilding infrastructure that a thousand teams have already built, instead of the one thing that makes this product yours. The tax is real, it is measured in weeks, and it gets paid at exactly the moment you have the least patience for it. Slicekit exists to remove most of it. This post is the honest version of that promise: what a template can take off your plate, and what it stubbornly cannot.
The three ways teams handle it
When you hit the plumbing wall there are really three roads, and each one asks you to give something up.
Roll your own from scratch. You get exactly the system you want and you understand every line of it. You also spend two or three weeks on undifferentiated wiring before the product starts, and you make a hundred small architectural decisions while you are least equipped to make them well. Worse, you make them inconsistently: the auth module ends up shaped nothing like the billing module, because you learned things in between. The cost is not just the weeks. It is the drift.
Reach for a thin Node starter. You are productive in an afternoon, and that feels great. Then the product grows, and the serious parts a starter leaves out (a real permission model, an audit trail, reliable background messaging, observability that survives production) become your problem one urgent gap at a time. You end up rebuilding the hard parts anyway, only now under deadline and bolted onto code that never expected them.
Adopt a sprawling generated boilerplate. Everything is in the box. The trouble is that everything is in the box: layers of abstraction you did not ask for, configuration you did not write, and a structure you have to reverse engineer before you can safely change anything. You inherit a large codebase you do not understand, which means you cannot confidently delete from it either. Generated volume is not the same as a foundation you own.
The honest tradeoff running through all three is time saved now against control kept later. Each option optimises hard for one and quietly taxes the other.
The one bet
Slicekit is the opinionated middle: the fortnight already spent, with the control kept. It is a premium, production-grade base pairing a .NET 10 API with a React single-page app, built around one consistent, event-driven architecture so the two halves feel like a single system. Buy it once and the whole repository is yours: clone it, keep what saves you weeks, delete the rest.
What keeps it opinionated rather than sprawling is that it rests on a single bet, the vertical slice. Almost everything else follows from that one idea.
React SPA
TanStack · typed client
.NET 10 API
vertical slices · CQRS
PostgreSQL
EF Core
RabbitMQ
outbox · events
Grafana
traces · logs · metrics
A feature is one slice through the whole system. On the API: a request, a handler, a domain change, an endpoint. On the frontend: a route, a query, a component. Each slice lives in its own folder instead of being smeared across a controllers layer, a services layer, and a repositories layer. Learn one slice and you have learned them all, on either side of the wire.
That is not an aesthetic preference. It is a bet that pays off in three concrete ways.
Changes stay local. A feature lives in one place, so adding behaviour means touching one folder, not threading an edit through five horizontal layers and hoping you found them all. The blast radius of a change is the slice, and you can hold the whole slice in your head at once.
Deletion is clean. Requirements change and features die. When a feature is a folder, removing it is a deletion, not an archaeology project hunting for the orphaned service method, the dead route, and the column nobody uses. There is even a documented recipe for tearing a slice out across both sides.
Onboarding is fast. There is one shape to learn, and the second slice looks like the first. A new
teammate, or you six months from now, reads one feature and has the mental model for the whole
codebase. The structure teaches itself, which is also why a coding agent can navigate it: the repo
ships AGENTS.md routers and per-side conventions so automated contributors start with context
instead of guessing.
The slice is the organising idea; the rest is the foundation every SaaS ends up needing, assembled and tested so your first commit is a feature. A .NET 10 API using domain-driven design and Wolverine for CQRS and messaging, with a transactional outbox so integration events are safe to publish. A Vite and React SPA with TanStack Router and Query, shadcn/ui and Tailwind, talking to the API through one typed client that handles cookies and CSRF for you. Authentication with cookie sessions, a typed permission catalogue mirrored to the UI, OAuth, two-factor auth, admin impersonation, and an audit trail. PostgreSQL with EF Core migrations, S3-compatible file storage, GDPR export and erasure. OpenTelemetry traces, metrics, and logs flowing to Tempo, Prometheus, Loki, and Grafana. Docker Compose for local infrastructure and CI that builds and tests both sides on every pull request.
Slicekit.Api
the host: endpoints, middleware, composition root
Slicekit.Core no dependency on the web host
Features/
vertical slices: command, handler, validator, result
Domain/
aggregates that raise events, primitives
Persistence/
AppDbContext, EF configurations, migrations
Messaging
Wolverine CQRS, transactional outbox
Four test projects guard it
Unit.Tests
logic in isolation
Architecture.Tests
boundaries hold
Feature.Tests
real Postgres
Api.Tests
HTTP end to end
The discipline that holds it together is in the boundaries. The API host depends on the core and never the reverse, so the same commands could be driven by a worker or a CLI, and four test projects keep those boundaries from quietly eroding. This is a mainstream stack you fully own, with no lock-in and nothing hidden behind a hosted service. When you outgrow an opinion you can change it, because you can find it.
What a template will not do for you
Here is the part the brochures skip. A template removes the undifferentiated plumbing and the bikeshedding. It does not, and cannot, do the actual product work.
It will not hand you product-market fit. It will not write your domain model, because your domain is the one thing no template can know in advance: the aggregates, the invariants, the workflows that make your business your business are yours to design. It will not supply judgment, the steady stream of small calls about what to build, what to cut, and when an opinion has stopped serving you. And it will not stop you from making a mess inside a slice if you are determined to.
What it removes is narrower and more honest than “build your SaaS for you.” It removes the weeks you would otherwise lose to auth, a typed client, messaging, storage, and CI. It removes the early architectural decisions you would make badly under time pressure and the inconsistency that creeps in when you make them one tired evening at a time. It gives you a defensible default and a structure that keeps you consistent. The product still has to come from you. The template just makes sure you spend your first weeks on the product and not the plumbing.
Where to start
Head to the getting-started guide to clone the repo and bring the stack up locally. From there, read the architecture overview to see how a request flows from the browser to the database and back.
If you want to go deeper on a specific pillar, a few follow-up posts dig in: passkeys, sessions and refresh-token theft detection covers the authentication story, why .NET and a modular monolith for a base you keep makes the case for the runtime and the architecture shape, why we do not ship MediatR explains the messaging stack and the licensing reasoning behind it, and why an AI can navigate this codebase covers the structure that makes the template legible to humans and assistants alike.