Help
Self-host Shortener.dev on Cloudflare
Run your own copy of the open-source Shortener.dev URL shortener on Cloudflare Workers with D1, KV and R2, on your own short domain.
Updated
Shortener.dev is open source under the AGPLv3, and the repository has everything that runs shortener.dev: the API, the dashboard and the website. You can run your own copy on your Cloudflare account and serve short links from your own domain.
Self-hosting makes sense if you want short links on your own domain, need data to stay in your Cloudflare account, or want to change how the shortener works. If you just want short links, the hosted version at shortener.dev is less work.
What runs where
| App | What it is | Runs on |
|---|---|---|
apps/api | REST API, and the short link redirects | Cloudflare Workers with Hono |
apps/app | Dashboard | Static assets on Cloudflare Workers |
apps/web | Website and docs (optional) | Cloudflare Workers |
The API Worker also serves the short links. Any request for a path like /spring-sale that isn't an API route is treated as a short link, so your short domain points at the same Worker as the API.
It uses these Cloudflare products: D1 for the database, two KV namespaces (cache and short link lookups), R2 for uploaded images, a Queue, Analytics Engine for clicks and request logs, rate limiting, and Email for verification codes. Check Cloudflare's pricing for the ones your account plan includes.
Run it locally
You need Node.js 24 or later and a Cloudflare account.
git clone https://github.com/Agenty/shortener.git
cd shortener
npm install
Create apps/api/.dev.vars with at least:
ENVIRONMENT=development
JWT_SECRET=a-long-random-string
APP_URL=http://localhost:5173
API_URL=http://localhost:8787
DOMAIN=localhost
Create the local database and start everything:
cd apps/api && npm run sql:dev && cd ../..
npm run dev
The API runs on http://localhost:8787, the dashboard on http://localhost:5173 and the website on http://localhost:3000. The API README lists the optional variables for Google and GitHub sign-in, Search Console verification, analytics and Stripe.
Deploy to Cloudflare
-
Create the resources from
apps/api:npx wrangler login npx wrangler d1 create shortener npx wrangler kv namespace create KVCACHE npx wrangler kv namespace create LINKS npx wrangler r2 bucket create shortener npx wrangler queues create shortener-queue -
Copy the D1
database_idand both KVidvalues intoapps/api/wrangler.json, in the top-level config and in thepreviewsblock. The file in the repository points to the shortener.dev resources, so every ID has to be replaced. -
Create the production tables with
npm run sql. -
Add each value from
.dev.varsas a secret with production URLs, for examplenpx wrangler secret put JWT_SECRET. -
Deploy the API with
npm run deployinapps/api, and the dashboard withnpm run build && npx wrangler deployinapps/app.
Use your own short domain
- In the Cloudflare dashboard, add two custom domains to the API Worker: one for the API, such as
api.example.com, and your short domain, such asgo.example.com. - Set
SHORT_DOMAINinapps/api/services/links.service.tsand inapps/app/src/env.tsto your short domain. - Update the API URL in
apps/app/src/env.ts, and inapps/web/src/lib/site.tsif you deploy the website. - Deploy again.
New links are returned as https://go.example.com/your-back-half.
Keep the safety checks on
The API only creates links to verified or whitelisted domains and refuses blocked ones. The check is assertVerifiedDestinations in apps/api/services/domain.service.ts. Leave it on: without it, anyone with an account on your instance can create links to phishing pages on your domain, and your short domain ends up on browser and email blocklists. See Is srt1.link safe? for what the checks do.
License
The AGPLv3 requires you to share your changes when you run a modified version as a public service. For a commercial license or help with a self-hosted setup, contact us.