Sidetrail#
Sidetrail is an app to create and share "trails". Create sequential paths with 2-12 stops, walk through them one step at a time, and share them with others.
Built on AT protocol: trails, walks, and completions are stored in users' repositories and synced via Jetstream.
Architecture#
Three services:
- Next.js app — Web frontend + API. Reads from PostgreSQL, writes to users' ATProto repos via OAuth.
- Ingester — Subscribes to Jetstream and indexes
app.sidetrail.*records into PostgreSQL. - Realtime — Rebroadcasts Jetstream events to browser clients for real-time updates on some pages.
Local Development#
Prerequisites#
- Node.js 22.16.0+
- PostgreSQL
- Redis
Setup#
# Install dependencies
npm install
# Copy environment file and configure DATABASE_URL and REDIS_URL
cp .env.example .env
# Push database schema
npm run db:push
# Start all services (run in separate terminals)
npm run dev # Next.js app on :3000
npm run dev:ingester # Jetstream ingester
npm run dev:realtime # Realtime server
Then open 127.0.0.1:300 (it has to be 127.0.0.1, not localhost).
Environment Variables#
See .env.example. For local development, DATABASE_URL and REDIS_URL are required.
Production requires:
PUBLIC_URL- Your app's public URLPRIVATE_KEY_ES256- OAuth signing key (generate withnode scripts/gen-jwk.mjs)COOKIE_SECRET- Session encryption (32+ chars)
Lexicons#
Sidetrail uses three ATProto record types:
app.sidetrail.trail- Trail with embedded stopsapp.sidetrail.walk- User's current walk state (deleted on completion)app.sidetrail.completion- Permanent completion record
See lexicons/LEXICONS.md for details.
Testing#
# Create test database (one-time)
psql -c "CREATE DATABASE sidetrail_test"
npm test
Scripts#
npm run dev # Start Next.js dev server
npm run dev:ingester # Start Jetstream ingester
npm run dev:realtime # Start realtime server
npm run build # Production build
npm run db:push # Push schema to database
npm run db:studio # Open Drizzle Studio
npm run test # Run tests
npm run check # Lint + typecheck
Deployment#
Uses Railway with three services. Deploy with:
npm run deploy:app
npm run deploy:ingester
npm run deploy:realtime
License#
MIT