A basic dashboard template implemented using Remix and shadcn/ui, designed for quick project startup.
pnpm dlx create-remix@latest --template dev-templates/remix-dashboard-template-
Authentication & Security
- Username/Password Authentication with cookie-based sessions
- Mandatory two-factor authentication (2FA) for all users
- Role-based access control (RBAC) with flexible permission system
-
User Management
- Complete user CRUD operations (Create, Read, Update, Delete)
- Admin capabilities: reset passwords, disable 2FA, manage user roles
- User self-service: password change, 2FA settings
-
System Administration
- Configurable system settings interface
- User role and permission management
- Database auto-initialization for both development and production
- Development with Vite
- Database: SQLite (dev) / PostgreSQL (production ready)
- Database ORM with Prisma
- GitHub Actions for deploy on merge to production and staging environments
- Styling with Tailwind CSS v4 and shadcn/ui
- Dark mode support with next-themes
- Form validation with React Hook Form + Zod
- Charts with Recharts
- Code formatting and linting with Biome
- Static Types with TypeScript
- Node.js >= 20.0.0
- pnpm (recommended) or npm
- Dashboard (
/dashboard) - Main dashboard with charts and statistics - Login with 2FA (
/login,/two-factor) - Secure login with mandatory two-factor authentication - Password Management (
/settings/password) - Change your password - Security Settings (
/settings/security) - Manage 2FA settings (setup, regenerate, view backup codes)
- User Management (
/admin/users) - Manage all users- Create new users with role assignment
- Delete users
- Reset user passwords
- Disable user 2FA (for account recovery)
- System Settings (
/admin/settings) - Configure system-wide settings
Get started in just three steps:
-
Install dependencies
pnpm i
-
Configure environment variables
Create a
.envfile:NODE_ENV=development DATABASE_URL=file:./dev.db SESSION_SECRET=e33b3bfc-4c8c-41a3-b6fc-83a9905b90c8
-
Start the development server
pnpm dev
🎉 That's it! The database will be automatically initialized, including:
- Auto-generate Prisma Client
- Auto-apply database migrations
- Auto-insert initial seed data
The application uses automatic database initialization:
- Development environment: When running
pnpm dev, the Vite plugin automatically checks database status and performs necessary initialization - Production environment: Before running
pnpm start, theprestartscript automatically executes database migrations
After the first startup, you can log in with the following account:
- Username:
admin - Password:
admin
If you need to manually control database operations:
# Generate Prisma Client (after modifying schema.prisma)
pnpm run generate
# Create a new migration (after modifying schema.prisma)
pnpm run migrate:create
# Deploy migrations to production
pnpm run migrate:deploy
# Reset database (⚠️ deletes all data)
pnpm run db:reset
# Re-insert seed data
pnpm run seed
# Skip automatic initialization
SKIP_DB_INIT=true pnpm dev# Format and lint code (auto-fix)
pnpm run lint
# Format code only
pnpm run format
# Check code quality (no auto-fix)
pnpm run check
# Type checking
pnpm run typecheck-
DATABASE_URL- Prisma database connection string- Development (SQLite):
file:./dev.db - Production (PostgreSQL):
postgresql://user:password@localhost:5432/mydb - More connection format documentation
- Note: To switch to PostgreSQL, update the
providerinprisma/schema.prismafromsqlitetopostgresql
- Development (SQLite):
-
SESSION_SECRET- Session encryption secret key- Generate using a random password generator: Password Generator
-
NODE_ENV- Runtime environment (development/production)- Default:
development
- Default:
-
SKIP_DB_INIT- Skip automatic database initialization- Set to
trueto disable automatic initialization - Useful for debugging or special scenarios
- Set to
-
SKIP_SEED- Skip seed data insertion- Set to
trueto skip inserting initial data - Strongly recommended to set to
truein production
- Set to
NODE_ENV=production
DATABASE_URL=postgresql://user:password@db.example.com:5432/production_db
SESSION_SECRET=your-very-secure-random-secret-key
SKIP_SEED=trueThe easiest way to deploy with Docker:
# 1. Create .env file from example
cp .env.example .env
# 2. Generate a secure session secret
echo "SESSION_SECRET=$(openssl rand -hex 32)" >> .env
# 3. Start the service
docker compose up -d
# 4. View logs
docker compose logs -f app
# 5. Stop the service
docker compose downThe application will be available at http://localhost:3000
Using PostgreSQL with Docker Compose:
-
Update database provider in schema:
Edit
prisma/schema.prisma:datasource db { provider = "postgresql" // Change from "sqlite" to "postgresql" url = env("DATABASE_URL") }
-
Update database URL in .env:
DATABASE_URL=postgresql://remix:remix_password@postgres:5432/remix_dashboard -
Uncomment PostgreSQL service in
docker-compose.yml -
Restart services:
docker compose down docker compose up -d --build
Note: Prisma requires the provider to be hardcoded in schema.prisma and cannot read it from environment variables. This is a design limitation for type safety and compile-time code generation.
If you prefer to use Docker commands directly:
# 1. Build the image
docker build -t remix-dashboard .
# 2. Run the container (SQLite)
docker run -d \
--name remix-dashboard \
-p 3000:3000 \
-e SESSION_SECRET="your-secret-key-here" \
-e SKIP_SEED=true \
-v remix-data:/app/data \
remix-dashboard
# 3. View logs
docker logs -f remix-dashboard
# 4. Stop and remove the container
docker stop remix-dashboard
docker rm remix-dashboardUsing PostgreSQL:
First, update prisma/schema.prisma provider to postgresql, then:
# 1. Start PostgreSQL
docker run -d \
--name postgres \
-e POSTGRES_USER=remix \
-e POSTGRES_PASSWORD=secure_password \
-e POSTGRES_DB=remix_dashboard \
-v postgres-data:/var/lib/postgresql/data \
postgres:16-alpine
# 2. Rebuild the app with PostgreSQL provider
docker build -t remix-dashboard .
# 3. Run the app
docker run -d \
--name remix-dashboard \
--link postgres:postgres \
-p 3000:3000 \
-e DATABASE_URL="postgresql://remix:secure_password@postgres:5432/remix_dashboard" \
-e SESSION_SECRET="your-secret-key-here" \
-e SKIP_SEED=true \
remix-dashboardWhen deploying with Docker, set these environment variables:
SESSION_SECRET- Required. Generate with:openssl rand -hex 32DATABASE_URL- Database connection string (default:file:./data/production.db)SKIP_SEED- Set totrueto skip seed data in productionPORT- Port to listen on (default:3000)
If you see "Unable to connect to database" error:
- Check that the
.envfile exists and is configured correctly - Confirm that the
DATABASE_URLformat is correct - If using PostgreSQL, confirm the database service is running
- Check network connection and firewall settings
If database migration fails:
# Check migration status
pnpm exec prisma migrate status
# Reset database (⚠️ will delete all data)
pnpm run db:reset
# Manually deploy migrations
pnpm run migrate:deployIf you need complete control over the database initialization process:
# Development environment
SKIP_DB_INIT=true pnpm dev
# Production environment
SKIP_SEED=true pnpm start