ASP.NET Core 10 · React 19 · PostgreSQL

Ship your .NET
SaaS in 15 min

The production-ready SaaS boilerplate for .NET developers. Auth, Stripe, multi-tenancy, emails, CSRF, CI/CD — all wired up. You add your domain logic. Nothing else.

One-time purchase · Source code · No subscription

// Add your entities in 3 steps

public class Player : BaseEntity, IMustHaveTenant
{
    public Guid OrganizationId { get; set; }
    public string Name { get; set; } = "";
}

// 1 line in AppDbContext
modelBuilder.Entity<Player>()
    .HasQueryFilter(p =>
        _tenant.Id.HasValue &&
        p.OrganizationId == _tenant.Id.Value);

// Done. Isolated per tenant. Forever.
built with .NET 10 EF Core 10 React 19 PostgreSQL 16 Stripe Testcontainers Railway

The problem

Every .NET SaaS starts with
7 weeks of boilerplate.

01
Auth & refresh tokens
JWT, HttpOnly cookies, SameSite config, refresh token rotation, replay detection, logout revocation. Every edge case.
~2 weeks DIY
02
Multi-tenancy
Shared DB, Global Query Filters, OrganizationId auto-assignment, middleware resolution. Miss one guard, you leak data.
~3 weeks DIY
03
Stripe + webhooks
Checkout sessions, webhook signature verification, subscription sync, cancel-at-period-end, Billing Portal. Painful to get right.
~1 week DIY
04
Security hardening
CSRF protection, rate limiting, BCrypt timing attacks, SHA-256 token hashing, startup validation, CSP headers.
~1 week DIY

What's included

Everything. Already working.

Not a skeleton. Not a tutorial. A codebase you can fork, rename, and ship — with your business logic on top.

Complete auth system
Register, login, logout, forgot/reset password. 7-day sliding refresh tokens with rotation and replay detection via PostgreSQL xmin. HMAC-SHA256 JWTs with issuer + audience validation.
BCryptJWTHttpOnly cookiesSHA-256 tokens
Row-level multi-tenancy
Shared database, automatic isolation via EF Core Global Query Filters. OrganizationId auto-assigned on SaveChanges. One line to add a tenant-scoped entity. You cannot accidentally leak data.
IMustHaveTenantGlobal Query FiltersEF Core
Stripe billing, fully wired
Checkout sessions, webhook handling (created/updated/deleted), cancel-at-period-end detection, Billing Portal for self-service. Subscription + plan update in a single atomic transaction.
Stripe.netWebhooksBilling Portal
Clean Architecture, 4 layers
Domain / Application / Infrastructure / Api. No MediatR (commercial license concerns). Direct service injection. Code any .NET developer recognises on day one — zero learning curve for your team.
Clean ArchitectureIOptions<T>FluentValidation
React 19 dashboard
TypeScript strict, Tailwind v4, shadcn/ui, Sonner toasts. Login, register, forgot/reset password. Dashboard with members, billing, and settings — including delete org with session revocation.
React 19Viteshadcn/uiTailwind v4
CI/CD + Docker, production-ready
GitHub Actions with independent pipelines for API and web. Smoke test hits /health after each API deploy. Multi-stage Dockerfile with non-root user. Auto-migrations on startup with 5-retry loop.
GitHub ActionsRailwayDocker

Time saved, feature by feature

Feature DIY estimate DotForge
Auth + refresh tokens~2 weeks
Multi-tenancy + isolation~3 weeks
Stripe + webhooks~1 week
CSRF + security hardening~1 week
Emails (Resend)~2 days
Integration tests~1 week
CI/CD + Docker~3 days
Frontend dashboard~1 week

The stack

Enterprise-grade .NET.
Modern React. No compromise.

Backend
ASP.NET Core 10Web API, middleware pipeline
EF Core 10Code First, Global Query Filters
PostgreSQL 16xmin concurrency for tokens
BCrypt.NetPassword hashing, timing-safe
FluentValidationEvery DTO, field-level errors
Stripe.netPayments, webhooks, portal
ResendTransactional emails, HTML templates
Frontend
React 19 + ViteTypeScript strict mode
Tailwind CSS v4CSS-first config, no config.js
shadcn/uiComponents you own the code of
React Router v7Protected routes, 404 handling
Axios interceptorsAuto-refresh, CSRF injection
SonnerToast notifications
Infrastructure
GitHub ActionsIndependent API + web pipelines
RailwayAPI, web, PostgreSQL managed
DockerMulti-stage, non-root user
TestcontainersReal PostgreSQL in CI, not mocks
xUnit + FluentAssertions46 integration test cases

Security

Not an afterthought.
Baked in.

Every security decision is documented with the reasoning behind it. You understand what's protecting your users and why.

