48  Scaffold Commands: Flutter SPA + .NET WebAPI

Here are the Zsh commands to build the entire repository structure. Run these in your terminal.

48.1 Step 1: Create Root Directory & Basic Files

# Set your project name
PROJECT_NAME="my-app"

# Create root directory and navigate into it
mkdir -p $PROJECT_NAME && cd $PROJECT_NAME

# Initialize git
git init

# Create docs folder
mkdir -p docs

48.2 Step 2: Create Flutter Frontend

# Create Flutter project (web-only)
flutter create --platforms=web frontend

# Create additional folder structure inside frontend
mkdir -p frontend/lib/{features,shared,core}

48.3 Step 3: Create .NET Backend

# Create backend directory structure
mkdir -p backend/src

# Create .NET WebAPI project
dotnet new webapi -n MyApp.Api -o backend/src/MyApp.Api

# Create solution file and add project
dotnet new sln -n MyApp.Api -o backend
dotnet sln backend/MyApp.Api.sln add backend/src/MyApp.Api/MyApp.Api.csproj

# Create wwwroot with .gitkeep
mkdir -p backend/src/MyApp.Api/wwwroot
touch backend/src/MyApp.Api/wwwroot/.gitkeep

48.4 Step 4: Create Makefile

cat > Makefile << 'EOF'
# === Configuration ===
FRONTEND_DIR := frontend
BACKEND_DIR := backend/src/MyApp.Api
WWWROOT_DIR := $(BACKEND_DIR)/wwwroot

# === Default ===
.PHONY: help
help:
    @echo "Usage: make [target]"
    @echo ""
    @echo "Targets:"
    @echo "  build           Build frontend and backend (production)"
    @echo "  build-frontend  Build Flutter web"
    @echo "  build-backend   Build .NET API"
    @echo "  run             Run .NET server (serves SPA + API)"
    @echo "  dev-frontend    Run Flutter in Chrome (hot reload)"
    @echo "  dev-backend     Run .NET in watch mode"
    @echo "  clean           Clean all build artifacts"
    @echo "  restore         Restore all dependencies"

# === Build ===
.PHONY: build build-frontend build-backend

build: build-frontend build-backend
    @echo "βœ… Full build complete"

build-frontend:
    @echo "πŸ”¨ Building Flutter web..."
    cd $(FRONTEND_DIR) && flutter build web --release
    @echo "πŸ“¦ Copying to wwwroot..."
    rm -rf $(WWWROOT_DIR)/*
    cp -r $(FRONTEND_DIR)/build/web/* $(WWWROOT_DIR)/

build-backend:
    @echo "πŸ”¨ Building .NET API..."
    cd $(BACKEND_DIR) && dotnet build -c Release

# === Run ===
.PHONY: run dev-frontend dev-backend

run:
    @echo "πŸš€ Running .NET server..."
    cd $(BACKEND_DIR) && dotnet run -c Release

dev-frontend:
    @echo "πŸ”₯ Running Flutter dev server..."
    cd $(FRONTEND_DIR) && flutter run -d chrome

dev-backend:
    @echo "πŸ”₯ Running .NET in watch mode..."
    cd $(BACKEND_DIR) && dotnet watch run

# === Utilities ===
.PHONY: clean restore

clean:
    @echo "🧹 Cleaning..."
    rm -rf $(FRONTEND_DIR)/build
    rm -rf $(WWWROOT_DIR)/*
    touch $(WWWROOT_DIR)/.gitkeep
    cd $(BACKEND_DIR) && dotnet clean

restore:
    @echo "πŸ“₯ Restoring dependencies..."
    cd $(FRONTEND_DIR) && flutter pub get
    cd $(BACKEND_DIR) && dotnet restore
EOF

48.5 Step 5: Create .gitignore

cat > .gitignore << 'EOF'
# Flutter
frontend/build/
frontend/.dart_tool/
frontend/.packages
frontend/.flutter-plugins
frontend/.flutter-plugins-dependencies

# .NET
backend/**/bin/
backend/**/obj/
backend/**/*.user
backend/**/.vs/

