Part of: Dashboard Starter

Why I'm Building Another Dashboard Starter (In Public)

I'm building an open-source dashboard starter for React, ASP.NET Core, and SQL Server, and I'm writing about every step as I go.

It's called dashboard-starter. The goal is simple: a working, production-shaped dashboard app that anyone can clone, rename, and start building their real product on. No more spending the first three weeks of a project rebuilding sign-in, a sidebar, a data grid, and a deploy pipeline.

I've been writing software for over 15 years, much of it in fintech and SaaS. I've set up this same foundation more times than I can count. This time I'm doing it once, in the open, and explaining my reasoning so you can take what's useful and argue with the rest.

Why another starter?

Most starter templates stop right where the hard part begins.

They tend to fall into two camps. The first is a beautiful admin UI with fake data and no real backend. It looks great in a screenshot, but the moment you need authentication that actually protects an API, or a table that pages through a million rows on the server, you're on your own. The second is a backend sample that shows off an architecture pattern but has no usable front end at all.

What's missing is the boring middle: how a real app fits together end to end. How a permission defined in the database shows up as a hidden button in React. How a migration gets from a developer's laptop to production. How errors get logged instead of swallowed.

And almost none of them tell you why. You get a folder structure and a pile of dependencies, but not the reasoning behind them. That makes it hard to know which decisions are load-bearing and which ones you can safely change.

Who it's for and the ground rules

This is for developers and small teams building internal tools, back-office systems, or B2B SaaS products on the Microsoft stack. If your app is mostly forms, tables, and dashboards behind a login, this should save you weeks.

Three principles will guide every decision:

  • Usable. It has to be something you can actually ship on, not a demo. Real auth, real database, real tests.
  • Opinionated. One clear way to do each thing. Starters that try to support every option end up supporting none of them well. If you disagree with a choice, the codebase should be simple enough that swapping it out is obvious.
  • Explained. Every significant decision gets written up in this series. You should never have to guess why something is the way it is.

The stack, and why

The stack is the one I've shipped production systems on for years: React in the browser, ASP.NET Core in the middle, SQL Server underneath. It isn't the trendiest combination, and that's partly the point. It's stable, well documented, easy to hire for, and a huge number of real businesses run on it.

BROWSER React + TypeScript built with Vite calls the API reflects permissions in the UI API ASP.NET Core Web API C# · current .NET LTS checks permissions users · roles · permissions DATABASE SQL Server EF Core · migrations checked in Docker Compose for local dev CI · ON EVERY PUSH GitHub Actions build · test · lint, right next to the code

Every feature follows the same path: React calls the API, the API checks permissions and talks to SQL Server through EF Core, and CI checks it all on every push.

LayerChoiceWhy
Front endReact + TypeScript, built with ViteThe largest ecosystem for dashboard UI. TypeScript catches the bugs that matter before they ship. Vite keeps local builds fast.
APIASP.NET Core Web API (C#, current .NET LTS)Fast, mature, and strongly typed end to end. LTS releases mean you aren't forced into an upgrade every year.
DatabaseSQL ServerRock solid for relational business data, runs anywhere including Docker and Azure, and the free Developer edition covers local work.
Data accessEF Core, migrations checked inSchema changes live in source control and get reviewed like any other code.
AuthUsers, roles, and permissions in the appMost business apps need fine-grained permissions, not just "logged in or not". This will be built in from day one.
Local devDocker ComposeOne command to start the database. No installing SQL Server on your laptop.
CIGitHub ActionsBuild, test, and lint on every push, right next to the code.

I'll go deeper on each of these in their own posts, including the alternatives I considered and why I passed on them.

The plan for version 1

Version 1 covers the 80% that nearly every dashboard app needs on day one, and nothing more.

Foundation

  • One repo holding the front end, the API, and the database project
  • Local dev with Docker Compose and seeded sample data
  • Error handling, structured logging, and health checks

The app itself

  • An app shell: sidebar navigation, top bar, responsive layout, light and dark themes
  • Sign in, sign out, and password reset
  • Users, roles, and permissions, enforced on both the API and the UI
  • A reusable data grid with server-side paging, sorting, and filtering
  • One complete CRUD module that shows the end-to-end pattern for adding features
  • Forms with validation rules shared between client and server
  • Settings and user profile pages
  • An audit log of who changed what
  • A dashboard home page with sample KPI cards and charts

Shipping it

  • Automated tests for the API and the UI
  • A CI pipeline and a documented path to deployment

What's out of scope (for now)

Multi-tenancy, billing, a plugin system, and a mobile app are all real needs, but they'd double the size of the project before it's useful to anyone. They're candidates for later, once the core is solid.

How the series will work

Each post maps to a milestone in the repo. When a post goes up, the code for it will be merged and tagged, so you can check out exactly what the post describes.

Every post will cover three things: what I built, the tradeoffs I weighed, and anything I'd do differently in hindsight. I'll include the mistakes. A build log that only shows the clean final version isn't very useful.

Here's the rough order:

  1. Why another dashboard starter? (this post)
  2. Repo structure and local dev setup: the solution layout, Docker Compose, and seeded data
  3. The app shell: layout, navigation, and theming
  4. Authentication: sign in, sign out, and password reset
  5. Roles and permissions: one permission model, enforced in the API and reflected in the UI
  6. The data grid: server-side paging, sorting, and filtering
  7. A full CRUD module: the pattern you'll copy for every new feature
  8. Forms and validation: one set of rules on both sides
  9. Audit logging: recording who changed what
  10. The dashboard home: KPI cards and charts
  11. Testing and CI: keeping it green
  12. Deployment: getting it in front of real users

The order may shift as I go. If something turns out to depend on something else, I'll reorder and say why.

Follow along

The repo is live at github.com/mvmorten/dashboard-starter. Right now it holds a README and an MIT license, which means you can use anything that ends up in it, including in commercial work.

If you want to follow the build, star or watch the repo. If you think one of my choices is wrong, open an issue and tell me why. Since the project is opinionated, I won't merge everything, but I'll read all of it, and the good arguments will show up in future posts.

Next up: setting up the repo structure and getting the whole stack running locally with a single command.