an app to share curated trails
TypeScript 82.8%
CSS 15.8%
JavaScript 1.4%
Other 0.1%
6 2 0

Clone this repository

https://tangled.org/thisismissem.social/sidetrail
git@tangled.org:thisismissem.social/sidetrail

For self-hosted knots, clone URLs may differ based on your setup.

README.md

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 URL
  • PRIVATE_KEY_ES256 - OAuth signing key (generate with node scripts/gen-jwk.mjs)
  • COOKIE_SECRET - Session encryption (32+ chars)

Lexicons#

Sidetrail uses three ATProto record types:

  • app.sidetrail.trail - Trail with embedded stops
  • app.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