API (4)
Last updated Oct 12, 2026 Wrangler offers APIs to programmatically interact with your Cloudflare Workers.
createTestHarness- Start one or more Workers for integration tests in any Node.js test runner.experimental_generateTypes- Generate TypeScript type definitions from your Worker configuration.unstable_startWorker- Start a server for running integration tests against your Worker.unstable_dev- Start a server for running either end-to-end (e2e) or integration tests against your Worker.getPlatformProxy- Get proxies and values for emulating the Cloudflare Workers platform in a Node.js process.
createTestHarness
createTestHarness() starts one or more Workers for integration tests from any Node.js test runner. It runs production build output from Wrangler configuration files, Vite-generated configuration files, or inline Wrangler configuration objects. The API wraps Miniflare and provides methods for dispatching requests and scheduled events.
For setup guidance and examples, refer to Integration test harness.
Syntax
import { createTestHarness } from "wrangler";
const server = createTestHarness(options);
import { createTestHarness } from "wrangler";
const server = createTestHarness(options);
Parameters
optionsobjectoptional- Test harness options. If you call
createTestHarness()without options, callserver.update(options)beforeserver.listen().rootstringoptional
Base directory used to resolve relative Worker configuration paths. Defaults to process.cwd().
- workers WorkerInput[]
Workers to run in the test server. The first Worker is the primary Worker.
Each WorkerInput can load a Worker from a Wrangler configuration file:
const server = createTestHarness({
workers: [
{ configPath: "./wrangler.web.jsonc" },
{ configPath: "./wrangler.api.jsonc" },
],
});
const server = createTestHarness({
workers: [
{ configPath: "./wrangler.web.jsonc" },
{ configPath: "./wrangler.api.jsonc" },
],
});
Configuration file inputs support these fields:
configPathstring | URL- Path to a Wrangler configuration file. Relative paths resolve from
root. envstringoptional- Wrangler environment to load from the configuration file.
varsRecord<string, Json>optional- Test-only variables that override variables from the Wrangler configuration file.
secretsRecord<string, string>optional- Test-only secrets that override values loaded from
.dev.varsand.envfiles. bindingOverridesRecord<string, string>optional- Test-only service binding overrides. Keys are binding names in this Worker's environment. Values are Worker names in this test harness.
Each WorkerInput can also use config to provide an inline Wrangler configuration object:
const server = createTestHarness({
workers: [
{
config: {
name: "api-worker",
main: "src/api.ts",
compatibility_date: "YYYY-MM-DD",
},
},
],
});
const server = createTestHarness({
workers: [
{
config: {
name: "api-worker",
main: "src/api.ts",
compatibility_date: "YYYY-MM-DD",
},
},
],
});
Return type
createTestHarness() returns a TestHarness object with these methods:
listen()Promise<{ url: URL }>- Starts the server and returns its current URL. Repeated calls return the same session until the server is closed or reset.
fetch(input, init)Promise<Response>- Dispatches a fetch request through the server. Relative URLs resolve against the current server URL. Absolute URLs follow the configured Worker routes and fall back to the primary Worker.
getWorker(name?)WorkerHandle- Returns a handle for dispatching events directly to a Worker. When no name is provided, this returns the primary Worker.
getLogs()WorkerdStructuredLog[]- Returns captured Workers runtime logs since the current server session started or
clearLogs()was last called. clearLogs()void- Clears captured Workers runtime logs.
debug()void- Prints a diagnostic timeline for this test server, including server events and captured Workers runtime logs. This is useful in a test runner failure or cleanup hook.
update(optionsOrUpdater)Promise<void>- Updates the server configuration with a
TestHarnessOptionsobject or a function that receives the current options and returns the next options. If the server has not started yet, this configures the options used bylisten(). If the server is running, this reloads the running Workers. Updating the number of Workers in a running server is not supported. reset()Promise<void>- Restores the server to the options used when the current session first started. Storage is recreated, and the server URL may change after reset.
close()Promise<void>- Stops the server and releases all runtime resources.
getWorker(name?) returns a WorkerHandle object with these methods:
fetch(input, init)Promise<Response>- Dispatches a fetch event directly to this Worker.
scheduled(options)Promise<{ outcome: "ok" | "canceled" | "exception"; noRetry: boolean }>- Dispatches a scheduled event directly to this Worker.
getEnv()Promise<Env>- Returns the full environment object configured for this Worker, including variables, secrets, and bindings.
getExport()Promise<Service<Module['default']>>- Returns the default Worker export, including RPC methods.
applyD1Migrations(bindingName)Promise<void>- Applies local D1 migration files that have not already run to a D1 binding on this Worker.
getDurableObjectStorage(classNameOrBindingName, options)Promise<DurableObjectStorageHandle>- Returns SQL storage access for a Durable Object instance.
introspectWorkflow(bindingName)Promise<WorkflowIntrospector>- Creates an introspector for Workflow instances created after this method is called.
introspectWorkflowInstance(bindingName, instanceId)Promise<WorkflowInstanceIntrospector>- Creates an introspector for a specific Workflow instance.
Usage
This example uses the Node.js built-in test runner:
import assert from "node:assert/strict";
import { after, afterEach, before, describe, test } from "node:test";
import { createTestHarness } from "wrangler";
const server = createTestHarness({
workers: [
{ configPath: "./wrangler.web.jsonc" },
{ configPath: "./wrangler.api.jsonc" },
],
});
const apiWorker = server.getWorker("api-worker");
describe("Worker", () => {
before(async () => {
await server.listen();
});
afterEach(async () => {
await server.reset();
});
after(async () => {
await server.close();
});
test("dispatches through configured routes", async () => {
const response = await server.fetch("http://example.com/users/123");
assert.equal(response.status, 200);
});
test("calls a specific Worker directly", async () => {
const response = await apiWorker.fetch(
"http://api.example.com/v1/users/123",
);
assert.equal(response.status, 200);
});
test("triggers a scheduled handler", async () => {
const result = await apiWorker.scheduled({
cron: "0 0 * * *",
scheduledTime: new Date(),
});
assert.equal(result.outcome, "ok");
});
});
import assert from "node:assert/strict";
import { after, afterEach, before, describe, test } from "node:test";
import { createTestHarness } from "wrangler";
const server = createTestHarness({
workers: [
{ configPath: "./wrangler.web.jsonc" },
{ configPath: "./wrangler.api.jsonc" },
],
});
const apiWorker = server.getWorker("api-worker");
describe("Worker", () => {
before(async () => {
await server.listen();
});
afterEach(async () => {
await server.reset();
});
after(async () => {
await server.close();
});
test("dispatches through configured routes", async () => {
const response = await server.fetch("http://example.com/users/123");
assert.equal(response.status, 200);
});
test("calls a specific Worker directly", async () => {
const response = await apiWorker.fetch(
"http://api.example.com/v1/users/123",
);
assert.equal(response.status, 200);
});
test("triggers a scheduled handler", async () => {
const result = await apiWorker.scheduled({
cron: "0 0 * * *",
scheduledTime: new Date(),
});
assert.equal(result.outcome, "ok");
});
});
experimental_generateTypes
Generate TypeScript type definitions from your Worker configuration. This API uses the same core logic as the wrangler types CLI command, so outputs stay aligned between the CLI and programmatic API.
Unlike the CLI command, experimental_generateTypes does not write to disk automatically. Instead, it returns the generated type content as structured strings for you to handle as needed.
Note
The experimental_generateTypes() function has an experimental_ prefix because the API is experimental and may change in the future.
Syntax
import { experimental_generateTypes } from "wrangler";
const result = await experimental_generateTypes(options);
Parameters
optionsobjectoptional- Optional options object mirroring the
wrangler typesCLI flags:configstring | string[]
Path to the Wrangler configuration file to use. Can be an array for multi-config type resolution.
- env string
Name of the Wrangler environment to generate types for.
- envFile string[]
Paths to .env files to load when inferring local variables and secrets.
- envInterface string
Name of the generated environment interface. Defaults to Env.
- includeEnv boolean
Whether to include environment and bindings types in the output. Defaults to true.
- includeRuntime boolean
Whether to include runtime types in the output. Defaults to true.
- path string
Path to the declaration file for generated types. Defaults to worker-configuration.d.ts.
- strictVars boolean
Whether to generate strict literal and union types for variables. Defaults to true.
Return Type
experimental_generateTypes() returns a Promise resolving to an object containing the following fields:
contentstring- Combined formatted output containing all generated sections, including headers and both env and runtime types.
envstring | null- Generated environment and bindings types, or
nullwhen env types are excluded. pathstring- Target declaration file path associated with this generation run.
runtimestring | null- Generated runtime types, or
nullwhen runtime types are excluded.
Usage
You can use experimental_generateTypes to generate types programmatically and write them to disk yourself, or pass them to other tools:
import { experimental_generateTypes } from "wrangler";
import * as fs from "node:fs";
const result = await experimental_generateTypes({
config: "wrangler.json",
includeRuntime: true,
includeEnv: true,
});
// Write the combined content to the path specified in options
fs.writeFileSync(result.path, result.content, "utf-8");
To generate only env types without runtime types:
const result = await experimental_generateTypes({
includeRuntime: false,
});
To generate types for a specific environment with a custom interface name:
const result = await experimental_generateTypes({
env: "staging",
envInterface: "StagingEnv",
path: "./types/staging.d.ts",
});
unstable_startWorker
Caution
unstable_startWorker() is deprecated. Cloudflare recommends createTestHarness() for integration testing. To start a development server programmatically, use the Vite createServer() ↗︎ API with the Cloudflare Vite plugin.
This API exposes the internals of Wrangler's dev server, and allows you to customise how it runs. For example, you could use unstable_startWorker() to run integration tests against your Worker. This example uses node:test, but should apply to any testing framework:
import assert from "node:assert";
import test, { after, before, describe } from "node:test";
import { unstable_startWorker } from "wrangler";
describe("worker", () => {
let worker;
before(async () => {
worker = await unstable_startWorker({ config: "wrangler.json" });
});
test("hello world", async () => {
assert.strictEqual(
await (await worker.fetch("http://example.com")).text(),
"Hello world",
);
});
after(async () => {
await worker.dispose();
});
});
unstable_dev
Caution
unstable_dev() is deprecated. Cloudflare recommends createTestHarness() for integration testing. To start a development server programmatically, use the Vite createServer() ↗︎ API with the Cloudflare Vite plugin.
Start an HTTP server for testing your Worker.
Once called, unstable_dev will return a fetch() function for invoking your Worker without needing to know the address or port, as well as a stop() function to shut down the HTTP server.
By default, unstable_dev will perform integration tests against a local server. If you wish to perform an e2e test against a preview Worker, pass local: false in the options object when calling the unstable_dev() function. Note that e2e tests can be significantly slower than integration tests.
Constructor
const worker = await unstable_dev(script, options);
Parameters
scriptstring- A string containing a path to your Worker script, relative to your Worker project's root directory.
optionsobjectoptional- Optional options object containing
wrangler devconfiguration settings. - Include an
experimentalobject insideoptionsto access experimental features such asdisableExperimentalWarning.- Set
disableExperimentalWarningtotrueto disable Wrangler's warning about usingunstable_prefixed APIs.
- Set
Return Type
unstable_dev() returns an object containing the following methods:
fetch()Promise<Response>- Send a request to your Worker. Returns a Promise that resolves with a
Responseobject. - Refer to
Fetch. stop()Promise<void>- Shuts down the dev server.
Usage
When initiating each test suite, use a beforeAll() function to start unstable_dev(). The beforeAll() function is used to minimize overhead: starting the dev server takes a few hundred milliseconds, starting and stopping for each individual test adds up quickly, slowing your tests down.
In each test case, call await worker.fetch(), and check that the response is what you expect.
