Cloudflare Workers
Cloudflare Workers is a JavaScript edge runtime on Cloudflare CDN.
You can develop the application locally and publish it with a few commands using Wrangler. Wrangler includes trans compiler, so we can write the code with TypeScript.
Let’s make your first application for Cloudflare Workers with Hono.
1. Setup
A starter for Cloudflare Workers is available. Start your project with "create-hono" command. Select cloudflare-workers template for this example.
npm create hono@latest my-appyarn create hono my-apppnpm create hono my-appbun create hono@latest my-appdeno init --npm hono my-appMove to my-app and install the dependencies.
cd my-app
npm icd my-app
yarncd my-app
pnpm icd my-app
bun i2. Hello World
Edit src/index.ts like below.
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello Cloudflare Workers!'))
export default app3. Run
Run the development server locally. Then, access http://localhost:8787 in your web browser.
npm run devyarn devpnpm devbun run devChange port number
If you need to change the port number you can follow the instructions here to update wrangler.toml / wrangler.json / wrangler.jsonc files: Wrangler Configuration
Or, you can follow the instructions here to set CLI options: Wrangler CLI
4. Deploy
If you have a Cloudflare account, you can deploy to Cloudflare. In package.json, $npm_execpath needs to be changed to your package manager of choice.
npm run deployyarn deploypnpm run deploybun run deployThat's all!
Using Hono with other event handlers
You can integrate Hono with other event handlers (such as scheduled) in Module Worker mode.
To do this, export app.fetch as the module's fetch handler, and then implement other handlers as needed:
const app = new Hono()
export default {
fetch: app.fetch,
scheduled: async (batch, env) => {},
}Serve static files
If you want to serve static files, you can use the Static Assets feature of Cloudflare Workers. Specify the directory for the files in wrangler.toml:
assets = { directory = "public" }Then create the public directory and place the files there. For instance, ./public/static/hello.txt will be served as /static/hello.txt.
.
├── package.json
├── public
│ ├── favicon.ico
│ └── static
│ └── hello.txt
├── src
│ └── index.ts
└── wrangler.tomlTypes
You have to install @cloudflare/workers-types if you want to have workers types.
npm i --save-dev @cloudflare/workers-typesyarn add -D @cloudflare/workers-typespnpm add -D @cloudflare/workers-typesbun add --dev @cloudflare/workers-typesTesting
For testing, we recommend using @cloudflare/vitest-pool-workers. Refer to examples for setting it up.
If there is the application below.
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Please test me!'))We can test if it returns "200 OK" Response with this code.
describe('Test the application', () => {
it('Should return 200 response', async () => {
const res = await app.request('http://localhost/')
expect(res.status).toBe(200)
})
})Bindings
In the Cloudflare Workers, we can bind the environment values, KV namespace, R2 bucket, or Durable Object. You can access them in c.env. It will have the types if you pass the "type struct" for the bindings to the Hono as generics.
type Bindings = {
MY_BUCKET: R2Bucket
USERNAME: string
PASSWORD: string
}
const app = new Hono<{ Bindings: Bindings }>()
// Access to environment values
app.put('/upload/:key', async (c, next) => {
const key = c.req.param('key')
await c.env.MY_BUCKET.put(key, c.req.body)
return c.text(`Put ${key} successfully!`)
})Using Variables in Middleware
This is the only case for Module Worker mode. If you want to use Variables or Secret Variables in Middleware, for example, "username" or "password" in Basic Authentication Middleware, you need to write like the following.
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)
})The same is applied to Bearer Authentication Middleware, JWT Authentication, or others.
Deploy from GitHub Actions
Before deploying code to Cloudflare via CI, you need a Cloudflare token. You can manage it from User API Tokens.
If it's a newly created token, select the Edit Cloudflare Workers template, if you already have another token, make sure the token has the corresponding permissions(No, token permissions are not shared between Cloudflare Pages and Cloudflare Workers).
then go to your GitHub repository settings dashboard: Settings->Secrets and variables->Actions->Repository secrets, and add a new secret with the name CLOUDFLARE_API_TOKEN.
then create .github/workflows/deploy.yml in your Hono project root folder, paste the following code:
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 }}then edit wrangler.toml, and add this code after compatibility_date line.
main = "src/index.ts"
minify = trueEverything is ready! Now push the code and enjoy it.
Load env when local development
To configure the environment variables for local development, create a .dev.vars file or a .env file in the root directory of the project. These files should be formatted using the dotenv syntax. For example:
SECRET_KEY=value
API_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9For more about this section you can find in the Cloudflare documentation: https://developers.cloudflare.com/workers/wrangler/configuration/#secrets
Then we use the c.env.* to get the environment variables in our code.
INFO
By default, process.env is not available in Cloudflare Workers, so it is recommended to get environment variables from c.env. If you want to use it, you need to enable nodejs_compat_populate_process_env flag. You can also import env from cloudflare:workers. For details, please see How to access env on Cloudflare docs
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 you deploy your project to Cloudflare, remember to set the environment variable/secrets in the Cloudflare Workers project's configuration.
For more about this section you can find in the Cloudflare documentation: https://developers.cloudflare.com/workers/configuration/environment-variables/#add-environment-variables-via-the-dashboard