Build a full-stack web application with OAuth authentication, Tuxedo ORM, Bowtie schema sync, and responsive UI using Noundry libraries. Get from zero to production in minutes.
# Clone the starter template
$ git clone https://github.com/noundry/NoundryStarter MyWebApp
# Navigate to the web project
$ cd MyWebApp/src/NoundryStarter.Web
# Restore and run
$ dotnet restore
$ dotnet run
Your web app will be available at https://localhost:5001.
Clone the Noundry Web App Starter from GitHub. All Noundry packages come pre-configured.
$ git clone https://github.com/noundry/NoundryStarter MyWebApp
Navigate to the web project and restore NuGet packages.
$ cd MyWebApp/src/NoundryStarter.Web
$ dotnet restore
Set your PostgreSQL connection string in .env. Bowtie automatically syncs your schema on startup.
# .env file
DATABASE_CONNECTION_STRING="Host=localhost;Database=MyWebAppDb;Username=postgres;Password=secret"
Set up OAuth providers by adding your client ID and secret.
// appsettings.json
{
"Authentication": {
"Google": {
"ClientId": "your-client-id",
"ClientSecret": "your-client-secret"
}
}
}
Start the application with hot reload for rapid development.
$ dotnet watch run
MyWebApp/
Pages/ # Razor Pages
Account/ # Login, Register, Profile
Admin/ # Admin dashboard
Index.cshtml # Home page
Models/ # Entity models
Data/ # Tuxedo repositories, queries
Services/ # Business logic
wwwroot/ # Static assets, CSS
Program.cs # Application entry point
appsettings.json # Configuration
Dockerfile # Container support
The template comes pre-configured with Noundry component libraries. Here are examples of using them in your Razor Pages.
var builder = WebApplication.CreateBuilder(args);
// Add Noundry services
builder.Services.AddAuthnz(builder.Configuration);
builder.Services.AddTuxedo(builder.Configuration
.GetConnectionString("DefaultConnection"));
// Add Razor Pages with Noundry tag helpers
builder.Services.AddRazorPages();
var app = builder.Build();
app.UseAuthentication();
app.UseAuthorization();
app.MapRazorPages();
app.Run();
// Models/Customer.cs
[Table("customers")]
public class Customer
{
[ExplicitKey]
[DefaultValue("gen_random_uuid()")]
[Column("id", "uuid")]
public Guid Id { get; set; }
[Column("first_name", "varchar(100)")]
public required string FirstName { get; set; }
[Column("email", "varchar(255)")]
[Index(IsUnique = true)]
public required string Email { get; set; }
[Column("is_active", "boolean")]
[DefaultValue("true")]
public bool IsActive { get; set; } = true;
}
# .env file (development)
DATABASE_CONNECTION_STRING="Host=localhost;Database=MyWebAppDb;Username=postgres;Password=secret"
GOOGLE_CLIENT_ID="your-client-id"
GOOGLE_CLIENT_SECRET="your-client-secret"
GITHUB_CLIENT_ID="your-github-client-id"
GITHUB_CLIENT_SECRET="your-github-client-secret"
The template uses Razor Pages with Tailwind CSS. Add new pages to the Pages directory.
// Pages/Customers/Index.cshtml.cs
public class IndexModel : PageModel
{
private readonly IDbConnection _db;
public IndexModel(IDbConnection db) => _db = db;
public IReadOnlyList<Customer> Customers { get; set; } = [];
public async Task OnGetAsync()
{
Customers = (await _db.GetAllAsync<Customer>())
.ToList();
}
}
<!-- Key packages in the template -->
<PackageReference Include="Noundry.UI" />
<PackageReference Include="Noundry.Authnz" />
<PackageReference Include="Noundry.Tuxedo" />
<PackageReference Include="Noundry.Tailbreeze" />
<PackageReference Include="Noundry.TagHelpers" />
<PackageReference Include="Noundry.DotEnvX" />
Pre-built Razor components for forms, tables, modals, alerts, and more.
OAuth 2.0 authentication with social login (Google, GitHub, Microsoft) and role management.
Lightweight ORM with Dapper-compatible API for database access.
Tailwind CSS integration with dark mode and build pipeline.
Custom tag helpers for Razor Pages and MVC views.
Environment variable management with encryption support.
The template uses PostgreSQL with Noundry.Tuxedo ORM. Bowtie automatically syncs your schema from model attributes on startup — no manual migration commands needed.
The template supports Google and GitHub by default. Add Microsoft, Facebook, or custom OpenID Connect providers in Program.cs.
Modify tailwind.config.js to change colors, fonts, and breakpoints. Noundry.Tailbreeze handles the CSS build pipeline.
Register hosted services in Program.cs for background processing, scheduled tasks, or message queue consumers.
Use Noundry Spinup to provision a security-hardened VM on any cloud, then deploy your app with Docker.
# Install Spinup
$ dotnet tool install -g Noundry.Spinup
# Set your cloud credentials (example: AWS)
$ export AWS_ACCESS_KEY_ID=your-key
$ export AWS_SECRET_ACCESS_KEY=your-secret
# Provision a VM (AWS, Azure, GCP, or DigitalOcean)
$ spinup provision --cloud aws --region us-east-1 --resource vm --name mywebapp -y
# Or use DigitalOcean
$ export DIGITALOCEAN_TOKEN=your-api-token
$ spinup provision --cloud digitalocean --region nyc3 --resource vm --name mywebapp -y
Spinup automatically hardens the VM with UFW firewall, fail2ban, SSH key-only auth, and your IP whitelisted.
# Build for production
$ dotnet publish -c Release -o ./publish
# Or use Docker
$ docker build -t mywebapp .
# SSH into your VM (key auto-generated by Spinup)
$ ssh -i ~/.spinup/workspaces/mywebapp/mywebapp_ssh_key.pem ubuntu@<public-ip>
# Deploy with Docker on the VM
$ docker run -d -p 80:80 --env-file .env mywebapp