You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Dispatch is a personal, locally-hosted web application for managing tasks, notes, projects, and daily workflows in a single unified interface. It is a private tool — built, hosted, and consumed by a single user on their local machine.
Core Principles
Local-first: Runs on localhost, data stays on disk in a SQLite file. No cloud dependency for data storage.
Single user, authenticated: OAuth2 login (GitHub) and local credentials gate access. Even though it's local, auth prevents accidental exposure if the port is reachable on the network.
REST API driven: The UI is a React SPA that communicates with Next.js API Route Handlers over standard REST (JSON request/response). No GraphQL.
Actionable assistant: Personal Assistant chat can invoke app actions through a local MCP (Model Context Protocol) server.
Simple and fast: SQLite for zero-ops persistence. No external database server to manage.
Tech Stack
Layer
Technology
Framework
Next.js 16.1.6 (App Router)
Language
TypeScript 5.9
UI
React 19, Tailwind CSS v4
Database
SQLite via better-sqlite3
ORM
Drizzle ORM 0.45
Authentication
NextAuth.js v5-beta (OAuth2 + Credentials)
AI
Vercel AI SDK (ai, @ai-sdk/*) + MCP
Runtime
Node.js
Testing
Vitest 4.0
Authentication
GitHub OAuth: Conditionally enabled when AUTH_GITHUB_ID and AUTH_GITHUB_SECRET env vars are set.
Local Credentials: Email/password registration and login via bcryptjs hashing. Registration endpoint at POST /api/auth/register.
Role-based administration: The first account created is automatically assigned the admin role.
Account freeze controls: Frozen accounts are blocked from sign-in and protected API access.
All API routes (except /api/auth/*) require a valid session.
The withAuth wrapper in src/lib/api.ts enforces this at the route level.
API Key Auth: Alternative authentication via Authorization: Bearer <key> or X-API-Key: <key> headers for programmatic access. Keys managed at /api/api-keys.
Sessions are JWT-based (required for Credentials provider compatibility with Drizzle adapter).
Custom sign-in page at /login.
Optional SQLCipher-backed at-rest database encryption is managed from the admin controls on /profile.
Data Model
Auth Tables
users — id, name, email (unique), emailVerified, image, password, role (member/admin), frozenAt?, showAdminQuickAccess, assistantEnabled. Supports both OAuth (image from provider) and credentials (password hash).
accounts — OAuth provider link records. Composite PK on provider + providerAccountId.
Local/credentials users display a user silhouette SVG icon as the fallback avatar (in both the sidebar and profile page).
Hosting
Runs locally via npm run dev during development.
npm run dev runs both Next.js and the MCP server concurrently.
Production mode via npm run build && npm run start for a more optimized local server.
No deployment target — this is a personal localhost application.
App version exposed via NEXT_PUBLIC_APP_VERSION from package.json.
Testing
Vitest for unit and integration tests, colocated with source under __tests__/ directories.
Test helpers provide in-memory SQLite database factory (src/test/db.ts) and auth mocking (src/test/setup.ts).
Tests mock @/auth for session control and @/db with an in-memory SQLite instance.
When appropriate, test with the chrome-devtools MCP for visual/interactive verification. Check to see if a dev server is already running before trying to start a new one.
Environment Variables (.env.local)
Variable
Purpose
AUTH_SECRET
NextAuth.js JWT signing secret
AUTH_GITHUB_ID
GitHub OAuth app client ID
AUTH_GITHUB_SECRET
GitHub OAuth app client secret
DISPATCH_SECURITY_CONFIG_PATH
Optional override for local encryption state file path