Exosphere is a set of small, modular, self-hostable community tools built on the AT Protocol. app.exosphere.site
6
fork

Configure Feed

Select the types of activity you want to include in your feed.

Exosphere#

Modular, self-hostable community platform built on the AT Protocol.

Tools#

  • Runtime & package manager: Bun (workspaces monorepo)
  • Backend: Hono.js on Bun, SQLite via bun:sqlite
  • Frontend: Preact + Preact Signals, vanilla-extract for styling, Vite for dev/build
  • Auth: AT Protocol OAuth (@atproto/* packages)
  • Validation: Zod at system boundaries
  • Language: TypeScript (strict mode)
  • Dev PDS: Docker Compose (docker-compose.dev.yml) runs a local Bluesky PDS

Commands#

  • bunx run check: (or vp check) Check project lints, tpyes, format
  • bun run test: (or vp test) Run unit tests
  • bun run test:e2e: Run end-to-end tests

Architecture#

Monorepo with Bun workspaces under packages/:

Package Role
core Shared infra: auth, db, sphere management, types
client Shared client-side utilities: API helpers, auth, router, theme, UI styles, reusable components
app Host app — assembles modules, Hono server entry (src/server.ts), Preact client entry (src/client.tsx)
feeds Feed & discussions module
feature-requests Feature requests module

Each module exposes: a Hono sub-app (API routes), Preact components (UI), its own SQLite migrations, and a ExosphereModule interface. Modules depend on core but not on each other.

The app package registers modules in src/server.ts by mounting their API routes under /api/<module-name>.

See ARCHITECTURE.md for full details on data flow, AT Protocol integration, membership model, and access modes.

Lexicons#

The project lexicons are located in ../landing and hosted on tangled: https://tangled.org/exosphere.site/landing.

TS/TSX coding style#

  • Strong typing and type safety
  • Avoid barrel files when possible
  • We are using Preact, in JSX, prefer class over className
  • Make optimistic updates when possible

Styling#

  • No universal box-sizing: border-box — let elements use the default content-box. Only apply border-box on specific elements that need it (e.g. form controls with width: 100%).
  • Prefer CSS logical properties for margins, paddings, and borders (margin-inline, padding-block, border-inline-start, etc.) over physical properties (margin-left, padding-top, etc.).
  • Prefer modern CSS — use contemporary features and patterns over legacy approaches.
  • Avoid inline styling, prefer re-usable components from ./packages/client