# wwwroot (generated content)
backend/src/MyApp.Api/wwwroot/*
!backend/src/MyApp.Api/wwwroot/.gitkeep

# IDE
.idea/
.vscode/
*.swp
*.swo

# OS
.DS_Store
Thumbs.db

# Logs
*.log
EOF

48.6 Step 6: Create README.md

cat > README.md << 'EOF'
# My App

Mono-repo with Flutter Web SPA frontend and .NET WebAPI backend.

## Structure

β”œβ”€β”€ frontend/ # Flutter Web SPA β”œβ”€β”€ backend/ # .NET WebAPI β”‚ └── src/MyApp.Api/ β”‚ └── wwwroot/ # Built Flutter app served here β”œβ”€β”€ docs/ └── Makefile


## Quick Start

```bash
# Install dependencies
make restore

# Development (separate servers)
make dev-frontend    # Terminal 1: Flutter hot-reload
make dev-backend     # Terminal 2: .NET API

# Production build & run
make build           # Build Flutter β†’ wwwroot
make run             # Run .NET server

48.7 Available Commands

Command Description
make help Show all commands
make restore Install all dependencies
make build Production build
make run Run production server
make dev-frontend Flutter dev with hot-reload
make dev-backend .NET watch mode
make clean Clean build artifacts

EOF


## Step 7: Update .NET Program.cs for SPA

```zsh
cat > backend/src/MyApp.Api/Program.cs << 'EOF'
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

// Serve static files from wwwroot (Flutter build)
app.UseDefaultFiles();
app.UseStaticFiles();

app.UseAuthorization();

app.MapControllers();

// SPA fallback - serves index.html for client-side routing
app.MapFallbackToFile("index.html");

app.Run();
EOF

48.8 Step 8: Create Architecture Doc

cat > docs/architecture.md << 'EOF'
# Architecture

## Overview

Browser β”‚ β–Ό β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ .NET WebAPI Server β”‚ β”‚ (Kestrel) β”‚ β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚ /api/* β†’ Controllers β”‚ β”‚ /* β†’ wwwroot/ β”‚ β”‚ (Flutter SPA) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜


## Request Flow

1. API requests (`/api/*`) β†’ .NET Controllers
2. Static files β†’ `wwwroot/` directory  
3. Client routes β†’ Fallback to `index.html` (SPA handles routing)

## Development

- Frontend: `localhost:3000` (Flutter dev server)
- Backend: `localhost:5xxx` (.NET)

## Production

- Single server serves both SPA and API
- Flutter build copied to `wwwroot/`
EOF

48.9 All-in-One Script

If you want to run everything at once, here’s a combined script:

#!/bin/zsh
PROJECT_NAME="my-app"

# Create and enter project
mkdir -p $PROJECT_NAME && cd $PROJECT_NAME
git init
mkdir -p docs

# Flutter frontend
flutter create --platforms=web frontend
mkdir -p frontend/lib/{features,shared,core}

# .NET backend
mkdir -p backend/src
dotnet new webapi -n MyApp.Api -o backend/src/MyApp.Api
dotnet new sln -n MyApp.Api -o backend
dotnet sln backend/MyApp.Api.sln add backend/src/MyApp.Api/MyApp.Api.csproj
mkdir -p backend/src/MyApp.Api/wwwroot
touch backend/src/MyApp.Api/wwwroot/.gitkeep

echo "βœ… Scaffold complete! Run: cd $PROJECT_NAME && make help"

48.10 Verify Structure

After running the commands, verify with:

tree -L 4 -I 'node_modules|.git'

Expected output:

.
β”œβ”€β”€ Makefile
β”œβ”€β”€ README.md
β”œβ”€β”€ backend
β”‚   β”œβ”€β”€ MyApp.Api.sln
β”‚   └── src
β”‚       └── MyApp.Api
β”‚           β”œβ”€β”€ Controllers
β”‚           β”œβ”€β”€ MyApp.Api.csproj
β”‚           β”œβ”€β”€ MyApp.Api.http
β”‚           β”œβ”€β”€ Program.cs
β”‚           β”œβ”€β”€ Properties
β”‚           β”œβ”€β”€ appsettings.Development.json
β”‚           β”œβ”€β”€ appsettings.json
β”‚           └── wwwroot
β”œβ”€β”€ docs
β”‚   └── architecture.md
└── frontend
    β”œβ”€β”€ README.md
    β”œβ”€β”€ analysis_options.yaml
    β”œβ”€β”€ lib
    β”‚   β”œβ”€β”€ core
    β”‚   β”œβ”€β”€ features
    β”‚   β”œβ”€β”€ main.dart
    β”‚   └── shared
    β”œβ”€β”€ pubspec.lock
    β”œβ”€β”€ pubspec.yaml
    β”œβ”€β”€ test
    └── web