github honojs/hono v3.2.0

latest releases: v4.3.7, v4.3.6, v4.3.5...
12 months ago

New routers, presets, app.mount(), Node server v1. Let's go!

Hono v3.2 is now available! It introduces many features while maintaining simplicity.

  • Two new routers: LinearRouter and PatternRouter.
  • Presets: hono/tiny, hono/quick.
  • app.mount()
  • Release of Node adapter server v1.0.0!
  • Support for AWS Lambda function URLs.
  • Cookie Middleware.
  • Renaming hono/nextjs to hono/vercel.

Let's take a look!

New Routers

We introduce two new routers: LinearRouter and PatternRouter.

LinearRouter

LinearRouter is "quick". While RegExpRouter is one of the fastest routers in the JavaScript world, it's a bit slow when registering routing paths.

app.get('/', handler) // <=== Registering routing paths - a little slow

//...

app.fetch(request)  // <=== Handle request - ultra-fast

So, in environments that are initialized with every request, such as Fastly Compute@Edge, RegExpRouter may not be the best choice.

LinearRouter registers routes very quickly, even compared to other fast JavaScript routers. The following is one of the benchmark results, which includes the route registration phase.

• GET /user/lookup/username/hey
----------------------------------------------------- -----------------------------
LinearRouter     1.82 µs/iter      (1.7 µs … 2.04 µs)   1.84 µs   2.04 µs   2.04 µs
MedleyRouter     4.44 µs/iter     (4.34 µs … 4.54 µs)   4.48 µs   4.54 µs   4.54 µs
FindMyWay       60.36 µs/iter      (45.5 µs … 1.9 ms)  59.88 µs  78.13 µs  82.92 µs
KoaTreeRouter    3.81 µs/iter     (3.73 µs … 3.87 µs)   3.84 µs   3.87 µs   3.87 µs
TrekRouter       5.84 µs/iter     (5.75 µs … 6.04 µs)   5.86 µs   6.04 µs   6.04 µs

summary for GET /user/lookup/username/hey
  LinearRouter
   2.1x faster than KoaTreeRouter
   2.45x faster than MedleyRouter
   3.21x faster than TrekRouter
   33.24x faster than FindMyWay

And according to this comment, it will be 40% faster on Fastly Compute@Edge.

PatternRouter

PatternRouter is "tiny". By default, Hono uses SmartRouter with RegExpRouter and TrieRouter. Although not the fastest, we made it even smaller.

If you need to reduce size for resource-limited environments, you can use PatternRouter.

An application using only PatternRouter is about 12KB in size.

yusuke $ esbuild --outdir=dist --bundle --minify ./src/index.ts

  dist/index.js  11.9kb

⚡ Done in 9ms

Presets: hono/tiny, hono/quick

Hono has several routers, each designed for a specific purpose. You can specify the router you want to use in the Hono constructor.

Presets are provided for common use cases, so you don't have to specify the router each time. The Hono class imported from all presets is the same, the only difference being the router. Therefore, you can use them interchangeably.

We introduce hono/tiny and hono/quick today.

hono/tiny

Preset hono/tiny means using only PatternRouter.

this.router = new PatternRouter()

To use hono/tiny, you only have to import hono/tiny and use Hono as usual.

import { Hono } from 'hono/tiny'

const app = new Hono()

//...

hono/quick

Preset hono/quick means using only LinearRouter.

this.router = new LinearRouter()

You can also use hono/quick like other presets.

import { Hono } from 'hono/quick'

Which preset should I use?

We now offer three presets: hono, hono/tiny, and hono/quick. You might be wondering, "Which preset should I use?" Please refer to the followings.

Preset Suitable platforms
hono This is highly recommended for most use cases. Although the registration phase may be slower than hono/quick, it exhibits high performance once booted. It's ideal for long-life servers built with Deno, Bun, or Node.js. For environments such as Cloudflare Workers, Deno Deploy, Lagon, where v8 isolates are utilized, this preset is suitable too. Because the isolates persist for a certain amount of time after booting.
hono/quick This preset is designed for environments where the application is initialized for every request. Fastly Compute@Edge operates in this manner, thus this preset is recommended for use it.
hono/tiny This is the smallest router package and is suitable for environments where resources are limited.

app.mount()

By using new feature app.mount(), you can integrate applications using other frameworks, such as itty-router, with Hono.

