| name | rust-webapp |
| description | Build full-stack web applications using Rust (Axum + SQLx) with HTMX + Alpine.js frontend and Neon (serverless PostgreSQL). Use when asked to create web apps, CRUD apps, dashboards, forms, or any stateful web application. Triggers on requests like "build a todo app", "create a voting app", "make a dashboard", "build a blog", etc. |
Build full-stack stateful web apps using Axum + HTMX + Alpine.js + Neon (PostgreSQL).
Stack: Axum + SQLx (Rust), Askama templates + HTMX + Alpine.js + PicoCSS, Neon (PostgreSQL), Docker.
Workflow
Phase 1: Setup
Prerequisites (install once):
npm i -g neonctl
brew install jq
cargo install sqlx-cli --features postgres,native-tls
Required env vars: NEON_API_KEY, NEON_PROJECT_ID
Scaffold app:
NEON_BRANCH_TTL=2h .claude/skills/rust-webapp/scripts/scaffold <app-name> .
Creates app files and a Neon branch ({app}-dev) with 2h expiration.
Phase 2: Data Modeling
- Define models in
src/models.rs - Write migration SQL in
migrations/001_init.sql - Use
SERIALfor i32,BIGSERIALfor i64
Reference: Models - SQLx patterns, struct definitions, type mapping
Phase 3: Backend Implementation
- Add route handlers in
src/main.rs - All handlers return
Result<T, AppError>- use?operator - NEVER use
.expect()or.unwrap()- causes server crashes - Route params use
{id}syntax (NOT:id)
Reference: Handlers - CRUD patterns, router setup, transactions
Phase 4: Frontend
- Update Askama templates in
templates/ - Delete unused template files (create.html, edit.html if not needed)
- Use HTMX for interactivity, Alpine.js for state
Reference: Templates - Askama, HTMX, Alpine patterns Reference: Design - CSS components, layout patterns
Phase 5: Validation
Validate (runs cargo check, clippy, tests, release build):
.claude/skills/rust-webapp/scripts/validate .
Fix all errors before completing.
Template Structure
├── Cargo.toml # Dependencies
├── Dockerfile # Multi-stage Rust build
├── src/
│ ├── main.rs # Axum server, routes, templates
│ ├── db.rs # SQLx pool setup
│ └── models.rs # Data structs
├── templates/
│ ├── base.html # Base layout (PicoCSS/HTMX/Alpine CDN)
│ ├── index.html # List view
│ ├── edit.html # Edit form
│ └── create.html # Create form
├── static/
│ └── styles.css # Custom CSS overrides
└── migrations/
└── 001_init.sql # Database schema
Critical Rules
- NEVER
.expect()or.unwrap()in handlers - use?operator - Route params:
{id}not:id- wrong syntax compiles but panics at runtime - All handlers return
Result<T, AppError> - Check
rows_affected()for DELETE/UPDATE to return 404 - Use compile-time SQLx macros (
query!,query_as!) - Ensure the app has enough logs for basic observability
Full list: Pitfalls
Constraints
- Neon (PostgreSQL) required - needs
DATABASE_URL - All routes at root level (/, /new, /{id}/edit)
- Strict clippy lints - must pass validation