Demo mode allows you to showcase MovaLab without risking data corruption or requiring user signup. It is an optional configuration for local demonstrations and testing.
- Overview
- Quick Start
- Features in Demo Mode
- Local Demo Setup
- Resetting and Clearing Demo Data
- Security Considerations
- Technical Implementation
- Troubleshooting
- FAQ
Demo mode is a special configuration that:
- Enables quick-login buttons -- Users can log in as different roles with one click (no signup required)
- Disables destructive actions -- Delete, remove, and dangerous operations are blocked
- Hides superadmin access -- Prevents exposure of sensitive admin features
- Protects demo data -- Ensures the demo environment stays clean for the next user
| Scenario | Use Demo Mode? |
|---|---|
| Public product demo | Yes |
| Internal testing | Yes |
| Evaluating MovaLab | Yes |
| Development with test data | Optional |
| Production deployment | No |
Demo mode requires demo users to exist in the database. The scripts/create-seed-users.ts utility can create these, but it is not run automatically by any npm script. You must run it manually if you want demo users:
npx tsx scripts/create-seed-users.ts# One command starts everything
npm run dev:demoThis will:
- Check Docker is installed and running
- Start Supabase containers (PostgreSQL, Auth, API, etc.)
- Wait for services to be ready
- Start Next.js with demo mode enabled
- Open http://localhost:3000
If Supabase containers are already running, you can just set the environment variable:
-
Add to
.env.local:NEXT_PUBLIC_DEMO_MODE=true -
Start the dev server:
npm run dev
Both approaches result in the same demo experience.
npm run docker:stopInstead of the standard login form with email/password, demo mode shows:
- Quick-login buttons for each demo user
- Role descriptions to help users choose
- One-click access (no password typing needed)
- Password hint displayed for manual login if needed
The following destructive actions are blocked in demo mode:
| Action | Normal Mode | Demo Mode |
|---|---|---|
| Delete accounts | Allowed | Blocked |
| Remove users from accounts | Allowed | Blocked |
| Delete departments | Allowed | Blocked |
| Delete roles | Allowed | Blocked |
| Remove users from roles | Allowed | Blocked |
| Delete projects | Allowed | Blocked |
| Delete tasks | Allowed | Blocked |
| Delete time entries | Allowed | Blocked |
| Delete workflows | Allowed | Blocked |
| Delete newsletters | Allowed | Blocked |
| Superadmin setup | Accessible | Hidden |
When a user attempts a blocked action, they see a friendly message explaining that the action is disabled in demo mode.
Hidden Features
- Superadmin setup page
- User signup toggle on login page
# Clone the repository
git clone https://github.com/itigges22/MovaLab.git
cd MovaLab
# Run the full setup
npm run setup
# Create demo users (required for demo mode quick-login buttons)
npx tsx scripts/create-seed-users.ts
# Start demo mode
npm run dev:demo# Start demo mode
npm run dev:demo
# When done, stop Docker to free RAM
npm run docker:stopLocal demo mode runs several Docker containers:
- PostgreSQL database
- Supabase Auth (GoTrue)
- Supabase API (PostgREST)
- Supabase Studio (optional, for database UI)
Typical RAM usage: 2-4 GB
To minimize resource usage, stop Docker when not in use: npm run docker:stop
To completely reset the database to a clean slate:
npm run docker:resetThis will:
- Drop all existing data
- Re-run all migrations
- Load seed data (3 system roles only)
Note: After a reset, you'll need to either go through the onboarding wizard again or re-create demo users:
npx tsx scripts/create-seed-users.tsWarning: This destroys ALL data in the local database.
If you want to clean specific data without a full reset:
- Open Supabase Studio:
npm run docker:studio(opens http://localhost:54323) - Navigate to the Table Editor
- Manually delete rows from specific tables
If Docker containers are corrupted:
# Stop and remove all Supabase containers
npm run docker:clean
# This runs: supabase stop --no-backup && docker system prune -f
# Start fresh
npm run setupDemo mode provides:
- UI convenience (quick-login buttons)
- Accidental deletion prevention
- Clean demo experience
Demo mode does NOT provide:
- Database isolation
- User authentication bypass prevention
- API security (beyond blocking specific endpoints)
For true security, use:
- Row Level Security (RLS) policies (always enabled)
- Proper authentication and authorization
- The standard login flow (non-demo mode) for production
Local Docker volumes are not backed up. If you prune Docker volumes or reset, all data is lost. This is expected for a development/demo environment.
| File | Purpose |
|---|---|
lib/demo-mode.ts |
Core demo mode logic and configuration |
lib/api-demo-guard.ts |
API route protection |
components/demo-login-form.tsx |
Quick-login UI component |
scripts/start-demo.js |
Smart startup script |
scripts/create-seed-users.ts |
Dev utility to create demo users (not run by npm scripts) |
| Variable | Purpose | Values |
|---|---|---|
NEXT_PUBLIC_DEMO_MODE |
Enable demo mode UI | true / false |
DEMO_MODE |
Server-side demo check (fallback) | true / false |
Note: NEXT_PUBLIC_ prefix makes the variable available in browser code.
Option 1: Via npm run dev:demo
- Sets
NEXT_PUBLIC_DEMO_MODE=trueat runtime - Also starts Supabase containers automatically
- Includes safety checks
Option 2: Via .env.local
- Add
NEXT_PUBLIC_DEMO_MODE=trueto your.env.local - Run
npm run devnormally - Supabase must already be running
Both methods produce identical behavior.
-
Client-side detection:
import { isDemoMode } from '@/lib/demo-mode'; if (isDemoMode()) { // Show demo UI }
-
Blocking actions (client):
import { isActionBlocked, getBlockedActionMessage } from '@/lib/demo-mode'; if (isActionBlocked('delete_project')) { toast.error(getBlockedActionMessage('delete_project')); return; }
-
Blocking actions (API):
import { checkDemoModeForDestructiveAction } from '@/lib/api-demo-guard'; export async function DELETE(request: NextRequest) { const blocked = checkDemoModeForDestructiveAction('delete_project'); if (blocked) return blocked; // Continue with delete... }
-
Add the action type to
lib/demo-mode.ts:export type BlockedAction = | 'delete_account' | 'your_new_action' // Add here // ...
-
Add the message:
const BLOCKED_MESSAGES: Record<BlockedAction, string> = { your_new_action: 'This action is disabled in demo mode.', // ... };
-
Use in your component or API route.
Error: Docker is not running!
Solution:
- Open Docker Desktop
- Wait for it to fully start (check the whale icon in system tray)
- Try again:
npm run dev:demo
Error: Port 54321 is already in use
Solution:
# Stop any existing Supabase
npm run docker:stop
# If that doesn't work, force stop all containers
docker stop $(docker ps -q)
# Try again
npm run dev:demoSymptoms: Delete buttons still visible, normal login shown
Check:
- Verify
NEXT_PUBLIC_DEMO_MODE=trueis set in.env.localOR you're usingnpm run dev:demo - Restart the dev server (the env var is read at startup)
- Clear browser cache / hard refresh (Ctrl+Shift+R)
- Check browser console for errors
Symptoms: Quick-login buttons show but no users exist to log in as
Solution: Create demo users manually:
npx tsx scripts/create-seed-users.tsSolutions:
- Verify Supabase is running:
npx supabase status - Check the Supabase API:
curl http://127.0.0.1:54321/rest/v1/ - Clear
.nextcache:rm -rf .next && npm run dev - Check for JavaScript errors in browser console
Yes! Demo users can create projects, tasks, log time, etc. They just can't delete data. This allows users to fully experience the platform.
Yes, data persists in Docker volumes until you run npm run docker:reset.
Yes, edit lib/demo-mode.ts to change:
- User list and roles
- Colors and descriptions
- Which actions are blocked
Run npx tsx scripts/create-seed-users.ts to create demo users. For additional data (projects, tasks, etc.), use the application UI or insert data via Supabase Studio.
You'll have full access to delete data, access superadmin features, etc. But it's the SAME database -- there's no separate "local production" database.
- Discord: Join the MovaLab community
- GitHub Issues: Report bugs or request features
- Documentation: Check
CLAUDE.mdfor comprehensive technical docs