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-appSelect cloudflare-workers when prompted.
Install dependencies:
cd my-app
npm installHello World
Edit src/index.ts:
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello Cloudflare Workers!'))
export default appRun Locally
Start the development server:
npm run devAccess http://localhost:8787 in your browser.
Change Port
To change the port, update wrangler.toml:
[dev]
port = 3000Or use CLI options: npx wrangler dev --port 3000
Deploy
Deploy to Cloudflare:
npm run deployYou’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=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9Access 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
- Create a Cloudflare API token from User API Tokens
- Add
CLOUDFLARE_API_TOKENto GitHub repository secrets - 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 }}- Update
wrangler.toml:
main = "src/index.ts"
minify = true