Skip to content

These docs are for Miniflare 2 which is no longer supported apart from critical security updates.
Please see the migration guide to upgrade to Miniflare 3, and the updated API docs.

Miniflare
Visit Miniflare on GitHub
Set theme to dark (โ‡ง+D)

๐Ÿชฃ R2

Buckets

Specify R2 Buckets to add to your environment as follows:

$ miniflare --r2 BUCKET1 --r2 BUCKET2 # or -r
wrangler.toml
[[r2_buckets]]
binding = "BUCKET1"
bucket_name = "<ignored>"
[[r2_buckets]]
binding = "BUCKET2"
bucket_name = "<ignored>"
const mf = new Miniflare({
r2Buckets: ["BUCKET1", "BUCKET2"],
});

Persistence

By default, R2 data is stored in memory. It will persist between reloads, but not CLI invocations or different Miniflare instances. To enable persistence to the file system or Redis, specify the R2 persistence option:

$ miniflare --r2-persist # Defaults to ./.mf/r2
$ miniflare --r2-persist ./data/ # Custom path
$ miniflare --r2-persist redis://localhost:6379 # Redis server
wrangler.toml
[miniflare]
r2_persist = true # Defaults to ./.mf/r2
r2_persist = "./data/" # Custom path
r2_persist = "redis://localhost:6379" # Redis server
const mf = new Miniflare({
r2Persist: true, // Defaults to ./.mf/r2
r2Persist: "./data", // Custom path
r2Persist: "redis://localhost:6379", // Redis server
});

When using the file system, each bucket will get its own directory within the R2 persistence directory.

When using Redis, each key will be prefixed with the bucket name. If you're using this with the API, make sure you call dispose on your Miniflare instance to close database connections.

Manipulating Outside Workers

For testing, it can be useful to put/get data from Durable Object storage outside a worker. You can do this with the getR2Bucket method:

import { Miniflare } from "miniflare";
const mf = new Miniflare({
modules: true,
script: `
export default {
async fetch(request, env, ctx) {
const object = await env.BUCKET.get("count");
const value = parseInt(await object.text()) + 1;
await env.BUCKET.put("count", value.toString());
return new Response(value.toString());
}
}
`,
r2Buckets: ["BUCKET"],
});
const bucket = await mf.getR2Bucket("BUCKET");
await bucket.put("count", "1");
const res = await mf.dispatchFetch("http://localhost:8787/");
console.log(await res.text()); // 2
console.log(await (await bucket.get("count")).text()); // 2