A web-native application starter for Remix 3, by the Laravolt team. Volt builds on the platform
the way Remix 3 intends: Request/Response, real <form>s that post without JavaScript, native
<dialog> and popovers, signed cookies, SQL migrations. On top of that it ships what every business
app needs on day one: auth, DB-backed sessions, CSRF, an admin shell, a component kit and a strict
Handler → Service → Repository architecture, so teams ship real systems quickly and consistently.
Baseline: Remix 3.0.0-rc.1 (pinned; not Remix v2 / React Router).
UI: volt-preline (Preline UI 5, MIT) by default;
volt-catalyst (Tailwind Plus Catalyst) is a
drop-in upgrade for licensed teams.
bun install
cp .env.example .env # SESSION_SECRET only required outside development
npm run migrate
npm run dev # http://localhost:5555Register at /register; promote yourself with
sqlite3 db/volt.sqlite "update users set is_admin=1 where email='you@example.com'" and sign in
again to see the admin user table.
| Area | Included |
|---|---|
| Authentication | Email/phone + password, registration, logout, password reset by email, optional Google login |
| Sessions | DB-backed (sessions table), signed cookie carries only the id, rotation on login, revoke-all on password reset |
| Security | CSRF on every POST/PUT/PATCH/DELETE, per-route rate limits, secure cookies in production |
| Admin | Dashboard shell (navbar, account menu, mobile drawer), user list with bulk delete + confirmation |
| Profile | Account details + change password forms with field-level validation |
| Data | SQLite via better-sqlite3, SQL migrations (db/migrations, remix db compatible), repositories own all SQL |
| UI | volt-preline components: forms, tables, dialogs, dropdowns, listbox/combobox, layouts; dark mode |
| Production | No bundler: on-demand compiled, minified, fingerprinted assets (BUILD_ID), gzip, Dockerfile |
| Tests | remix test: repositories, services, routes (CSRF pass/fail, session rotation, admin rules) |
Request → middleware (static, formData, session, csrf, auth, render)
→ Handler app/actions/<area>/controller.tsx (HTTP only)
→ Service app/services/* (business rules, typed errors)
→ Repository app/repositories/* (the only SQL)
→ SQLite db/migrations/*
Rules, session/CSRF model and the PR checklist: ARCHITECTURE.md. Conventions for contributors and AI agents: AGENTS.md.
import { Button } from 'volt-preline/button'
import { Field, Label } from 'volt-preline/fieldset'
import { Input } from 'volt-preline/input'- Styling comes from Preline's semantic tokens (
bg-primary,bg-card,text-muted-foreground, …); override the theme inapp/styles/app.cssafter the kit import. - Dark mode:
installDarkMode()runs inapp/actions/public/entry.tsand follows the OS or a saved choice (setTheme('dark')); it survives Remix frame navigations. - Interactive components (dropdown, dialog, listbox, drawers) live inside
clientEntryislands:app/ui/public/app-shell.tsx,app/actions/app/public/users-table.tsx. - Switch to Catalyst (Tailwind Plus license required): add
volt-catalystas a dependency, replacevolt-preline/withvolt-catalyst/in imports andapp/styles/app.css, and list it inremix.json#assets.allowPackages. The two packages share the same component API.
| Command | Purpose |
|---|---|
npm run dev / npm run hmr |
dev server (Node --watch) / with browser+server HMR |
npm test |
remix test |
npm run typecheck |
tsc --noEmit |
npm run css / css:watch |
build public/app.css (Tailwind v4) |
npm run migrate / migrate:down / migrate:status |
migrations |
npm run routes / npm run doctor |
Remix CLI route table / convention check |
npm run start |
production (NODE_ENV=production, see below) |
No build step: the asset server compiles browser modules on demand and Node runs the TypeScript
source via remix/node-tsx.
export NODE_ENV=production SESSION_SECRET=$(openssl rand -hex 32) \
APP_URL=https://app.example.com DATABASE_FILE=/data/volt.sqlite BUILD_ID=$(git rev-parse --short HEAD)
bun install && npm run migrate && npm run startSet BUILD_ID per deploy for immutable fingerprinted asset URLs. Put a TLS proxy in front.
Container: docker build --build-arg BUILD_ID=$(git rev-parse --short HEAD) -t volt .
When deploying behind a reverse proxy or TLS termination layer:
-
HTTPS and Secure Cookies: In production (
NODE_ENV=production), session cookies are automatically stamped withSecure; HttpOnly; SameSite=Lax. Browsers will reject storing or sending these cookies over plain HTTP. Ensure the site is served over HTTPS. -
Proxy Trust (
trustProxy/TRUST_PROXY): When a proxy forwards traffic to Volt via HTTP (e.g.http://127.0.0.1:5555), request headers likeX-Forwarded-Proto,X-Forwarded-Host, andX-Forwarded-Formust be trusted. Volt enablestrustProxy: config.trustProxyinserver.tsby default in production (TRUST_PROXY=1). Without this, Remix's CSRF protection detects an origin mismatch between the incoming browser request (https://...) and the local node request (http://127.0.0.1:5555), returning403 Forbidden(invalid-origin) on state-changing POST requests. -
Tailscale Serve Example:
sudo tailscale set --operator=$USER tailscale serve --bg https / http://127.0.0.1:5555
npm note: on machines with
minimum-release-agein~/.npmrc,remix@3.0.0-rc.1may be hidden from npm for a week after release;bun installis unaffected.
- Roles & permissions, audit trail, file uploads (S3/local), notifications and queues
- CRUD scaffolding (
volt make:resource) on top of the layered architecture - Public
volt-prelinerelease and a hosted demo
Recreated from laravolt/laju on the Remix 3 baseline; planning
intent in intent.md.