This repository serves as a robust starting point for building modern full-stack applications with .NET and SvelteKit. It comes pre-configured with essential components to jumpstart your development, following Clean Architecture principles.
- Clean Architecture: Organized into Domain, Application, Infrastructure, and WebApi layers.
- Database: Pre-configured PostgreSQL connection with Entity Framework Core.
- Identity: Built-in authentication system (JWT/Cookie-based) with HttpOnly cookies.
- Validation: FluentValidation integration.
- Logging: Serilog configuration.
- Documentation: Scalar (OpenAPI) integration.
- Modern Stack: Svelte 5 (Runes), Tailwind CSS v4, and Vite.
- UI Components: Shadcn-svelte (using bits-ui@next) for accessible, customizable components.
- BFF Pattern: Backend-for-Frontend architecture using SvelteKit's server-side hooks and proxy routes to handle authentication securely.
- Type Safety: End-to-end type safety with
openapi-fetchgenerated from the backend OpenAPI spec. - Localization: Production-ready i18n system with type-safe keys, server-side detection, and cookie persistence.
- Containerization: Ready-to-use
Dockerfileanddocker-composesetup for the entire stack. - Tooling: Includes initialization scripts to rename the project and set up ports automatically.
Before you begin, ensure you have the following installed:
- Docker Desktop
- .NET 10 SDK
- Node.js 22+ (for local frontend development)
- Git
Follow these simple steps to set up your new project:
Fork this repository or clone it directly to your local machine:
git clone <your-repo-url>
cd web-api-templateThis template includes scripts to rename the project (from "MyProject" to your desired name) and configure ports. It will also restore local .NET tools (like dotnet-ef).
For macOS / Linux:
chmod +x init.sh
./init.shFor Windows (PowerShell):
.\init.ps1What the script does:
- Asks for your Project Name (e.g.,
MyAwesomeApi). - Asks for a Base Port (default
13000).- Frontend:
Base Port(e.g.,13000). - API:
Base Port + 2(e.g.,13002). - Database:
Base Port + 4(e.g.,13004).
- Frontend:
- Renames all files, directories, and namespaces in the solution.
- Updates
docker-compose.local.ymland configuration files with the new ports. - Restores local .NET tools (ensures
dotnet-efis available).
Once initialized, you can start the entire infrastructure (Frontend + API + Database) using Docker Compose:
docker compose -f docker-compose.local.yml up -d --build- Frontend:
http://localhost:<BASE_PORT>(e.g.,http://localhost:13000) - API:
http://localhost:<API_PORT>(e.g.,http://localhost:13002) - Swagger UI:
http://localhost:<API_PORT>/scalar/v1
src/
├── backend/ # .NET Web API solution
│ ├── MyProject.Domain/ # Core domain entities, value objects
│ ├── MyProject.Application/ # Application contracts, features
│ ├── MyProject.Infrastructure/ # Implementation (EF Core, etc.)
│ └── MyProject.WebApi/ # API entry point
│
└── frontend/ # SvelteKit application
├── src/
│ ├── lib/
│ │ ├── api/ # Generated API client
│ │ ├── components/ # UI components (Shadcn)
│ │ └── server/ # Server-side config
│ └── routes/ # File-based routing
└── static/
Note: When running the API in the
Developmentconfiguration, the application automatically applies any pending migrations on startup.
If you need to add new migrations:
- Ensure the database container is running.
- Run the following command from the root directory:
dotnet ef migrations add <MigrationName> --project src/backend/<YourProjectName>.Infrastructure --startup-project src/backend/<YourProjectName>.WebApi --output-dir Features/Postgres/Migrations
dotnet ef database update --project src/backend/<YourProjectName>.Infrastructure --startup-project src/backend/<YourProjectName>.WebApiFor a better developer experience (HMR, faster builds), you can run the frontend locally while keeping the backend in Docker:
- Start the backend and database:
docker compose -f docker-compose.local.yml up -d api db
- Navigate to the frontend directory:
cd src/frontend - Install dependencies:
npm install
- Start the dev server:
npm run dev
The frontend includes a robust localization system built on Paraglide JS, designed for high-traffic and scalable SPAs.
- Type-Safe Keys: TypeScript types are generated from the default locale (
en.json), preventing missing key errors. - Auto-Detection: Detects language from the browser (client-side) or
Accept-Languageheader/cookies (server-side). - Persistence: User preference is saved in a cookie (
locale) for consistent experience across sessions. - SSR Support: Injects the correct
langattribute into the HTML tag during server-side rendering to prevent hydration mismatches.
- Create a new translation file in
src/frontend/src/lib/locales/(e.g.,es.json). - Register the new locale in
src/frontend/src/lib/i18n.ts:register('es', () => import('./locales/es.json'));
- Add the language code to the
supportedLocalesarray insrc/frontend/src/lib/i18n.ts.
This project is licensed under the GNU Affero General Public License v3.0 (AGPLv3).