mrbbot/miniflare: ๐Ÿ”ฅ Fully-local Cloudflare Workers Simulator

Fun, full-featured, fully-local simulator for developing and testing Cloudflare

See for more detailed documentation.


  • ๐Ÿ“จ Fetch Events (with HTTP server and manual triggering)
  • โฐ Scheduled Events (with manual and cron triggering)
  • ๐Ÿ”‘ Variables and Secrets with .env Files
  • ๐Ÿ“š Modules Support
  • ๐Ÿ“ฆ KV (with optional persistence)
  • โœจ Cache (with optional persistence)
  • ๐Ÿ“Œ Durable Objects (with optional persistence)
  • ๐ŸŒ Workers Sites
  • โœ‰๏ธ WebSockets
  • ๐Ÿ›  Custom & Wrangler Builds Support
  • โš™๏ธ WebAssembly Support
  • ๐Ÿ—บ Source Map Support
  • ๐Ÿ•ธ Web Standards: Base64, Timers, Fetch, Encoding, URL, Streams, Crypto
  • ๐Ÿ“„ HTMLRewriter
  • ๐Ÿ‘€ Automatic Reload on File Changes
  • ๐Ÿ’ช Written in TypeScript


Miniflare is installed using npm:

$ npm install -g miniflare # either globally..
$ npm install -D miniflare # ...or as a dev dependency

Using the CLI

$ miniflare worker.js --watch --debug
[mf:dbg] Options:
[mf:dbg] - Scripts: worker.js
[mf:dbg] Reloading worker.js...
[mf:inf] Worker reloaded!
[mf:dbg] Watching .env, worker.js, wrangler.toml...
[mf:inf] Listening on :8787
[mf:inf] -

Using the API

import { Miniflare } from "miniflare";

const mf = new Miniflare({
  script: `
  addEventListener("fetch", (event) => {
    event.respondWith(new Response("Hello Miniflare!"));
const res = await mf.dispatchFetch("http://localhost:8787/");
console.log(await res.text()); // Hello Miniflare!

CLI Reference

Usage: miniflare [script] [options]

  -h, --help              Show help                                    [boolean]
  -v, --version           Show version number                          [boolean]
  -H, --host              HTTP server host to listen on (all by default)[string]
  -p, --port              HTTP server port (8787 by default)            [number]
  -d, --debug             Log debug messages                           [boolean]
  -c, --wrangler-config   Path to wrangler.toml                         [string]
      --wrangler-env      Environment in wrangler.toml to use           [string]
  -m, --modules           Enable modules                               [boolean]
      --modules-rule      Modules import rule (TYPE=GLOB)                [array]
      --build-command     Command to build project                      [string]
      --build-base-path   Working directory for build command           [string]
      --build-watch-path  Directory to watch for rebuilding on changes  [string]
  -w, --watch             Watch files for changes                      [boolean]
  -u, --upstream          URL of upstream origin                        [string]
  -t, --cron              Cron pattern to trigger scheduled events with  [array]
  -k, --kv                KV namespace to bind                           [array]
      --kv-persist        Path to persist KV data to (omit path for default)
      --cache-persist     Path to persist cached data to (omit path for default)
  -s, --site              Path to serve Workers Site files from         [string]
      --site-include      Glob pattern of site files to serve            [array]
      --site-exclude      Glob pattern of site files not to serve        [array]
  -o, --do                Durable Object to bind (NAME=CLASS)            [array]
      --do-persist        Path to persist Durable Object data to (omit path for
  -e, --env               Path to .env file                             [string]
  -b, --binding           Bind variable/secret (KEY=VALUE)               [array]
      --wasm              WASM module to bind (NAME=PATH)                [array]


Many thanks to
for inspiration.

Durable Objectโ€™s transactions are implemented using Optimistic Concurrency
Control (OCC) as described in
โ€œOn optimistic methods for concurrency control.โ€ ACM Transactions on Database Systems.
Thanks to Alistair Oโ€™Brien for helping me
understand this.

Related Articles

Back to top button