# 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/`. 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