pR1 - Pretty-fast serverless URL shortener built on Cloudflare Workers. Zero runtime dependencies, real-time analytics, automatic QR code generation, and optimized for the free tier.
First project I've developed with 100% just dictation and claude code (due to recovering from a shoulder surgery and unable to type properly)
- Pretty Fast - Edge computing with Cloudflare Workers
- Real-time Analytics - Track visits, locations, devices, and more
- QR Codes - Automatic generation for all short URLs
- Self-Service Editing - Edit tokens for public URL management
- Free Tier Optimised - Handle 2,500-3,000 redirects/day on free tier
# 1. Clone and install
git clone https://github.com/zephrfish/pR1.git
cd pR1
npm install
# 2. Login to Cloudflare
npx wrangler login
# 3. Create KV namespaces
npx wrangler kv:namespace create "URL_STORE"
npx wrangler kv:namespace create "ANALYTICS"
npx wrangler kv:namespace create "URL_STORE" --preview
npx wrangler kv:namespace create "ANALYTICS" --preview
# 4. Configure wrangler.toml
cp wrangler.toml.example wrangler.toml
# Edit wrangler.toml with your KV IDs and domain
# 5. Set admin password
npx wrangler secret put ADMIN_PASSWORD
# Enter a strong password (12+ chars, mixed case, numbers, special chars)
# 6. Deploy
npm run deployVisit your domain and start creating short URLs!
- Node.js 18 or higher
- Cloudflare Account (free tier works perfectly)
- Custom Domain added to Cloudflare
- Cloudflare API Token with permissions:
- Account > Workers KV Storage > Edit
- Account > Workers Scripts > Edit
- Zone > Workers Routes > Edit
- Visit Cloudflare API Tokens
- Click "Create Token" → "Create Custom Token"
- Set permissions:
- Account | Workers KV Storage | Edit
- Account | Workers Scripts | Edit
- Zone | Workers Routes | Edit
- Set Zone Resources to include your domain
- Save token securely
name = "pR1"
main = "src/index.js"
compatibility_date = "2024-11-01"
routes = [
{ pattern = "yourdomaingoeshere/*", zone_name = "yourdomaingoeshere" }
]
[[kv_namespaces]]
binding = "URL_STORE"
id = "your_url_store_id_here"
preview_id = "your_preview_id_here"
[[kv_namespaces]]
binding = "ANALYTICS"
id = "your_analytics_id_here"
preview_id = "your_preview_id_here"
[vars]
DOMAIN = "yourdomaingoeshere"
ALLOW_HTTP = "true" # Allow HTTP URLs (set false for production)
ALLOW_PRIVATE_IPS = "true" # Allow private IPs (set false for production)# Set admin password (required)
npx wrangler secret put ADMIN_PASSWORD
# Password requirements:
# - Minimum 12 characters
# - Uppercase and lowercase letters
# - Numbers and special characters- Go to Cloudflare Dashboard → DNS
- Add A record:
- Type: A
- Name: @ (root domain)
- IPv4: 192.0.2.1 (placeholder)
- Proxy: Enabled (orange cloud) - Required
- Visit your domain (e.g.,
https://yourdomaingoeshere) - Enter a long URL
- Optional: Custom short code or expiration
- Click "Create Short URL"
- QR code automatically appears - scan or download
- Copy, download QR, or share
- Use edit token to manage your URL later
- Click "Login" button
- Enter admin password
- View all URLs with analytics
- Edit, delete, or view detailed analytics
- Access global analytics dashboard
- Generate QR codes for any URL
curl -X POST https://yourdomaingoeshere/api/create \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/very/long/url",
"shortCode": "mylink",
"expiresIn": 86400
}'Response:
{
"success": true,
"shortUrl": "https://yourdomaingoeshere/mylink",
"shortCode": "mylink",
"expiresAt": "2025-01-20T12:00:00.000Z",
"editToken": "abc123...",
"editUrl": "https://yourdomaingoeshere/e/abc123..."
}curl https://yourdomaingoeshere/api/urls \
-H "Authorization: Bearer your_admin_password"curl https://yourdomaingoeshere/api/analytics/mylink \
-H "Authorization: Bearer your_admin_password"Response includes:
- Total visits (human vs bot)
- Unique visitors and sessions
- Geographic data (country, city, timezone)
- Technology data (browser, OS, device)
- Traffic sources (referrers, UTM parameters)
- Network information (ASN, data center)
# With admin password
curl -X PUT https://yourdomaingoeshere/api/update/mylink \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your_admin_password" \
-d '{"url": "https://example.com/new-destination"}'
# With edit token (public)
curl -X PUT https://yourdomaingoeshere/api/url/EDIT_TOKEN \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/new-destination"}'# With admin password
curl -X DELETE https://yourdomaingoeshere/api/delete/mylink \
-H "Authorization: Bearer your_admin_password"
# With edit token (public)
curl -X DELETE https://yourdomaingoeshere/api/url/EDIT_TOKENcurl https://yourdomaingoeshere/api/stats┌─────────────────┐
│ Browser │
└────────┬────────┘
│ HTTPS
↓
┌───────────────────────────┐
│ Cloudflare Workers │
│ (Edge Computing) │
│ ┌────────────────────┐ │
│ │ src/index.js │ │
│ │ - Routing │ │
│ │ - Security │ │
│ │ - Rate Limiting │ │
│ │ - API Handlers │ │
│ └────────────────────┘ │
│ ┌────────────────────┐ │
│ │ src/html.js │ │
│ │ - UI Templates │ │
│ │ - QR Generation │ │
│ │ - Themes │ │
│ └────────────────────┘ │
│ ┌────────────────────┐ │
│ │ src/sw.js │ │
│ │ - Service Worker │ │
│ │ - Offline Support │ │
│ └────────────────────┘ │
└───────────┬───────────────┘
│
┌─────┴──────┐
↓ ↓
┌──────────┐ ┌──────────┐
│URL_STORE │ │ANALYTICS │
│ KV │ │ KV │
└──────────┘ └──────────┘
pR1 is heavily optimized to maximize usage on Cloudflare's free tier:
- Detailed Analytics: 2% sample rate (1 in 50 visits)
- Visit Counters: 5% sample rate (1 in 20 visits)
- Statistical Accuracy: Estimates are statistically valid
- Before: 2 writes per redirect (1000 redirects = 2000 writes )
- After: 0.07 writes per redirect (1000 redirects = 70 writes )
- Reduction: 96.5% fewer writes
- ~2,500-3,000 redirects/day (was ~500 before optimization)
- Unlimited homepage visits (no KV writes)
- ~200 new URLs/day
# Start dev server
npm run dev
# Access at http://localhost:8787
# View logs in real-time
npx wrangler tail# Create test URL
curl -X POST http://localhost:8787/api/create \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "shortCode": "test"}'
# Test redirect
curl -I http://localhost:8787/test
# Run unit tests
npm test# View logs
npx wrangler tail
# Check deployment
npx wrangler whoami
npx wrangler deployments list
# List KV namespaces
npx wrangler kv:namespace list
# Inspect KV keys
npx wrangler kv:key list --namespace-id YOUR_IDRuns entirely on Cloudflare Free Tier:
| Resource | Free Tier Limit | pR1 Usage (Optimized) | Status |
|---|---|---|---|
| Workers Requests | 100,000/day | ~3,000/day | 3% |
| KV Reads | 100,000/day | ~3,000/day | 3% |
| KV Writes | 1,000/day | ~210/day | 21% |
| KV Storage | 1 GB | <1 MB | <0.1% |
| Bandwidth | Unlimited | Free | Free |