Bunny.net Edge Scripting
Bundle your hadars app into a single self-contained edge script and deploy to bunny.net's global CDN network. SSR runs in the script; JS, CSS, and other static assets are served from bunny.net Storage.
How it works
hadars export bunny runs your production build and then uses esbuild to bundle the SSR module, HTML template, and all runtime dependencies into a single bunny.mjs. Bunny.net edge scripts run on Deno + V8 and use the standard Web Request / Response API — no event format conversion is needed.
1 — Bundle the edge script
Run this from your project root. It builds the app first, then produces bunny.mjs in the same directory.
hadars export bunny
# Custom output path
hadars export bunny dist/script.mjsThe command runs hadars build, writes a temporary entry shim that statically imports the SSR module and HTML template, then bundles everything with esbuild (platform: browser, format: esm, target: es2022). The @bunny.net/edgescript-sdk is marked external — it is always available in the bunny.net Deno runtime and must not be bundled.
2 — Upload static assets to Storage
Build artifacts in .hadars/static/ are content-hashed and safe to cache indefinitely. Your own files in static/ use a shorter TTL. Skip out.html — that's the SSR template used by the script at runtime, not a public file.
# Upload build output via the bunny.net Storage API or dashboard
# Content-hashed filenames are safe for indefinite caching
curl -X PUT "https://storage.bunnycdn.com/my-zone/.hadars/static/" \
-H "AccessKey: $BUNNY_STORAGE_KEY" \
--data-binary @.hadars/static/
# Or use the bunny.net CLI / dashboard file manager to upload
# the contents of .hadars/static/ and static/ to your storage zone.Connect the storage zone to a pull zone (CDN) and configure it to serve requests for static file extensions (*.js, *.css, *.woff2, etc.) while routing all other requests to the edge script.
3 — Create the edge script
- In the bunny.net dashboard, go to Edge Platform › Scripting and click Add Script.
- Select Standalone as the script type.
- Paste the contents of
bunny.mjsinto the editor (or connect your GitHub repository for CI/CD). - Click Save and Publish.
Manual entry shim
hadars export bunny generates and bundles an entry shim automatically. If you prefer to manage the bundling step yourself, write the shim by hand:
// script.ts — your Bunny edge script entry point
import * as BunnySDK from "@bunny.net/edgescript-sdk";
import * as ssrModule from './.hadars/index.ssr.js';
import outHtml from './.hadars/static/out.html';
import { createBunnyHandler } from 'hadars/bunny';
import config from './hadars.config';
BunnySDK.net.http.serve(createBunnyHandler(config, { ssrModule, outHtml }));Then bundle it yourself:
esbuild script.ts \
--bundle \
--platform=browser \
--format=esm \
--target=es2022 \
--outfile=bunny.mjs \
--loader:.html=text \
--external:@rspack/* \
--external:@bunny.net/edgescript-sdkcreateBunnyHandler API
import { createBunnyHandler, type BunnyBundled } from 'hadars/bunny';
import * as BunnySDK from "@bunny.net/edgescript-sdk";
import * as ssrModule from './.hadars/index.ssr.js';
import outHtml from './.hadars/static/out.html';
import config from './hadars.config';
// createBunnyHandler returns a standard (request: Request) => Promise<Response> function.
// Pass it directly to BunnySDK.net.http.serve.
BunnySDK.net.http.serve(createBunnyHandler(config, { ssrModule, outHtml }));optionsHadarsOptionsSame config object used for dev/runbundledBunnyBundledPre-loaded SSR module + HTML templateThe returned handler is a plain (request: Request) => Promise<Response> function — compatible with any Web API environment, not just bunny.net.
Local development
Use hadars dev for local development with full HMR. When you want to test the bundled edge script specifically, run it with Deno:
# Normal development (recommended)
hadars dev
# Build and test the bundled script locally with Deno
hadars export bunny && deno run -A bunny.mjsAlso deploying to AWS or Cloudflare? Lambda / production server · Cloudflare Workers