🔐
BCrypt for passwords
Intentionally slow. Dynamic dummy hash prevents timing attacks on login — even if the email doesn't exist in the database.
🔑
SHA-256 for tokens
Deterministic, searchable by WHERE clause. SHA-256 on already-random 32-byte tokens — BCrypt on tokens enables DoS attacks.
🛡️
CSRF double-submit pattern
Token stored in memory only — never localStorage. Global middleware, exemptions explicit via [CsrfExempt]. Stripe webhooks and refresh exempt by design.
🔄
Refresh token rotation
PostgreSQL xmin detects concurrent replay. Cookie + DB expiry aligned to the day. All sessions revoked on org deletion or password change.
🏢
Tenant isolation at DB layer
Global Query Filters on every tenant-scoped entity. HasValue guard on every filter. Auto-assignment in SaveChanges — you cannot forget the OrganizationId.
Startup validation
IOptions<T> with ValidateOnStart on all services. App refuses to start with missing or invalid config. A missing JWT secret fails loudly — not in prod at 3am.
📧
Email enumeration blocked
Forgot password always returns HTTP 200. Password reset rate-limited to 3/hour/email — silent after that. No way to enumerate which emails exist.
Rate limiting
5 req/min on auth endpoints, 200 req/min global per IP. Configurable, applied at middleware level — no per-controller attribute noise.

Test coverage

Integration tests on real
PostgreSQL. Not mocks.

Testcontainers spins up an actual database in Docker. Global Query Filters, migrations, and concurrency tokens are tested against the real engine — not a memory stub that hides bugs.

11
Auth tests
Register, login, refresh rotation, replay prevention, revoke on logout
6
Multi-tenant tests
Isolation, auto-assignment, IgnoreQueryFilters, no-context throws InvalidOperationException
8
Member tests
Add by email, duplicate rejection, remove, self-remove guard
7
Password reset tests
Full flow, replay, enumeration protection, rate limit, token invalidation
6
Stripe webhook tests
Created, updated, cancel-at-period-end, deleted, unknown org, invalid ID
8
Org + user tests
Profile, update, slug conflict, change password, duplicate email guard

Pricing

One price. Yours forever.

No subscription. No seat licenses. Ship unlimited products with a single purchase.

Starter
€149 one-time

Everything you need to launch your first .NET SaaS.

  • Complete source code
  • Auth, Stripe, multi-tenancy, emails
  • React 19 dashboard
  • 46 integration tests
  • CI/CD + Docker + Railway config
  • Buyer documentation (60+ pages)
Get started →

Single-developer license

What the license means
Use DotForge to build unlimited commercial products. You may not resell or redistribute DotForge itself as a template or starter kit. The source code you receive is yours to modify freely.

FAQ

Questions we actually get

Is this production-ready or just a tutorial codebase? +
It's production-ready. Multi-tenancy is enforced at the DB layer via EF Core Global Query Filters. BCrypt, SHA-256 tokens, CSRF middleware, JWT issuer/audience validation, Stripe webhook signature verification, rate limiting, typed options with startup validation, and auto-migrations are all configured. It runs on Railway and has been validated against real PostgreSQL in CI.
Why .NET and not Node/Supabase? +
Because you're a .NET developer. There are 70+ Next.js boilerplates. There are very few production-ready ones for .NET. DotForge gives you the enterprise-grade stack you already know — Clean Architecture, EF Core, BCrypt — paired with React 19. No context switch, no learning curve, no debt.
Do I need a Stripe account before I can run it? +
Yes, but Stripe test mode works immediately — no real payments until you go live. The app will refuse to start if Stripe keys are missing or invalid (ValidateOnStart). With accounts already set up, you can be running locally in 30 minutes.
Can I swap PostgreSQL for SQL Server? +
Yes. Change the EF Core provider in DependencyInjection.cs and regenerate migrations. The only PostgreSQL-specific feature is the xmin concurrency token on refresh tokens — the docs explain how to replace it with [Timestamp] for SQL Server.
Can I add Google/GitHub OAuth? +
Yes. ASP.NET Core's authentication middleware supports any OAuth provider. Add the NuGet package and register it in Program.cs. The User entity already has OAuthProvider and OAuthProviderId fields. Detailed guidance is in the buyer documentation.
What does the single-developer license mean? +
One developer, unlimited commercial products. You can build and sell as many SaaS products as you want using DotForge as the base. You cannot resell DotForge itself as a template or boilerplate to other developers.

Stop rebuilding
the plumbing.

Every .NET developer who wants to build a SaaS has rebuilt the same auth, Stripe, and multi-tenancy code from scratch. You don't have to. Buy once, ship forever.

Get DotForge — from €149

One-time · Source code · No subscription