Hono v4.5.0 is now available!
We have added three new built-in middleware. Now Hono is bringing 20 built-in middleware!
- Basic Authentication
- Bearer Authentication
- Body Limit
- Cache
- Combine
- Compress
- CORS
- CSRF Protection
- ETag
- IP Restriction
- JSX Renderer
- JWT
- Logger
- Method Override
- Pretty JSON
- Request ID
- Secure Headers
- Timeout
- Timing
- Trailing Slash
Amazing! These truly make Hono batteries-included framework.
Let's go through the new features in this release.
IP Restrict Middleware
Introducing IP Restrict Middleware. This middleware limits access to resources based on the IP address of the user.
import { Hono } from 'hono'
import { getConnInfo } from 'hono/bun'
import { ipRestriction } from 'hono/ip-restriction'
const app = new Hono()
app.use(
'*',
ipRestriction(getConnInfo, {
denyList: [],
allowList: ['127.0.0.1', '::1']
})
)
Thanks @nakasyou!
Combine Middleware
Introducing Combine Middleware. This middleware combines multiple middleware functions into a single middleware, allowing you to create complex access controls by combining it with middleware like IP Restriction.
import { Hono } from 'hono'
import { bearerAuth } from 'hono/bearer-auth'
import { getConnInfo } from 'hono/cloudflare-workers'
import { every, some } from 'hono/combine'
import { ipRestriction } from 'hono/ip-restriction'
import { rateLimit } from '@/my-rate-limit'
const app = new Hono()
app.use(
'*',
some(
every(ipRestriction(getConnInfo, { allowList: ['192.168.0.2'] }), bearerAuth({ token })),
// If both conditions are met, rateLimit will not execute.
rateLimit()
)
)
app.get('/', (c) => c.text('Hello Hono!'))
Thanks @usualoma!
Request ID Middleware
Introducing Request ID Middleware. This middleware generates a unique ID for each request, which you can use in your handlers.
import { Hono } from 'hono'
import { requestId } from 'hono/request-id'
const app = new Hono()
app.use('*', requestId())
app.get('/', (c) => {
return c.text(`Your request id is ${c.get('requestId')}`)
})
Thanks @ryuapp!
Service Worker Adapter
A Service Worker adapter has been added, making it easier to run Hono applications as Service Workers.
For example, the following code works perfectly in a browser!
import { Hono } from 'hono'
import { handle } from 'hono/service-worker'
const app = new Hono().basePath('/sw')
app.get('/', (c) => c.text('Hello World'))
self.addEventListener('fetch', handle(app))
Thanks @nakasyou!
Cloudflare Pages Middleware
The Cloudflare Pages adapter now includes a handleMiddleware
function, allowing many Hono middleware to run as Cloudflare Pages middleware.
For example, to apply basic authentication, you can use the built-in middleware as shown below.
// functions/_middleware.ts
import { handleMiddleware } from 'hono/cloudflare-pages'
import { basicAuth } from 'hono/basic-auth'
export const onRequest = handleMiddleware(
basicAuth({
username: 'hono',
password: 'acoolproject'
})
)
Thanks @BarryThePenguin!
React 19 Compatibility
Hono JSX now supports React 19 compatible APIs.
For example, the following hooks have been added:
useFormStatus()
useActionState()
useOptimistic()
Additionally, rendering metadata within the <head />
tag is now supported. You can include elements like <title>
, <meta>
, and <link>
within your components.
import { Hono } from 'hono'
import { jsxRenderer } from 'hono/jsx-renderer'
const app = new Hono()
app.use(
jsxRenderer(({ children }) => {
return (
<html>
<head></head>
<body>{children}</body>
</html>
)
})
)
app.get('/top-page', (c) => {
return c.render(
<article>
<title>Top Page!</title>
<link rel="canonical" href="https://hono.dev/top-page" />
<h1>Top Page</h1>
<p>Hono is a great framework!</p>
</article>
)
})
The above will render the following HTML:
<!DOCTYPE html>
<html>
<head>
<title>Top Page!</title>
<link rel="canonical" href="https://hono.dev/top-page" />
</head>
<body>
<article>
<h1>Top Page</h1>
<p>Hono is a great framework!</p>
</article>
</body>
</html>
See all changes in this PR: #2960
Thanks @usualoma!
@hono/react-compat
Plus, with the new @hono/react-compat
, you can alias the react
or react-dom
used in your project to hono/jsx without any configuration.
npm install react@npm:@hono/react-compat react-dom@npm:@hono/react-compat
Passing interface
as Bindings
/Variables
You can now pass interface
to Bindings
or Variables
. This allows you to use the type definitions generated by the wrangler types
command directly.
interface Env {
MY_KV_NAMESPACE: KVNamespace
MY_VAR: string
MY_DB: D1Database
}
Previously, only type definitions using type
could be passed to Bindings
. Now, interfaces like the Env
example above can be used with generics.
const app = new Hono<{
Bindings: Env
}>()
Thanks @ottomated!
Other features
- JWT - use Signed Cookie in JWT Middleware #2989
- Vercel - add
getConnInfo
for Vercel Adapter #3085 - Lambda@Edge - add
getConnInfo
helper for Lambda@Edge #3099
All Updates
- feat(jsx/dom): export createRoot and hydrateRoot from jsx/dom/client as default by @usualoma in #2929
- feat(jsx/server): introduce
jsx/dom/server
module for compatibility withreact-dom/server
by @usualoma in #2930 - feat(jsx/dom): Improve compatibility React (useCallback, React.StrictMode) by @usualoma in #2944
- feat(jwt): Use Signed Cookie in JWT Middleware by @newarifrh in #2989
- React 19 compat by @yusukebe in #3048
- feat(adaptor): Remove
unknown
from AddressType by @yasuaki640 in #2958 - test(adapter/bun): fixed
conninfo.test.ts
by @yusukebe in #3059 - feat(jsx/dom): skip calculate children if props are the same by @usualoma in #3049
- feat(cloudflare-pages): Add Cloudflare Pages middleware handler by @BarryThePenguin in #3028
- fix(cloudflare-pages): Expose Cloudflare Pages type parameters by @BarryThePenguin in #3065
- fix(helper/conninfo): add
undefined
forAddressType
by @yusukebe in #3112 - feat(middleware): Introduce IP Restriction Middleware by @nakasyou in #2813
- fix(ip-restriction): return the named function by @yusukebe in #3113
- feat(vercel): add
getConnInfo
for vercel adapter by @promer94 in #3085 - fix(vercel): remove deprecated address type by @ryuapp in #3115
- feat(lambda-edge): add
getConnInfo
helper for Lambda@Edge by @yasuaki640 in #3099 - feat: Introduce Service Worker Adapter by @nakasyou in #3062
- feat(middleware): introduce Request ID middleware by @ryuapp in #3082
- feat(middleware/combine): Introduce combine middleware by @usualoma in #2941
- feat(types): allow passing
interface
s as Bindings / Variables by @ottomated in #3136 - chore: update comments in codes by @yusukebe in #3145
- fix(types): use
ContextVariableMap
inContext<any>
by @yusukebe in #3134 - feat(jsx): add global attributes to interface definition by @yasuaki640 in #3142
- fix(types): remove slow types by @yusukebe in #3147
- Next by @yusukebe in #3144
New Contributors
- @newarifrh made their first contribution in #2989
- @BarryThePenguin made their first contribution in #3028
- @promer94 made their first contribution in #3085
- @ottomated made their first contribution in #3136
Full Changelog: v4.4.13...v4.5.0