# §64 — The edge

TLS, certificates, and compression, without a Caddy sidecar and without a `nginx.conf` nobody on the team can read.

`@atlas/edge` terminates TLS, issues and renews Let's Encrypt certificates thirty days before expiry, and reverse-proxies to your app. In development with no `DOMAIN` set it detects localhost and serves plain HTTP on `:8080` — no certs, no sudo.

Use the staging directory for the first production boot. Let's Encrypt allows five failures per hostname per hour, and the fastest way to spend that budget is a typo in a DNS record. The browser will call staging certs untrusted; that is the point of them.

## What you are carrying

- `@atlas/edge` — TLS termination, ACME, proxying, compression.
- `@atlas/security` — Headers and rate limits at the boundary.

## Start it

```bash
atlas init -n myedge --template edge
```

## What it looks like

`edge.ts`

```ts
import { LETSENCRYPT_PROD, LETSENCRYPT_STAGING, defineEdge, proxy } from "@atlas/edge"

defineEdge({
  acme: process.env.ADMIN_EMAIL
    ? {
        email: process.env.ADMIN_EMAIL,
        storage: process.env.CERT_DIR ?? "/var/atlas/edge",
        // ACME_STAGING=1 on the first prod boot. Five failures an hour is
        // not many when a DNS record is wrong.
        directoryUrl: process.env.ACME_STAGING ? LETSENCRYPT_STAGING : LETSENCRYPT_PROD,
      }
    : undefined,
  sites: [{
    host: process.env.DOMAIN ?? "localhost",
    compress: ["gzip", "zstd"],
    routes: [{ handler: proxy("http://localhost:3000") }],
  }],
}).listen()
```

## Where now

- Put it online — turn to §100 (Appendix A)
- Hand it to an agent — turn to §102 (Appendix C)
- Walk it again from the start — turn to §1
