# Atlas

Composable Bun/TypeScript packages for building APIs, full-stack apps, and CLI tools.

[Documentation](https://wess.io/atlas/) · [API reference](https://wess.io/atlas/docs/api/) · [Quick start](https://wess.io/atlas/docs/quickstart/)

## What is Atlas

Atlas is an à la carte set of functional, minimal-dependency packages that snap together like Lego blocks. Pick what you need — config, database, HTTP server, auth, storage — and compose them into your app. Inspired by Elixir's ecosystem, idiomatic to TypeScript and Bun's native APIs.

No framework lock-in. No classes. Just functions and immutable data flowing through pipes.

## Install

```bash
bun add @wess/atlas
```

Every package is a subpath export, so you can import directly:

```ts
import { defineConfig, env } from "@wess/atlas/config"
import { connect } from "@wess/atlas/db"
import { serve, router, get, json } from "@wess/atlas/server"
```

Prefer the `@atlas/<pkg>` spelling used throughout these docs? Map it via
`tsconfig.json` `paths` (bun reads tsconfig paths at runtime):

```json
{
  "compilerOptions": {
    "paths": {
      "@atlas/auth":        ["./node_modules/@wess/atlas/packages/auth/index.ts"],
      "@atlas/auth/social": ["./node_modules/@wess/atlas/packages/auth/social/index.ts"],
      "@atlas/cache":       ["./node_modules/@wess/atlas/packages/cache/index.ts"],
      "@atlas/cli":         ["./node_modules/@wess/atlas/packages/cli/index.ts"],
      "@atlas/config":      ["./node_modules/@wess/atlas/packages/config/index.ts"],
      "@atlas/db":          ["./node_modules/@wess/atlas/packages/db/index.ts"],
      "@atlas/edge":        ["./node_modules/@wess/atlas/packages/edge/index.ts"],
      "@atlas/email":       ["./node_modules/@wess/atlas/packages/email/index.ts"],
      "@atlas/mcp":         ["./node_modules/@wess/atlas/packages/mcp/index.ts"],
      "@atlas/migrate":     ["./node_modules/@wess/atlas/packages/migrate/index.ts"],
      "@atlas/oauth":       ["./node_modules/@wess/atlas/packages/oauth/index.ts"],
      "@atlas/request":     ["./node_modules/@wess/atlas/packages/request/index.ts"],
      "@atlas/request/providers": ["./node_modules/@wess/atlas/packages/request/providers/index.ts"],
      "@atlas/security":    ["./node_modules/@wess/atlas/packages/security/index.ts"],
      "@atlas/server":      ["./node_modules/@wess/atlas/packages/server/index.ts"],
      "@atlas/server/ws":   ["./node_modules/@wess/atlas/packages/server/ws/index.ts"],
      "@atlas/server/sse":  ["./node_modules/@wess/atlas/packages/server/sse/index.ts"],
      "@atlas/share":       ["./node_modules/@wess/atlas/packages/share/index.ts"],
      "@atlas/sso":         ["./node_modules/@wess/atlas/packages/sso/index.ts"],
      "@atlas/storage":     ["./node_modules/@wess/atlas/packages/storage/index.ts"],
      "@atlas/ai":          ["./node_modules/@wess/atlas/packages/ai/index.ts"],
      "@atlas/admin":       ["./node_modules/@wess/atlas/packages/admin/index.ts"],
      "@atlas/ui":          ["./node_modules/@wess/atlas/packages/ui/index.ts"],
      "@atlas/ui/*":        ["./node_modules/@wess/atlas/packages/ui/*/index.tsx"]
    }
  }
}
```

Installing straight from the repo also works (`bun add github:wess/atlas`) and
lands in the same `node_modules/@wess/atlas/` location.

Bump atlas with `bun update @wess/atlas`.

## Packages

| Package | Description | External deps |
|---------|-------------|---|
| `@atlas/config` | Typed environment variables and config resolution | none |
| `@atlas/db` | Query builder, schemas, changesets, drivers (Postgres/SQLite) | `zod` |
| `@atlas/migrate` | Database migration manager | none |
| `@atlas/server` | Bun.serve with Plug-inspired pipe system | none |
| `@atlas/edge` | TLS-terminating reverse proxy with built-in Let's Encrypt | none |
| `@atlas/auth` | Password hashing, JWT, session management, auth flows | none |
| `@atlas/security` | CSP/headers, rate limit, audit log, TOTP, revocable DB-backed sessions | none |
| `@atlas/oauth` | OAuth 2.1 server: PKCE, refresh rotation, device flow, RFC 8414 discovery | none |
| `@atlas/sso` | OIDC relying-party (Sign in with $IdP): discovery, PKCE, state, code exchange, id_token verify | none |
| `@atlas/email` | Provider-agnostic transport (Resend) + invite/reset templates | none |
| `@atlas/share` | Share-URL builders (socials, messengers, mailto) + server-side share-by-email | none |
| `@atlas/storage` | S3-compatible object storage with presigned URLs | none |
| `@atlas/cache` | Redis-backed caching with TTL and cache-aside patterns | none |
| `@atlas/request` | HTTP client with retries, interceptors, provider configs | none |
| `@atlas/cli` | CLI framework and Foreman process manager | none |
| `@atlas/ui` | React + Mantine frontend blocks (forms, tables, auth UI) | `react`, `@mantine/*`, `@tanstack/*` |
| `@atlas/admin` | Django-style auto-generated admin panel | `react`, `@mantine/*`, `@tanstack/*` |
| `@atlas/mcp` | MCP server for AI/LLM debugging and introspection | none |
| `@atlas/ai` | AI providers, chat, embeddings, RAG, agents, streaming | none |

## Quick Start

Build a user API with authentication in 60 lines.

```bash
mkdir myapp && cd myapp
bun init -y
bun add @wess/atlas
```

The example below uses the `@atlas/<pkg>` aliases from the Install section.

Create `.env`:
```
DATABASE_URL="sqlite:./app.db"
PORT=3000
SECRET="your-secret-key-here"
```

Create `schema.ts`:
```ts
import { defineSchema, column } from "@atlas/db"

export const users = defineSchema("users", {
  id: column.serial().primaryKey(),
  email: column.text().unique(),
  passwordHash: column.text(),
  createdAt: column.timestamp().defaultRaw("CURRENT_TIMESTAMP"),
})
```

Create `server.ts`:
```ts
import { defineConfig, env } from "@atlas/config"
import { connect } from "@atlas/db"
import { migrate } from "@atlas/migrate"
import { serve, router, pipeline, parseJson, json, get, post } from "@atlas/server"
import { signup, login, requireAuth, token } from "@atlas/auth"

const config = defineConfig({
  database: env("DATABASE_URL"),
  port: env("PORT", { parse: Number, default: "3000" }),
  secret: env("SECRET"),
})

const db = connect({ driver: "sqlite", path: "./app.db" })
await migrate.up(db, "./migrations")

const api = pipeline(parseJson)

serve({
  port: config.port,
  routes: [
    post("/signup", api(
      signup({
        db,
        table: "users",
        fields: ["email", "password"],
        onSuccess: (c, user) => json(c, 201, { id: user.id, email: user.email }),
      })
    )),
    post("/login", api(
      login({
        db,
        table: "users",
        identity: "email",
        password: "password",
        onSuccess: async (c, user) =>
          json(c, 200, { token: await token.sign({ id: user.id }, config.secret) }),
      })
    )),
    get("/me", pipeline(requireAuth({ secret: config.secret }))(
      (c) => json(c, 200, { id: c.assigns.auth.id })
    )),
  ],
})
```

Run it:
```bash
bun server.ts
```

## Templates

Scaffold a new project with `atlas init --template <name>`:

| Template | Description |
|----------|-------------|
| `minimal` | Just server + config |
| `api` | REST API with db, auth, migrations |
| `edge` | App + TLS-terminating edge (replaces Caddy/nginx) |
| `fullstack` | API + React frontend |
| `admin` | API + admin panel |
| `worker` | Background job processor |
| `realtime` | WebSocket + SSE |
| `socialnetwork` | Users, posts, follows, likes, feeds, media, real-time |
| `cms` | Headless CMS with content types, publishing, webhooks |
| `ai` | Chatbot, RAG, agents, embeddings, streaming |

## Development

```bash
bun install
bun test
bun run lint
```

## For agents

Atlas exposes one canonical documentation set through four transports:

- [`llms.txt`](https://wess.io/atlas/llms.txt) — concise, specification-shaped discovery index.
- [`llms-full.txt`](https://wess.io/atlas/llms-full.txt) — the complete guide and package corpus.
- [Agent guide](https://wess.io/atlas/docs/agents/) — grounding order, imports, package selection, MCP safety, and context budgets.
- `packages/<name>/AGENTS.md` — canonical per-package APIs, also published as page-level Markdown.

Read them from the repository or installed package, run `atlas docs <name>`, or connect to
`atlas mcp` and call `docs.list` / `docs.read`. Every documentation page advertises its
Markdown alternate and the covering `llms.txt` index.

## Philosophy

- **Functional** — no classes, immutable data, composition over inheritance
- **Minimal deps** — wrap Bun's native APIs, not external packages
- **Composable** — each package works independently or with others
- **AI-friendly** — clear APIs, good types, predictable patterns
- **No framework lock-in** — use what you need, combine with anything else
- **Bun-native** — idiomatic to Bun's APIs and philosophy

## License

MIT

♥ [Sponsor this project](https://github.com/sponsors/wess)
