Setup guide

Every scaffold is a folder you copy once and then own. Get the workbench, pick your scaffold below, and you're building in minutes.

First

Get the workbench

Three ways, best first:

  1. Use this template on GitHub — creates your own repo with the full structure; delete the scaffolds you don't need.
  2. Clone it:
git clone https://github.com/malinfossum/workbench.git
  1. Download ZIP from the GitHub page (Code → Download ZIP) if you just want one scaffold folder.

Scaffold · Web

web-vite

Vanilla-JS MVC starter with Vite and Biome. The MVC pattern is pre-wired — a subscribe/notify model, a view that forwards data-action events, and a live controller — and the design system is bundled, ready to use.

  1. Copy scaffolds/web-vite/ to wherever the project lives.
  2. npm install
  3. Set <title> and <meta name="description"> in index.html.
  4. npm run dev — the shell opens dark with design-system styles applied.
  5. Build in src/model, src/view, src/controller; project styles go in src/styles/main.css (mobile-first).
design-system/ is read-only inside your project and excluded from Biome — refresh it with the extract tool, never by hand-editing.
View web-vite on GitHub →

Scaffold · C#

csharp-console

Not a copy-scaffold — an overlay. Create a console project the normal way, then run init.sh to inject editor configs (F5 debug, build task, launch profile) with the right project name auto-detected.

dotnet new console -n MyProject -o my-project
cd my-project
bash ~/Documents/Development/workbench/scaffolds/csharp-console/init.sh

No bash? Copy .vscode/ and Properties/ in manually and find/replace TemplateProject with your project name.

View csharp-console on GitHub →

Scaffold · C#

csharp-layered

A solution with a class library (App.Core — no IO), a console front-end, and an NUnit test project that references Core only. The same layering later scales to an API with one dotnet new webapi.

  1. Copy scaffolds/csharp-layered/ to wherever the project lives.
  2. Rename App.slnx and each App.* project + folder to <YourName>.* (find/replace App. across files).
  3. dotnet restore && dotnet build && dotnet test
  4. Open the solution in Rider and start writing domain types in Core/Models/.
View csharp-layered on GitHub →

Scaffold · C# · Web API

csharp-api

An ASP.NET Core Web API in the layered API + repository shape: controllers → service (App.Core, no IO) → repository → EF Core + SQLite. xUnit tests cover the service with a hand-rolled fake and the full HTTP pipeline via WebApplicationFactory.

  1. Copy scaffolds/csharp-api/ to wherever the project lives.
  2. Rename App.slnx and each App.* project + folder to <YourName>.* (find/replace App. across files). Also rename App.Api.http.
  3. dotnet tool restore && dotnet restore && dotnet build && dotnet test
  4. Create the database: dotnet ef migrations add Init --project <YourName>.Data --startup-project <YourName>.Api, then dotnet ef database update with the same flags.
  5. dotnet run --project <YourName>.Api and send the requests in <YourName>.Api.http.
View csharp-api on GitHub →

Scaffold · C# · Desktop

csharp-wpf

WPF/MVVM starter proven in Tidsro: CommunityToolkit.Mvvm, Services as the only I/O boundary, xUnit, and tokens.xaml mirroring the design-system palette and scales — dark-first with keyboard-only focus visuals.

  1. Copy scaffolds/csharp-wpf/ to wherever the project lives.
  2. Find/replace MyApp<YourName> across files and folder names (check x:Class and RootNamespace).
  3. dotnet restore && dotnet build && dotnet test
  4. dotnet run --project <YourName> — the window opens dark; the button proves the binding chain.
  5. Replace Status/ConfirmWiring in MainViewModel with real state and behavior.
Keep the Application class named App, but never name the project literally App — a WPF project by that name fails to compile.
View csharp-wpf on GitHub →

Library

Design system in your project

The canonical design system lives in libraries/design-system/ and is copied into projects with the extract tool — web and C# wwwroot alike:

node tools/extract.mjs design-system ../my-app          # → ../my-app/design-system
node tools/extract.mjs design-system ../my-api/wwwroot  # into a C# wwwroot
node tools/extract.mjs design-system ../my-app --check  # is my copy stale?
Browse every component in the gallery →