Open-source monorepo for Human Browser: a Turborepo workspace with a Next.js app that can receive inbound email via Resend webhooks.
GitHub: github.com/syd-shields/human-browser
| Path | Description |
|---|---|
apps/web |
Next.js 15 app (App Router, TypeScript, Tailwind). Includes POST /api/webhooks/resend for verified email.received events, scoped to upload@humanbrowser.com. |
packages/ui |
Shared React component library (@repo/ui). |
packages/eslint-config |
Shared ESLint config (@repo/eslint-config). |
packages/typescript-config |
Shared TypeScript bases (@repo/typescript-config). |
Inbound email flow is described in Receiving emails. Webhook payloads are metadata-only; use the Received Email API to load bodies and attachments.
pnpm install
pnpm devRun only the web app:
pnpm exec turbo run dev --filter=webOpen http://localhost:3000.
| Script | Purpose |
|---|---|
pnpm dev |
Dev servers for workspace apps |
pnpm build |
Production build via Turbo |
pnpm lint |
ESLint across packages |
pnpm format |
Prettier write (*.ts, *.tsx, *.md) |
pnpm format:check |
Prettier check (used in CI) |
pnpm check-types |
TypeScript tsc --noEmit via Turbo |
Copy apps/web/.env.example to apps/web/.env.local for local development.
| Variable | Required for webhook | Description |
|---|---|---|
RESEND_WEBHOOK_SECRET |
Yes | Signing secret from Resend → Webhooks (verify requests per Verify webhooks). |
RESEND_UPLOAD_INBOX |
No | Address matched against data.to (defaults to upload@humanbrowser.com). |
Set the same variable in Vercel Project → Settings → Environment Variables for Production and Preview so preview deployments can verify webhooks if you test against them.
Do not commit .env or .env.local; they are gitignored.
Workflow: .github/workflows/ci.yml
On every push and pull request to main, Quality runs:
pnpm install --frozen-lockfilepnpm format:checkpnpm lintpnpm check-typespnpm build
Dependabot is configured in .github/dependabot.yml for npm and GitHub Actions.
The project is set up so Vercel can build the Next app from the monorepo root using Turbo.
- In Vercel, open the human-browser project.
- Settings → Git → connect github.com/syd-shields/human-browser (install the Vercel GitHub app if prompted).
- Settings → General → Root Directory → set to
apps/web.
This makes Vercel treat the Next.js app as the app root whileapps/web/vercel.jsonruns install/build from the repo root (pnpm install+turbo run build --filter=web). - Production Branch →
main(default). Pushes tomaindeploy to Production. - Settings → Domains → add
dev.humanbrowser.comand assign it to Production (follow DNS instructions Vercel shows for your DNS provider). - Settings → Environment Variables → add
RESEND_WEBHOOK_SECRETfor Production (and Preview if needed).
With the GitHub integration enabled, every pull request gets a Preview deployment automatically. No extra workflow is required for preview URLs.
Optional hardening:
- Settings → Deployment Protection → enable protection for Preview (e.g. Vercel Authentication or password) if you want previews not to be public.
- Settings → Git → enable “Ignored Build Step” or Turborepo remote caching if the repo grows and you want faster builds.
Point your Resend webhook at:
https://dev.humanbrowser.com/api/webhooks/resend
Subscribe to email.received. Use the signing secret as RESEND_WEBHOOK_SECRET in Vercel.
For local testing, use a tunnel (e.g. ngrok) as in Receiving emails.
After at least one successful CI run on main (so the check name appears in the UI):
- Repo → Settings → Rules → Rulesets (or Branches → Branch protection rules).
- Protect
mainwith:- Require a pull request before merging (optional but typical for OSS).
- Require status checks to pass → add Quality (or CI / Quality, depending on how GitHub lists it).
- Optionally Require branches to be up to date before merging.
If you use Rulesets, add a rule targeting main and under Require status checks select the check that matches the Quality job from this repo’s CI workflow.
The remote human-browser already exists:
https://github.com/syd-shields/human-browser.git
To push your current branch:
git push -u origin mainTo create a new empty repo under another org or name in the future:
gh repo create <owner>/<name> --public --source=. --remote=origin --pushMIT.