miniflare
🔥 Fully-local simulator for Cloudflare Workers. For the latest version, see https://github.com/cloudflare/workers-sdk/tree/main/packages/miniflare.
Top Related Projects
Quick Overview
Miniflare is a local development environment for Cloudflare Workers, designed to simulate the Cloudflare Workers runtime on your local machine. It allows developers to test and debug their Workers scripts without deploying to the Cloudflare network, providing a faster and more convenient development experience.
Pros
- Fast and lightweight local development environment for Cloudflare Workers
- Supports most Cloudflare Workers APIs and features
- Provides hot reloading for quick iteration during development
- Integrates well with existing development workflows and tools
Cons
- May not perfectly replicate all aspects of the live Cloudflare Workers environment
- Some advanced features or edge cases might not be fully supported
- Requires separate deployment steps to push changes to production
- Learning curve for developers new to Cloudflare Workers ecosystem
Code Examples
- Basic Worker script:
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
return new Response('Hello World!')
}
- Using KV storage:
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
const value = await MY_KV.get('key')
return new Response(`Value: ${value}`)
}
- Handling different HTTP methods:
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
switch (request.method) {
case 'GET':
return new Response('This is a GET request')
case 'POST':
return new Response('This is a POST request')
default:
return new Response('Method not allowed', { status: 405 })
}
}
Getting Started
-
Install Miniflare:
npm install -g miniflare
-
Create a
worker.js
file with your Worker script. -
Run Miniflare:
miniflare worker.js
-
Access your Worker at
http://localhost:8787
. -
For more advanced configuration, create a
wrangler.toml
file:name = "my-worker" type = "javascript" account_id = "your-account-id" workers_dev = true
-
Run Miniflare with the configuration:
miniflare --wrangler-config wrangler.toml
Competitor Comparisons
A modern runtime for JavaScript and TypeScript.
Pros of Deno
- Broader ecosystem support, including a wide range of standard libraries and third-party modules
- Built-in TypeScript support without additional configuration
- More comprehensive tooling, including a built-in test runner, formatter, and linter
Cons of Deno
- Steeper learning curve for developers familiar with Node.js
- Potentially slower execution compared to Miniflare for specific Cloudflare Workers use cases
- Less focused on Cloudflare Workers-specific features and APIs
Code Comparison
Deno:
import { serve } from "https://deno.land/std@0.140.0/http/server.ts";
serve((req) => new Response("Hello World!"));
Miniflare:
addEventListener("fetch", (event) => {
event.respondWith(new Response("Hello World!"));
});
The code comparison shows that Deno uses ES modules and imports from URLs, while Miniflare follows the Cloudflare Workers API more closely. Deno's approach is more general-purpose, while Miniflare is tailored specifically for Cloudflare Workers development.
Web framework built on Web Standards
Pros of Hono
- Lightweight and fast web framework with minimal overhead
- Supports TypeScript out of the box for better type safety
- Versatile, can be used in various environments (Cloudflare Workers, Deno, Bun, etc.)
Cons of Hono
- Primarily focused on routing and middleware, less comprehensive than Miniflare
- May require additional setup for full-featured development environments
- Less integrated with Cloudflare Workers ecosystem compared to Miniflare
Code Comparison
Hono:
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello Hono!'))
export default app
Miniflare:
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
async function handleRequest(request) {
return new Response('Hello Miniflare!', { status: 200 })
}
Hono provides a more modern, expressive API for routing and handling requests, while Miniflare focuses on simulating the Cloudflare Workers environment for local development and testing. Hono is better suited for building web applications with clean, organized code, whereas Miniflare excels in creating a realistic development environment for Cloudflare Workers projects.
The next-gen web framework.
Pros of Fresh
- Built specifically for Deno, offering seamless integration with Deno's ecosystem
- Supports server-side rendering out of the box, enhancing SEO and initial page load performance
- Provides a more comprehensive web framework with routing, templating, and state management
Cons of Fresh
- Limited to Deno runtime, reducing flexibility compared to Miniflare's broader JavaScript support
- Steeper learning curve for developers not familiar with Deno or its specific APIs
- Less focus on simulating Cloudflare Workers environment, which Miniflare specializes in
Code Comparison
Fresh (server setup):
import { serve } from "https://deno.land/std@0.140.0/http/server.ts";
import { createApp } from "https://deno.land/x/fresh@1.1.2/server.ts";
const app = createApp();
await serve(app.fetch);
Miniflare (worker setup):
import { Miniflare } from "miniflare";
const mf = new Miniflare({
scriptPath: "./worker.js",
modules: true,
});
const response = await mf.dispatchFetch("http://localhost:8787/");
Fresh focuses on creating full-stack Deno applications, while Miniflare simulates the Cloudflare Workers environment for local development and testing. Fresh offers a more comprehensive framework for building web applications in Deno, whereas Miniflare provides a specialized tool for Cloudflare Workers development across different JavaScript runtimes.
The React Framework
Pros of Next.js
- Full-featured React framework with built-in routing, server-side rendering, and static site generation
- Large ecosystem and community support, with extensive documentation and third-party integrations
- Optimized for performance with automatic code splitting and image optimization
Cons of Next.js
- Steeper learning curve for developers new to React or server-side rendering concepts
- More complex setup and configuration compared to simpler static site generators
- Potentially higher resource usage due to server-side rendering capabilities
Code Comparison
Next.js:
// pages/index.js
export default function Home() {
return <h1>Welcome to Next.js!</h1>
}
Miniflare:
// index.js
addEventListener('fetch', event => {
event.respondWith(new Response('Hello from Miniflare!'))
})
Key Differences
- Next.js is a full-stack React framework, while Miniflare is a local development tool for Cloudflare Workers
- Next.js focuses on server-side rendering and static site generation, whereas Miniflare simulates the Cloudflare Workers runtime
- Next.js has a more opinionated structure and built-in features, while Miniflare provides a lightweight environment for testing and debugging Workers
Use Cases
- Choose Next.js for building complex web applications with React, especially those requiring server-side rendering or static site generation
- Use Miniflare for developing and testing Cloudflare Workers locally before deployment to the Cloudflare platform
Build Better Websites. Create modern, resilient user experiences with web fundamentals.
Pros of Remix
- Full-stack web framework with server-side rendering and client-side hydration
- Supports nested routing and data loading for improved performance
- Integrates well with various backend services and databases
Cons of Remix
- Steeper learning curve for developers new to full-stack frameworks
- Requires more setup and configuration compared to simpler alternatives
- May be overkill for small, static websites or simple applications
Code Comparison
Remix (server-side route):
export async function loader({ params }) {
const user = await getUser(params.userId);
return json({ user });
}
export default function UserProfile() {
const { user } = useLoaderData();
return <h1>{user.name}'s Profile</h1>;
}
Miniflare (worker script):
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request));
});
async function handleRequest(request) {
return new Response('Hello, Miniflare!');
}
Key Differences
- Remix is a full-stack framework, while Miniflare is a local development tool for Cloudflare Workers
- Remix focuses on server-side rendering and client-side hydration, whereas Miniflare simulates the Cloudflare Workers runtime
- Remix provides a more comprehensive development ecosystem, while Miniflare is specifically tailored for Cloudflare Workers development
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
[!WARNING]
This repository is for Miniflare 2, which is only receiving critical security updates. Miniflare 2 simulated the Workers runtime and the rest of the Cloudflare developer platform using Node.js. New versions of Miniflare can be found in the
workers-sdk
repository, and use the open-sourced Workers runtimeworkerd
. This practically eliminates behaviour mismatches between development and production deployments. We recommend you migrate to Miniflare 3 now if you can. Whilst Miniflare 3 supports most of Miniflare 2's features, one key omission is the unit testing environment. We're actively working on adding support for this to Miniflare 3. Once this is supported, we're planning to deprecate Miniflare 2 and archive this repository.
ð¥ Miniflare 2
Miniflare is a simulator for developing and testing Cloudflare Workers.
- ð Fun: develop workers easily with detailed logging, file watching and pretty error pages supporting source maps.
- ð Full-featured: supports most Workers features, including KV, Durable Objects, WebSockets, modules and more.
- â¡ Fully-local: test and develop Workers without an internet connection. Reload code on change quickly.
It's an alternative to wrangler dev
, written in TypeScript, that runs your
workers in a sandbox implementing Workers' runtime APIs.
See https://legacy.miniflare.dev for more detailed documentation.
Features
- ð¨ Fetch Events (with HTTP(S) server and manual dispatch)
- â° Scheduled Events (with cron triggering and manual dispatch)
- ð Variables and Secrets with
.env
Files - ð Modules Support
- ð¦ KV (with optional persistence)
- 𪣠R2 (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
- â¡ï¸ Live Reload on File Changes
- ð Compatibility Dates/Flags Support
- ð Multiple Workers Support
- 𤹠Custom Jest Environment (with isolated per-test storage)
- ðª Written in TypeScript
Install
Miniflare is installed using npm:
$ npm install -g miniflare@2 # either globally..
$ npm install -D miniflare@2 # ...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! (97B)
[mf:dbg] Watching .env, package.json, worker.js, wrangler.toml...
[mf:inf] Listening on :8787
[mf:inf] - http://127.0.0.1:8787
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]
Core Options:
-h, --help Show help [boolean]
-v, --version Show version number [boolean]
-c, --wrangler-config Path to wrangler.toml [string]
--wrangler-env Environment in wrangler.toml to use [string]
--package Path to package.json [string]
-m, --modules Enable modules [boolean]
--modules-rule Modules import rule [array:TYPE=GLOB]
--compat-date Opt into backwards-incompatible changes from [string]
--compat-flag Control specific backwards-incompatible changes [array]
--usage-model Usage model (bundled by default) [string]
-u, --upstream URL of upstream origin [string]
-w, --watch Watch files for changes [boolean]
-d, --debug Enable debug logging [boolean]
-V, --verbose Enable verbose logging [boolean]
--(no-)update-check Enable update checker (enabled by default) [boolean]
--repl Enable interactive REPL [boolean]
--root Path to resolve files relative to [string]
--mount Mount additional named workers [array:NAME=PATH[@ENV]]
--name Name of service [string]
--route Route to respond with this worker on [array]
--global-async-io Allow async I/O outside handlers [boolean]
--global-timers Allow setting timers outside handlers [boolean]
--global-random Allow secure random generation outside handlers [boolean]
--actual-time Always return correct time from Date methods [boolean]
--inaccurate-cpu Log inaccurate CPU time measurements [boolean]
HTTP Options:
-H, --host Host for HTTP(S) server to listen on [string]
-p, --port Port for HTTP(S) server to listen on [number]
-O, --open Automatically open browser to URL [boolean/string]
--https Enable self-signed HTTPS (with optional cert path) [boolean/string]
--https-key Path to PEM SSL key [string]
--https-cert Path to PEM SSL cert chain [string]
--https-ca Path to SSL trusted CA certs [string]
--https-pfx Path to PFX/PKCS12 SSL key/cert chain [string]
--https-passphrase Passphrase to decrypt SSL files [string]
--(no-)cf-fetch Path for cached Request cf object from Cloudflare [boolean/string]
--live-reload Reload HTML pages whenever worker is reloaded [boolean]
Scheduler Options:
-t, --cron CRON expression for triggering scheduled events [array]
Build Options:
-B, --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 [array]
KV Options:
-k, --kv KV namespace to bind [array]
--kv-persist Persist KV data (to optional path) [boolean/string]
R2 Options:
-r, --r2 R2 bucket to bind [array]
--r2-persist Persist R2 data (to optional path) [boolean/string]
Durable Objects Options:
-o, --do Durable Object to bind [array:NAME=CLASS[@MOUNT]]
--do-persist Persist Durable Object data (to optional path) [boolean/string]
--(no-)do-alarms Enable Durable Object alarms (enabled by default) [boolean]
Cache Options:
--(no-)cache Enable default/named caches (enabled by default) [boolean]
--cache-persist Persist cached data (to optional path) [boolean/string]
Sites Options:
-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]
Bindings Options:
-e, --env Path to .env file [string]
-b, --binding Binds variable/secret to environment [array:KEY=VALUE]
--global Binds variable/secret to global scope [array:KEY=VALUE]
--wasm WASM module to bind [array:NAME=PATH]
--text-blob Text blob to bind [array:NAME=PATH]
--data-blob Data blob to bind [array:NAME=PATH]
-S, --service Mounted service to bind [array:NAME=MOUNT[@ENV]]
Acknowledgements
Miniflare was created by Brendan Coll.
Many thanks to dollarshaveclub/cloudworker and gja/cloudflare-worker-local 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 the Miniflare creator understand this.
Top Related Projects
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot