synchub.to#
mirror your GitHub repos to tangled.org, automatically.
Install the GitHub App, connect your tangled identity, and every commit, branch, and tag will be mirrored to tangled. No additional configuration required.
Features#
- no workflow file required
- one-time OAuth connection to tangled
- per-push sync of branches and tags
- a dashboard where you can resync, pause, or rotate keys
IMPORTANT
Only public repositories are synced (tangled does not yet support private repositories).
Run it locally#
You will need Node 24+, pnpm 10+
(corepack enable), a Neon database (free tier is fine),
and the Smee CLI for webhook proxying
(pnpm add -g smee-client).
corepack enable
pnpm install
cp .env.example .env # fill in the values, see below
pnpm db:migrate
pnpm dev
.env.example documents every variable. Generate the secrets with the bundled
helpers:
pnpm gen:jwk # NUXT_ATPROTO_PRIVATE_JWK
pnpm gen:encryption-key # NUXT_ENCRYPTION_KEY and NUXT_SESSION_PASSWORD
pnpm gen:cron-secret # NUXT_CRON_SECRET
The rest (NUXT_DATABASE_URL, the NUXT_GITHUB_APP_* values) come from your
Neon dashboard and a new GitHub App.
The App needs contents:read and metadata:read permissions plus the push,
create, delete, and repository events, with its webhook pointed at your
Smee URL.
In separate terminals, proxy webhooks and drain the job queue:
smee --url <your-smee-url> --target http://127.0.0.1:3000/api/github/webhook
pnpm jobs:tick # run as needed; in production Vercel Cron does this
Deploy to Vercel#
synchub.to runs on Vercel with a Neon Postgres database.
- Apply migrations against your production database:
NUXT_DATABASE_URL="<pooled neon connection string>" pnpm db:migrate - Import the repo into Vercel (the Nuxt preset is auto-detected) and set every
variable from
.env.exampleunder Settings > Environment Variables. Mark the secrets (NUXT_DATABASE_URL,NUXT_GITHUB_APP_PRIVATE_KEY,NUXT_ATPROTO_PRIVATE_JWK,NUXT_ENCRYPTION_KEY,NUXT_SESSION_PASSWORD,NUXT_GITHUB_WEBHOOK_SECRET,NUXT_CRON_SECRET) as Sensitive. - Set
NUXT_PUBLIC_URLto your real origin and point the GitHub App webhook athttps://<your-domain>/api/github/webhook. - Deploy.
The worker runs on a Vercel Cron (declared in nuxt.config.ts, so no
vercel.json is needed) and appears under Settings > Cron Jobs after the
first deploy.
NOTE
The GitHub App private key is multi-line, but Vercel env values are single
line. Collapse the newlines to literal \n before pasting:
awk 'NF {printf "%s\\n", $0}' your-app.private-key.pem
Locally, keep the real newlines as shown in .env.example. Migrations are
manual: re-run pnpm db:migrate against production whenever you ship a
schema change.
License#
Made with ❤️
Published under MIT License.