Learn about Hono routing techniques, context management, middleware patterns, server-side rendering with JSX and how to deploy an app to Cloudflare Workers.
In this post, we introduce Hono, a multi-runtime web framework that’s extremely fast and lightweight. We’ll learn about Hono’s routing techniques, context management, middleware patterns and server-side rendering with JSX, and how to deploy our app to Cloudflare Workers. We’ll build a multicurrency conversion API that runs locally on Node.js and deploys to Cloudflare Workers on the free tier.
Prerequisites
- Node.js
- Basic TypeScript familiarity
- A Cloudflare account (free tier)
What Is Hono?
Hono is a small, fast and simple web framework built with web standards so it can run anywhere. It’s an Express alternative designed especially for modern serverless and edge computing environments. It has built-in TypeScript support and is very compatible with Cloudflare because the creator designed it with Cloudflare in mind.
What Are Cloudflare Workers?
Cloudflare is a serverless edge computing environment that makes it easy to build, deploy and scale apps across a global network. Instead of using heavy virtual machines or containers, it uses Google’s V8 engine isolates, which eliminates cold start times. When an API call comes in, Cloudflare Workers intercept the request and run your code on the nearest server to you, minimizing latency.
Project Setup
To get started, run this command in your terminal:
This creates a new project directory with the recommended structure and configuration files.
Next, run this command in your terminal to cd into your new directory:
To start a local dev server, run this command:
Wrangler is Cloudflare’s CLI tool that comes with your project. It helps you manage and deploy your Hono app.
How to Create Routes and Manage Context
Creating Routes
Like Express, Hono has app.get(), app.post() and other HTTP methods. You can also use regular expressions to customize routes. For example, you can limit a route to specific currency codes as shown below:
You can also define routes to match multiple paths using the wildcard *:
Or define optional parameters using ?:
Finally, you can group related routes with a common prefix using app.route():
Managing Context
While Express uses req and res, Hono uses a single context object called c. This object is passed to every middleware and route handler.
You can also use c to pass data between middleware and handlers with c.set() and c.get():
We’ll use this pattern later when creating custom middleware.
Middleware Patterns
Middleware functions look like route handlers, but with an extra next argument.
The path determines where the middleware runs. In the example above, we used the wildcard so it runs on all routes.
Calling await next() passes control to the next middleware or route handler in the chain. The code after await next() doesn’t run until the response is built. This makes it ideal for logging, adding headers and other post-processing tasks.
The execution order looks like this:
Once the response is built, execution unwinds in reverse order. The last middleware to run before the route handler resumes after the handler finishes; then execution continues back through the rest of the middleware stack.
You can also define middleware separately using the factory pattern and register it wherever you need it:
Then register it using:
Hono comes with some built-in middleware. Here are two commonly used examples:
You can also find third-party middleware here.
Building a Currency Converter Demo
First, open tsconfig.json and add "WebWorker" to the lib array. Save the file before continuing. This gives TypeScript access to the types available in the Cloudflare Workers runtime:
Next, create a file called src/types.ts to define the context type that will be shared across all Hono instances. We’re doing this because any value you attach to the context with c.set() needs to be declared first:
Next, let’s create a file called src/middleware/logger.ts to define our custom logger middleware using the factory pattern:
Next, let’s create a file called src/views/Home.tsx to define our JSX component that we’ll render in our index route. Any file containing JSX needs the .tsx extension:
Next, create a file called src/routes/index.tsx to set up JSX rendering. We’re going to register the jsxRenderer() middleware, which adds a render() method to our context object. This method allows us to serve the Home component as HTML:
In this route, we didn’t use the context type we defined because we’re not using the requestId variable. We’ll use it in the next route.
Next, create a file called src/routes/converter.ts to combine all our routing concepts: regex constraints, wildcards, optional parameters and context access:
Notice that because this Hono instance uses the requestId context variable, it needs to be typed with Variables:
Finally, in src/index.ts, we bring everything together. We register our custom middleware, mount our route groups and export the app:
Note that export default app is what Cloudflare Workers expects. It’s the entry point that the runtime calls when a request comes in.
Deploy App
Save all files, start your app in development mode, and test the routes to make sure everything works.
Next, run the command below and sign in to your Cloudflare account:
That’s it! Your app is now live on Cloudflare Workers.
You’ll see a success response like this:
Conclusion
In this post, we covered Hono’s routing techniques, context management, middleware patterns, server-side rendering with JSX and deploying your Hono app to Cloudflare Workers.
To further improve your app, you can use other Hono-built-in or third-party middleware, implement testing strategies and use Hono’s RPC (Remote Procedure Call) feature to share API specs between the server and client.










