Skip to main content

Create Your First Worker

Get started with Cloudflare Workers by creating a simple “Hello World” application. This guide will walk you through creating, developing, and deploying your first Worker.
1

Create a new project

Use Create Cloudflare (C3) to scaffold a new Worker project with a single command:
npm create cloudflare@latest
C3 will prompt you with several questions:
 Create an application with Cloudflare

 In which directory do you want to create your application?
 dir ./my-worker

 What type of application do you want to create?
 type "Hello World" Worker

 Do you want to use TypeScript?
 yes typescript

 Do you want to deploy your application?
 no deploy via `npm run deploy`

 Application created successfully!
Choose TypeScript for better development experience with autocomplete and type checking.
2

Navigate to your project

Change into your newly created project directory:
cd my-worker
Your project structure should look like this:
my-worker/
├── src/
│   └── index.ts        # Your Worker code
├── wrangler.jsonc      # Configuration file
├── package.json        # Dependencies and scripts
├── tsconfig.json       # TypeScript configuration
└── vitest.config.js    # Testing configuration
3

Explore the Worker code

Open src/index.ts to see your Worker code:
src/index.ts
export interface Env {
  // Example binding to KV. Learn more at https://developers.cloudflare.com/workers/runtime-apis/kv/
  // MY_KV_NAMESPACE: KVNamespace;
  //
  // Example binding to Durable Object. Learn more at https://developers.cloudflare.com/workers/runtime-apis/durable-objects/
  // MY_DURABLE_OBJECT: DurableObjectNamespace;
  //
  // Example binding to R2. Learn more at https://developers.cloudflare.com/workers/runtime-apis/r2/
  // MY_BUCKET: R2Bucket;
}

export default {
  async fetch(
    request: Request,
    env: Env,
    ctx: ExecutionContext
  ): Promise<Response> {
    return new Response("Hello World!");
  },
};
This is the default Worker template with:
  • Env interface: Type definitions for bindings (KV, R2, Durable Objects, etc.)
  • fetch handler: The main entry point that handles incoming HTTP requests
  • Request/Response: Standard Web API objects
4

Start the development server

Start Wrangler’s local development server:
npm run dev
You should see output like:
⛅️ wrangler 4.69.0
-------------------

 Starting local server...
[wrangler:inf] Ready on http://localhost:8787
Open your browser to http://localhost:8787 to see your Worker in action!
The development server includes:
  • Hot reloading: Changes are reflected immediately
  • Source maps: Debug TypeScript directly
  • DevTools: Press D in the terminal to open Chrome DevTools
5

Make your first change

Update your Worker to respond with JSON:
src/index.ts
export default {
  async fetch(
    request: Request,
    env: Env,
    ctx: ExecutionContext
  ): Promise<Response> {
    return Response.json({
      message: "Hello from Cloudflare Workers!",
      timestamp: new Date().toISOString(),
      url: request.url,
    });
  },
};
Save the file and refresh your browser. You should see the JSON response immediately!
Try adding more fields to the response or reading request headers with request.headers.get("User-Agent").
6

Deploy to production

When you’re ready to deploy your Worker to Cloudflare’s global network:
npm run deploy
Wrangler will authenticate with Cloudflare (if needed) and deploy your Worker:
⛅️ wrangler 4.69.0
-------------------

Total Upload: 0.51 KiB / gzip: 0.28 KiB
Uploaded my-worker (2.34 sec)
Published my-worker (0.89 sec)
  https://my-worker.YOUR-SUBDOMAIN.workers.dev
Your Worker is now live on Cloudflare’s global network across 300+ cities!
The first deployment will prompt you to log in to Cloudflare. Make sure you have a Cloudflare account (free tier available).

Understanding the Configuration

Your wrangler.jsonc file contains the Worker configuration:
wrangler.jsonc
{
  "$schema": "node_modules/wrangler/config-schema.json",
  "name": "my-worker",
  "main": "./src/index.ts",
  "compatibility_date": "2026-03-03"
}
  • name: Your Worker’s name (used in the deployment URL)
  • main: Entry point file for your Worker
  • compatibility_date: The version of the Workers runtime to use
  • $schema: Enables autocomplete in your editor
You can add bindings to KV, R2, D1, and other Cloudflare services:
wrangler.jsonc
{
  "name": "my-worker",
  "main": "./src/index.ts",
  "compatibility_date": "2026-03-03",
  "kv_namespaces": [
    { "binding": "MY_KV", "id": "your-kv-namespace-id" }
  ],
  "r2_buckets": [
    { "binding": "MY_BUCKET", "bucket_name": "my-bucket" }
  ]
}

Next Steps

Now that you have your first Worker running, explore these topics:

Handle Requests

Learn to parse URLs, read headers, and handle different HTTP methods

Add Storage

Connect to KV for key-value storage or D1 for SQL databases

Use Bindings

Integrate with R2, Durable Objects, and other Cloudflare services

Write Tests

Test your Workers locally with Vitest and @cloudflare/vitest-pool-workers

Common Commands

Here are the most frequently used Wrangler commands:
CommandDescription
wrangler devStart local development server
wrangler deployDeploy to production
wrangler tailStream live logs from production
wrangler kv:namespace create <name>Create a KV namespace
wrangler d1 create <name>Create a D1 database
wrangler whoamiCheck authentication status
Run wrangler --help to see all available commands or wrangler <command> --help for specific command help.

Alternative: Using Wrangler Init

You can also create a Worker using Wrangler directly:
npx wrangler init my-worker -y
This creates a minimal Worker setup without the interactive prompts.

Troubleshooting

If port 8787 is already in use, specify a different port:
wrangler dev --port 8788
If you have trouble authenticating:
  1. Run wrangler logout to clear credentials
  2. Run wrangler login to authenticate again
  3. Alternatively, use an API token with wrangler login --scopes-list
Make sure all dependencies are installed:
npm install
Need help? Join the Cloudflare Discord or check the GitHub Discussions.

Build docs developers (and LLMs) love