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:
- Use this template on GitHub — creates your own repo with the full structure; delete the scaffolds you don't need.
- Clone it:
git clone https://github.com/malinfossum/workbench.git
- 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.
- Copy
scaffolds/web-vite/to wherever the project lives. npm install- Set
<title>and<meta name="description">inindex.html. npm run dev— the shell opens dark with design-system styles applied.- Build in
src/model,src/view,src/controller; project styles go insrc/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.
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.
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.
- Copy
scaffolds/csharp-layered/to wherever the project lives. - Rename
App.slnxand eachApp.*project + folder to<YourName>.*(find/replaceApp.across files). dotnet restore && dotnet build && dotnet test- Open the solution in Rider and start writing domain types in
Core/Models/.
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.
- Copy
scaffolds/csharp-api/to wherever the project lives. - Rename
App.slnxand eachApp.*project + folder to<YourName>.*(find/replaceApp.across files). Also renameApp.Api.http. dotnet tool restore && dotnet restore && dotnet build && dotnet test- Create the database:
dotnet ef migrations add Init --project <YourName>.Data --startup-project <YourName>.Api, thendotnet ef database updatewith the same flags. dotnet run --project <YourName>.Apiand send the requests in<YourName>.Api.http.
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.
- Copy
scaffolds/csharp-wpf/to wherever the project lives. - Find/replace
MyApp→<YourName>across files and folder names (checkx:ClassandRootNamespace). dotnet restore && dotnet build && dotnet testdotnet run --project <YourName>— the window opens dark; the button proves the binding chain.- Replace
Status/ConfirmWiringinMainViewModelwith real state and behavior.
App, but never name the project
literally App — a WPF project by that name fails to compile.
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?
- Copies only the lean parts and records the version in the copy.
--checktells you when a project is behind the canonical version.- Refuses to overwrite files you've edited locally (
--forceto override). - One rule: edit the system in the workbench, re-extract — never patch a copy.