Cloudflare Workers is an edge computing platform that runs JavaScript at Cloudflare’s global network. Hono works perfectly with Cloudflare Workers with zero configuration.
Quick Start
Create a new Hono project for Cloudflare Workers:
npm create hono@latest my-app
Select “cloudflare-workers” as your template when prompted.
Installation
If you’re adding Hono to an existing Cloudflare Workers project:
Basic Usage
Create your application in src/index.ts:
import { Hono } from 'hono'
const app = new Hono ()
app . get ( '/' , ( c ) => c . text ( 'Hello Cloudflare Workers!' ))
app . get ( '/api/hello' , ( c ) => {
return c . json ({ message: 'Hello from the edge!' })
})
export default app
Cloudflare Workers expects your application to be exported as default. Hono’s app object is a valid fetch handler.
Adapter Features
The Cloudflare Workers adapter provides several utilities:
Static Files
Serve static files using the serveStatic middleware:
import { Hono } from 'hono'
import { serveStatic } from 'hono/cloudflare-workers'
const app = new Hono ()
app . use ( '/static/*' , serveStatic ({ root: './' }))
app . use ( '/favicon.ico' , serveStatic ({ path: './favicon.ico' }))
app . get ( '/' , ( c ) => c . text ( 'Hello!' ))
export default app
WebSocket Support
Upgrade HTTP connections to WebSocket:
import { Hono } from 'hono'
import { upgradeWebSocket } from 'hono/cloudflare-workers'
const app = new Hono ()
app . get (
'/ws' ,
upgradeWebSocket (( c ) => {
return {
onMessage ( event , ws ) {
console . log ( `Message from client: ${ event . data } ` )
ws . send ( 'Hello from server!' )
},
onClose : () => {
console . log ( 'Connection closed' )
},
}
})
)
export default app
Connection Info
Get connection information including IP address:
import { Hono } from 'hono'
import { getConnInfo } from 'hono/cloudflare-workers'
const app = new Hono ()
app . get ( '/info' , ( c ) => {
const info = getConnInfo ( c )
return c . json ({
remote: info . remote ,
})
})
export default app
Configuration
wrangler.toml
Configure your Worker with wrangler.toml:
name = "my-hono-app"
main = "src/index.ts"
compatibility_date = "2024-01-01"
[ build ]
command = "npm install && npm run build"
# Add environment variables
[ vars ]
ENVIRONMENT = "production"
# Configure KV namespace
[[ kv_namespaces ]]
binding = "MY_KV"
id = "your-kv-id"
# Configure R2 bucket
[[ r2_buckets ]]
binding = "MY_BUCKET"
bucket_name = "my-bucket"
Accessing Bindings
Access Cloudflare bindings through the context:
import { Hono } from 'hono'
type Bindings = {
MY_KV : KVNamespace
MY_BUCKET : R2Bucket
DB : D1Database
}
const app = new Hono <{ Bindings : Bindings }>()
app . get ( '/kv/:key' , async ( c ) => {
const key = c . req . param ( 'key' )
const value = await c . env . MY_KV . get ( key )
return c . text ( value || 'Not found' )
})
app . get ( '/r2/:key' , async ( c ) => {
const key = c . req . param ( 'key' )
const object = await c . env . MY_BUCKET . get ( key )
if ( ! object ) return c . notFound ()
return c . body ( await object . arrayBuffer ())
})
export default app
Deployment
Install Wrangler
Install the Cloudflare Workers CLI:
Login to Cloudflare
Authenticate with your Cloudflare account:
Deploy
Deploy your application: Your app will be available at https://my-hono-app.<your-subdomain>.workers.dev
Development
Run your Worker locally:
This starts a local development server with hot reload at http://localhost:8787.
Environment Variables
Add secrets for sensitive data:
wrangler secret put API_KEY
Access secrets in your code:
type Bindings = {
API_KEY : string
}
const app = new Hono <{ Bindings : Bindings }>()
app . get ( '/api' , ( c ) => {
const apiKey = c . env . API_KEY
// Use the API key
})
Best Practices
Workers have a size limit. Use tree-shaking and avoid large dependencies.
TypeScript provides excellent type safety for bindings and context.
Always implement error handling as Workers run at the edge.
Use Cache API and KV for better performance.
Resources
Cloudflare Workers Docs Official Cloudflare Workers documentation
Wrangler CLI Learn more about the Wrangler CLI