mirror your GitHub repos to tangled.org automatically
1

Configure Feed

Select the types of activity you want to include in your feed.

30 1 0

Clone this repository

https://tangled.org/danielroe.dev/synchub.to https://tangled.org/did:plc:g4lh56ouiwlcyhukzkjvy75g
git@tangled.org:danielroe.dev/synchub.to git@tangled.org:did:plc:g4lh56ouiwlcyhukzkjvy75g

For self-hosted knots, clone URLs may differ based on your setup.



README.md

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.

  1. Apply migrations against your production database:
    NUXT_DATABASE_URL="<pooled neon connection string>" pnpm db:migrate
    
  2. Import the repo into Vercel (the Nuxt preset is auto-detected) and set every variable from .env.example under 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.
  3. Set NUXT_PUBLIC_URL to your real origin and point the GitHub App webhook at https://<your-domain>/api/github/webhook.
  4. 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.