Cloudflare Worker CDN for image delivery and on-the-fly transformation.
Serves assets from R2 with Cloudflare Image Transformations, cache-aside
caching, CORS, rate limiting, and security headers.
Official Site Β· Blog Β· WolfStar Invite Link Β· Support Server Β· Feedback
Table of contents
- β¨ Features
- π Requirements
- π³ Getting Started
- π¦ Usage
- β¨οΈ Local Development
- π» Online Development
- π€ Contributing
- β€οΈ Sponsor
WolfStar CDN is a Cloudflare Worker that serves and transforms images from R2 storage for the WolfStar Network. Built with Nitro v3 and TypeScript, it prioritizes stability, speed, and security.
- R2 Asset Delivery: Serve objects directly from Cloudflare R2 with immutable long-lived cache headers.
- On-the-fly Image Transformations: Resize, reformat, and adjust quality via query parameters using Cloudflare Image Transformations.
- Cache-aside Caching: HIT/MISS path via the Cloudflare Cache API with
X-Cache-Statusheaders. - CORS: Dynamic origin validation from an allowlist of trusted origins.
- Rate Limiting: 20 requests per 60 seconds per IP via Cloudflare Rate Limit binding.
- Security Headers:
X-Content-Type-Options,X-Frame-Options, andX-XSS-Protectionon every response. - Range Requests: Partial content (
bytes=) support for large assets (mutually exclusive with image transforms). - Health Check: Lightweight
/healthendpoint for uptime monitoring. - Structured Logging: Wide-event request logs via
evlog.
- Node.js: 22+ (LTS)
- pnpm: 10+ (required β not npm or yarn)
- Wrangler: 4+ (Cloudflare CLI)
- Cloudflare account: With R2 storage enabled and Image Transformations available for transform routes
-
Clone the repository
git clone https://github.com/wolfstar-project/cdn.git cd cdn -
Install dependencies
pnpm install
-
Configure Cloudflare bindings
Open
wrangler.jsoncand update the required values:Binding Kind Description wolfstar_cdnR2Bucket Primary asset storage RATE_LIMITERRateLimit 20 requests per 60 s per IP ALLOWED_ORIGINSenv var Comma-separated list of allowed origins R2_WORKER_URLenv var Base URL used when constructing fetches Note Secrets must be added via
wrangler secret put <NAME>and must never be committed to the repository. -
Start the development server
pnpm dev
Note The Cloudflare Cache API (
caches.default) and rate limiting bindings are only available inside the Cloudflare Workers runtime. Some features will be skipped or no-op locally.
pnpm devβ Start Nitro dev server (local Workers emulation)pnpm buildβ Production build via Vite + Nitropnpm deployβ Deploy prebuilt output via Wranglerpnpm previewβ Preview the production build locallypnpm lintβ Run Oxlint + Oxfmt check (no auto-fix)pnpm lint:fixβ Run Oxlint & Oxfmt and fix issuespnpm typecheckβ Type-check withtsc --noEmit(must pass with zero errors)
nitro.config.ts -- Nitro config (preset, cloudflare bindings)
vite.config.ts -- Vite config (nitro plugin)
wrangler.jsonc -- Wrangler deployment and bindings configuration
server/
error.ts -- Global error handler
middleware/
01.cors.ts -- CORS middleware (dynamic origin validation)
02.rate-limiter.ts -- Rate limiting (20 req/60s)
03.cache.ts -- Cache-read middleware (HIT path)
plugins/
security-headers.ts -- Security headers
cache-writer.ts -- Cache-write plugin (MISS path)
routes/
health.get.ts -- Health check endpoint
[...path].ts -- Catch-all CDN route
utils/
types.ts -- Type definitions
constants.ts -- Image extensions, dimension limits, cache TTL
errors.ts -- Error response factory
blob.ts -- Blob/R2 utilities (fetch, transform, range, parse)
- Nitro v3 β Cloudflare Workers server runtime
- TypeScript β Type safety
- Vite β Build tooling
- Wrangler β Cloudflare Workers CLI
- Oxlint β Code linting
- Oxfmt β Code formatting
- evlog β Structured wide-event logging
- @vite-hub/blob β R2 blob storage abstraction
GET /path/to/image.pngTransformations apply when the file extension is an image
(jpg, jpeg, png, gif, webp, svg, tiff, avif) and at least one
transform parameter is present.
| Param | Description | Valid values |
|---|---|---|
w |
Width | 1β4096 |
h |
Height | 1β4096 |
q |
Quality (default 85) |
1β100 |
fit |
Resize fit mode | scale-down, contain, cover, crop, pad |
f |
Output format | webp, avif, jpeg, png |
GET /avatars/user.png?w=256&h=256&fit=cover&f=webp&q=80Range requests and image transformations are mutually exclusive. Combining both returns
400.
GET /healthReturns JSON with worker status, timestamp, and Cloudflare region.
Refer to CONTRIBUTING.md for detailed setup instructions, code style, and the pull request process.
Before committing:
pnpm buildβ must build successfullypnpm lint:fixβ fix lint and format issuespnpm typecheckβ must pass with zero type errors- Commit messages must follow Conventional Commits
Click any of the buttons below to start a new development environment to demo or contribute to the codebase without having to install anything on your machine:
Thank you to all the people who already contributed to WolfStar CDN! Please make sure to read the Contributing Guide before making a pull request.
If you like WolfStar and want to support the project, consider making a donation. Every contribution helps to maintain and improve the network.
Thank you for your support!