f07eddf29ef413b3f1b06b360436b42a3e3597f9
Fastify + Prisma backend, React + Vite frontend, Docker deployment. Multi-board feedback platform with anonymous cookie auth, passkey upgrade path, ALTCHA spam protection, plugin system, and full privacy-first architecture.
Echoboard
A self-hosted feedback board where users submit feature requests and bug reports without creating an account. Anonymous by default, with optional passkey registration for persistence across devices.
Quick start
git clone <repo-url>
cd echoboard
cp .env.example .env
# Generate secrets
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
# Paste output into APP_MASTER_KEY, APP_BLIND_INDEX_KEY, TOKEN_SECRET, JWT_SECRET, ALTCHA_HMAC_KEY
# Generate VAPID keys for push notifications
npx web-push generate-vapid-keys
# Paste into VAPID_PUBLIC_KEY and VAPID_PRIVATE_KEY
# Set WEBAUTHN_RP_ID and WEBAUTHN_ORIGIN to your domain
docker compose up -d
docker compose exec app npx echoboard create-admin --email you@example.com
Development
npm install
cp .env.example .env
# Fill in .env with dev values (WEBAUTHN_RP_ID=localhost, WEBAUTHN_ORIGIN=http://localhost:3000)
npm run dev
This starts the API on port 3000 and the Vite dev server on port 5173 (with API proxy).
Architecture
- packages/api - Fastify + Prisma backend
- packages/web - React + Vite frontend
- plugins/ - Optional integrations (Gitea, GitHub, etc.)
Identity model
Two tiers of user identity:
- Anonymous cookie (default) - zero friction, browser-generated token, single device only
- Passkey (optional upgrade) - username + WebAuthn biometric, works across devices, no email needed
Plugin system
Plugins live in plugins/ and are registered in echoboard.plugins.ts. Each plugin is self-contained with its own routes, database tables, and UI components. Removing a plugin leaves zero trace in the core app.
License
CC0-1.0
Description
Languages
TypeScript
97.1%
CSS
1.5%
JavaScript
1.1%
HTML
0.2%
Dockerfile
0.1%