// Create itty-router application
const ittyRouter = IttyRouter()

// Handle `GET /itty-router/hello`
ittyRouter.get('/hello', () => new Response('Hello from itty-router!'))

// Hono application
const app = new Hono()

// Hono application
app.mount('/itty-router', ittyRouter.handle)

Also Remix:

import { Hono } from 'hono'
import { env } from 'hono/adapter'
import { serveStatic } from 'hono/cloudflare-workers'

import { createRequestHandler } from '@remix-run/cloudflare'
import * as build from './build'

// Remix application
// @ts-ignore
const handleRemixRequest = createRequestHandler(build, process.env.NODE_ENV)

// Hono application
const app = new Hono()

// Static files for Remix
app.get(
  '/remix/build/*',
  serveStatic({
    root: './',
  })
)

// Mount Remix app
app.mount('/remix', handleRemixRequest, (c) => {
  return { env: env(c) }
})

This implies that we can mount applications built with any framework, such as itty-router, Remix, Qwik, or SolidJS, into our Hono application.

Ecosystem

With this implementation, we introduce two concepts: adapt and mount. Adapt refers to Hono's ability to adapt to any runtime, while mount implies that Hono can integrate with any framework. Along with middleware, these capabilities allow us to create a comprehensive ecosystem, as depicted below:

SS

With these special features, Hono will not just be a web framework, it will be like a "Glue".

One of the greatest aspects of this concept is that the framework does not have to create individual adapters for various platforms such as Cloudflare Worker, Cloudflare Pages, Vercel, Deno, and Bun.

SS

If your framework is based on the Web Standard API, there is no additional work required. Hono can mount it and enable your framework to run on any runtime.

SS

Furthermore, we can use Hono's middleware for other frameworks. For example, to add Basic authentication to an application built with ittry-router, there's no need to implement it from scratch. Just add Hono's middleware.

app.use('/another-app/admin/*', basicAuth({ username, password }))

This is the ecosystem we wanted creating.

Node.js adapter server v1.0.0 has been released

The first major release of the Node.js adapter server, "v1.0.0", is now available! This version uses only the native Web Standard APIs available in Node.js v18 or higher. The size has been significantly reduced and this means we are really following to Web Standard APIs.

SS

You can start using it right away by installing it from npm.

npm install @hono/node-server

Then, simply import the serve function and adapt it to your Hono application.

import { serve } from '@hono/node-server'
import { Hono } from 'hono'

const app = new Hono()
app.get('/', (c) => c.text('Hono meets Node.js'))

serve(app, (info) => {
  console.log(`Listening on http://localhost:${info.port}`)
})

Support for routing includes a hostname

The new getPath() function now supports routing that includes a hostname.

const app = new Hono({
  getPath: (req) => req.url.replace(/^https?:\/\//, ''),
})

app.get('www1.example.com/hello', (c) => c.text('hello www1'))
app.get('www2.example.com/hello', (c) => c.text('hello www2'))

With getPath(), you can also handle the host header value for routing.

const app = new Hono({
  getPath: (req) => req.headers.get('host') + req.url.replace(/^https?:\/\/[^\/]+/, ''),
})

app.get('www1.example.com/hello', (c) => c.text('hello www1'))

// The following request will match the route:
// new Request('http://www1.example.com/hello', {
//  headers: { host: 'www1.example.com' },
// })

Support for AWS Lambda functions URLs

The AWS Lambda adapter now supports Lambda functions URLs.

Cookie Middleware

We're introducing a new Cookie Middleware.

import { getCookie, setCookie } from 'hono/cookie'

// ...

app.get('/cookie', (c) => {
  const yummyCookie = getCookie(c, 'yummy_cookie')
  // ...
  setCookie(c, 'delicious_cookie', 'macha')
  //
}

And c.req.cookie() and c.cookie() are deprecated and will be removed in the next major version, v4.

hono/nextjs to hono/vercel

We've created hono/vercel and deprecated hono/nextjs. hono/nextjs will be removed in v4.

Other updates

  • rewriteRequestPath option for the serve-static
  • app.routerName
  • Support for clearing response headers
  • Remove HTTP status messages from http-status.ts
  • Performance improvements
  • Bug fixes

Thanks

Thank you to all our contributors!

All changes

New Contributors

Full Changelog: v3.1.8...v3.2.0

Don't miss a new hono release

NewReleases is sending notifications on new releases.