Running your own
The app is Next.js on Vercel, MongoDB Atlas, Auth.js with Google, Stripe, and Anthropic. Nothing here is required to use rewr.it — this is for running it.
Local
npm install
cp .env.example .env.local
npm run dev
Then, once against a fresh database:
npm run db:indexes
Environment
| Variable | Purpose |
|---|---|
ANTHROPIC_API_KEY | Server-only rewrite key |
ANTHROPIC_MODEL_STANDARD / ANTHROPIC_MODEL_FAST | Model ids behind the product's tiers |
MONGODB_URI | Atlas connection string |
AUTH_SECRET | Auth.js secret |
AUTH_GOOGLE_ID / AUTH_GOOGLE_SECRET | Google OAuth |
DEVICE_COOKIE_SECRET | Signs the anonymous device cookie |
STRIPE_SECRET_KEY / STRIPE_WEBHOOK_SECRET / STRIPE_PRICE_PRO | Billing and the Pro subscription |
STRIPE_PRICE_CREDITS_MINI / _STARTER / _POPULAR / _POWER | One-time credit lots |
STRIPE_AUTOMATIC_TAX | Turn on only after Tax is set up and registrations are active |
NEXT_PUBLIC_APP_URL | Canonical site URL. Checkout and Portal returns, CORS, and metadataBase |
DAILY_SPEND_CAP_USD | App-wide daily spend breaker. Default 50 |
CRON_SECRET | Bearer token for /api/cron/reconcile |
HUMANIZE_DISABLED | Kill switch. true makes the rewrite endpoint return 503 |
DETECT_DISABLED | Same, for /api/detect |
HUMANIZER_EXTENSION_IDS | Comma-separated extension ids allowed through CORS in production |
HUMANIZER_CORS_ORIGINS | Extra allowed origins, comma-separated |
ADMIN_EMAILS | Allowlist for /admin. Unset disables admin entirely |
UNLIMITED_EMAILS | Accounts whose period caps are lifted. Word caps and the spend cap still apply |
NEXT_PUBLIC_LEGAL_ENTITY | Entity named on /terms and /privacy |
NEXT_PUBLIC_LEGAL_JURISDICTION | Governing law for /terms |
NEXT_PUBLIC_LEGAL_CONTACT_EMAIL | Where legal and privacy requests go |
NEXT_PUBLIC_APP_URLNext resolves every Open Graph URL against metadataBase, which comes from this.
A production build still pointing at localhost has broken link previews
everywhere and nothing that says so.
The switches that matter under load
DAILY_SPEND_CAP_USD— a breaker, not a budget. When it trips, rewrites return503withcode: "spend_cap"and no request reaches Anthropic.HUMANIZE_DISABLED— the kill switch.503,code: "kill_switch", instantly, for everyone.- Per-plan concurrency and burst limits live in
lib/plans.ts, not in env. They are code because they are entitlements.
The tell policy
Thresholds, vocabulary, and pattern rules are editable at /admin/policy and
served to clients by GET /api/policy. Clients ship with the defaults, so the
detector works before the fetch lands and keeps working if it fails.
Changing the policy changes what every client flags and what the score means. There is one copy for exactly that reason.
These docs
The documentation site is a Docusaurus build in docs-site/, separate from the
Next app — separate package.json, separate build, no shared imports.
cd docs-site
npm install
npm start # dev server
npm run build # static site into docs-site/build
The look comes from docs-site/src/css/custom.css, which mirrors the tokens in
docs/BRAND.md. If a colour or a face changes, it changes in the brand doc and
in lib/theme.ts first, and this stylesheet follows.