Skip to Content
getting-startedCloudflare Workers

Last Updated: 3/11/2026


Cloudflare Workers

Cloudflare Workers  is a JavaScript edge runtime on Cloudflare’s CDN. You can develop locally and deploy with Wrangler , which includes a TypeScript compiler.

Setup

Create a new project with the Cloudflare Workers template:

npm create hono@latest my-app

Select cloudflare-workers when prompted.

Install dependencies:

cd my-app npm install

Hello World

Edit src/index.ts:

import { Hono } from 'hono' const app = new Hono() app.get('/', (c) => c.text('Hello Cloudflare Workers!')) export default app

Run Locally

Start the development server:

npm run dev

Access http://localhost:8787 in your browser.

Change Port

To change the port, update wrangler.toml:

[dev] port = 3000

Or use CLI options: npx wrangler dev --port 3000

Deploy

Deploy to Cloudflare:

npm run deploy

You’ll need a Cloudflare account.

Serve Static Files

Use Static Assets  to serve files. In wrangler.toml:

assets = { directory = "public" }

Create a public directory and add files. For example, ./public/static/hello.txt will be served as /static/hello.txt.

Bindings

Access environment values, KV, R2, or Durable Objects via c.env. Pass type definitions as generics:

type Bindings = { MY_BUCKET: R2Bucket USERNAME: string PASSWORD: string } const app = new Hono<{ Bindings: Bindings }>() app.put('/upload/:key', async (c) => { const key = c.req.param('key') await c.env.MY_BUCKET.put(key, c.req.body) return c.text(`Put ${key} successfully!`) })

Environment Variables

For local development, create .dev.vars in the project root:

SECRET_KEY=value API_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Access them via c.env:

type Bindings = { SECRET_KEY: string } const app = new Hono<{ Bindings: Bindings }>() app.get('/env', (c) => { const SECRET_KEY = c.env.SECRET_KEY return c.text(SECRET_KEY) })

Before deploying, set environment variables in the Cloudflare Workers dashboard.

Using Variables in Middleware

To use environment variables in middleware:

import { basicAuth } from 'hono/basic-auth' type Bindings = { USERNAME: string PASSWORD: string } const app = new Hono<{ Bindings: Bindings }>() app.use('/auth/*', async (c, next) => { const auth = basicAuth({ username: c.env.USERNAME, password: c.env.PASSWORD, }) return auth(c, next) })

Testing

Use @cloudflare/vitest-pool-workers for testing. Example test:

import { Hono } from 'hono' const app = new Hono() app.get('/', (c) => c.text('Please test me!')) describe('Test the application', () => { it('Should return 200 response', async () => { const res = await app.request('http://localhost/') expect(res.status).toBe(200) }) })

Multiple Event Handlers

Integrate Hono with other event handlers in Module Worker mode:

const app = new Hono() export default { fetch: app.fetch, scheduled: async (batch, env) => {}, }

Deploy from GitHub Actions

  1. Create a Cloudflare API token from User API Tokens 
  2. Add CLOUDFLARE_API_TOKEN to GitHub repository secrets
  3. Create .github/workflows/deploy.yml:
name: Deploy on: push: branches: - main jobs: deploy: runs-on: ubuntu-latest name: Deploy steps: - uses: actions/checkout@v4 - name: Deploy uses: cloudflare/wrangler-action@v3 with: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
  1. Update wrangler.toml:
main = "src/index.ts" minify = true