🔥 Fully-local simulator for Cloudflare Workers. For the latest version, see https://github.com/cloudflare/workers-sdk/tree/main/packages/miniflare.
Body#formData()
with malformed form data. Thanks @b-marques for the PR.scriptPath
as the file path for the script if set. Thanks @frandiox for the PR.vitest-environment-miniflare
works with Node 21. Closes issue #732, thanks @jkeys089 for the PR.waitUntil()
s added inside waitUntil()
callbacks are waited on. Closes issue #605, thanks @hansottowirtz for the PR.undici
to 5.82.2
, addressing low severity npm audit
warning. Closes issues #607 and #738, thanks @hansottowirtz and @mm-jpoole.KV#list
with long (≥50ch) prefixes by @huw in https://github.com/cloudflare/miniflare/pull/691
fetcher.fetch()
internal url by @RamIdeas in https://github.com/cloudflare/miniflare/pull/724
1.20231025.0
and enable coloured logging by @mrbbot in https://github.com/cloudflare/miniflare/pull/725
Full Changelog: https://github.com/cloudflare/miniflare/compare/v3.20231023.0...v3.20231025.0
workerd
and miniflare
to 20231023
by @jspspike in https://github.com/cloudflare/miniflare/pull/723
Full Changelog: https://github.com/cloudflare/miniflare/compare/v3.20231016.0...v3.20231023.0
getFetcher()
for dispatching fetch
/scheduled
/queue
events by @mrbbot in https://github.com/cloudflare/miniflare/pull/708
dispatchFetch()
s and batch proxy heap frees by @mrbbot in https://github.com/cloudflare/miniflare/pull/713
3.20231010.0
by @penalosa in https://github.com/cloudflare/miniflare/pull/715
Full Changelog: https://github.com/cloudflare/miniflare/compare/v3.20231002.1...v3.20231010.0
getFetcher()
for dispatching fetch
/scheduled
/queue
events by @mrbbot in https://github.com/cloudflare/miniflare/pull/708
dispatchFetch()
s and batch proxy heap frees by @mrbbot in https://github.com/cloudflare/miniflare/pull/713
3.20231010.0
by @penalosa in https://github.com/cloudflare/miniflare/pull/715
workerd
to 1.20231016.0
and prevent ProxyServer
eviction by @mrbbot in https://github.com/cloudflare/miniflare/pull/717
Full Changelog: https://github.com/cloudflare/miniflare/compare/v3.20231002.1...v3.20231016.0
KVNamespace#put()
with empty value by @mrbbot in https://github.com/cloudflare/miniflare/pull/704
Miniflare#dispose()
immediately after new Miniflare()
by @mrbbot in https://github.com/cloudflare/miniflare/pull/705
//# sourceURL
comments if present by @mrbbot in https://github.com/cloudflare/miniflare/pull/706
3.20231002.1
by @mrbbot in https://github.com/cloudflare/miniflare/pull/707
Full Changelog: https://github.com/cloudflare/miniflare/compare/v3.20231002.0...v3.20231002.1
workerd
and versions to 3.20231002.0
by @mrbbot in https://github.com/cloudflare/miniflare/pull/701
Full Changelog: https://github.com/cloudflare/miniflare/compare/v3.20230922.0...v3.20231002.0
workerd
and miniflare
to 20230922
by @jspspike in https://github.com/cloudflare/miniflare/pull/696
Full Changelog: https://github.com/cloudflare/miniflare/compare/v3.20230918.0...v3.20230922.0
GET
requests with bodies in entry worker by @mrbbot in https://github.com/cloudflare/miniflare/pull/677
handleQueue()
function from entry worker by @mrbbot in https://github.com/cloudflare/miniflare/pull/678
workerd
binary via MINIFLARE_WORKERD_PATH
variable by @mrbbot in https://github.com/cloudflare/miniflare/pull/682
miniflare
version to 20230918
by @jspspike in https://github.com/cloudflare/miniflare/pull/688
Full Changelog: https://github.com/cloudflare/miniflare/compare/v3.20230904.0...v3.20230918.0
This release changes the persistence directory layout. KV namespaces, R2 buckets and D1 databases will automatically be migrated to the new layout automatically. Caches will not be migrated.
As an example, specifying the following options...
new Miniflare({
kvPersist: "./data/kv",
kvNamespaces: ["NAMESPACE"],
r2Persist: "./data/r2",
r2Buckets: ["BUCKET"],
d1Persist: "./data/d1",
d1Databases: ["DATABASE"],
cachePersist: "./data/cache"
});
...would previously persist data like...
data
├── cache
│ └── default
│ ├── blobs
│ │ └── cb439464a0136ae87dda5b16e5d5c2e25c1aadd9971defa989b5a3de8c16e7da00004bf38fc72ed2
│ └── db.sqlite
├── d1
│ └── DATABASE
│ └── db.sqlite
├── kv
│ └── NAMESPACE
│ ├── blobs
│ │ └── 6ae43bc9d5630ba36dbd152d458265eab16472e2837c6395f002cd074879ff1500004bf38ca477b4
│ └── db.sqlite
└── r2
└── BUCKET
├── blobs
│ └── c3ba545e38e76c32a9534e9406a2899d997993f0d75efc75f2507acf08735cac00004bf38da2e625
└── db.sqlite
...but will now persist data like...
data
├── cache
│  ├── default
│  │  └── blobs
│  │  └── cb439464a0136ae87dda5b16e5d5c2e25c1aadd9971defa989b5a3de8c16e7da00004bf38fc72ed2
│  └── miniflare-CacheObject
│  └── 9f458c07675338a7426a7b81ac4fb1baf92d034efbcaaf4336379640ed744ded.sqlite
├── d1
│  └── miniflare-D1DatabaseObject
│  └── e5f2187c86795ea6326c373904215941fcc05bb3d3eb8bf40b08a5573435c797.sqlite
├── kv
│  ├── NAMESPACE
│  │  └── blobs
│  │  └── 6ae43bc9d5630ba36dbd152d458265eab16472e2837c6395f002cd074879ff1500004bf38ca477b4
│  └── miniflare-KVNamespaceObject
│  └── c5143190acbf456f17b8db87ca6e6d0c672fd61585313adee82937a956e44b8c.sqlite
└── r2
├── BUCKET
│  └── blobs
│  └── c3ba545e38e76c32a9534e9406a2899d997993f0d75efc75f2507acf08735cac00004bf38da2e625
└── miniflare-R2BucketObject
└── 2ba11df92c037da2e2f63b12b8924678770664954fa3deab29e63c3d63bbfb7e.sqlite
Note db.sqlite
s are no longer stored under the namespace directory, but flat in miniflare-*Object
directories. The file names in this directory correspond to the IDs of each namespaces' Durable Object.
As of Miniflare v3, the persistence layout is no longer a public interface, and is subject to change at any time. As long as you're accessing persisted data via the Miniflare API, data will be persisted across minor versions. If you have scripts that depend on the previous persistence layout directly, we recommend using the Miniflare API to manipulate your data instead.
import { Miniflare, Response } from "miniflare";
const mf = new Miniflare({
script: "",
modules: true,
kvPersist: "./data/kv",
kvNamespaces: ["NAMESPACE"],
r2Persist: "./data/r2",
r2Buckets: ["BUCKET"],
d1Persist: "./data/d1",
d1Databases: ["DATABASE"],
cachePersist: "./data/cache"
});
// Instance of https://workers-types.pages.dev/#KVNamespace
const kvNamespace = await mf.getKVNamespace("NAMESPACE");
await kvNamespace.put("key", "value");
// Instance of https://workers-types.pages.dev/#R2Bucket
const r2Bucket = await mf.getR2Bucket("BUCKET");
await r2Bucket.put("key", "value");
// Instance of https://workers-types.pages.dev/#D1Database
const d1Database = await mf.getD1Database("DATABASE");
await d1Database.exec("CREATE TABLE entries (key TEXT PRIMARY KEY, value TEXT);");
await d1Database.prepare("INSERT INTO entries (key, value) VALUES (?1, ?2)").bind("a", "1").run();
// Instance of https://workers-types.pages.dev/#CacheStorage
const caches = await mf.getCaches();
const response = new Response("body", { headers: { "Cache-Control": "max-age=3600" }});
await caches.default.put("http://localhost/key", response);
If you need to access databases directly, you can generate the miniflare-*Object/<id>.sqlite
<id>
using the following function:
import crypto from "node:crypto";
function durableObjectNamespaceIdFromName(uniqueKey, name) {
const key = crypto.createHash("sha256").update(uniqueKey).digest();
const nameHmac = crypto.createHmac("sha256", key).update(name).digest().subarray(0, 16);
const hmac = crypto.createHmac("sha256", key).update(nameHmac).digest().subarray(0, 16);
return Buffer.concat([nameHmac, hmac]).toString("hex");
}
...where uniqueKey
is one of miniflare-{KVNamespace,R2Bucket,D1Database,Cache}Object
, and name
is the ID of your namespace/bucket/database/cache. Note this is very likely to break again in future versions, so please use the Miniflare API if you can.
Miniflare#ready
by @mrbbot in https://github.com/cloudflare/miniflare/pull/671
NodeJsCompatModule
, and module-related fixups by @mrbbot in https://github.com/cloudflare/miniflare/pull/673
workerd
to 1.20230904.0
and bump versions by @mrbbot in https://github.com/cloudflare/miniflare/pull/675
Full Changelog: https://github.com/cloudflare/miniflare/compare/v3.20230821.0...v3.20230904.0