NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #1282 most downloaded on npm
Web framework built on Web Standards
Last release today
29 Sep 2026
Ships on a steady schedule
a new release about every 2 weeks
Nearly every release is documented
notes for 60 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
5 years old
453 releases · first in 2021
One column per quarter.
This release includes a security fix for CSRF Protection Middleware. If you are using CSRF Protection Middleware, please upgrade this hono package imm…
This release includes a security fix for CSRF Protection Middleware. If you are using CSRF Protection Middleware, please upgrade this hono package immediately.
Before this release, a request without a Content-Type header can bypass the protection. This fix does not allow it. See: https://github.com/honojs/hono/security/advisories/GHSA-2234-fmw7-43wr
v2 by @yusukebe in https://github.com/honojs/hono/pull/3506Access-Control-Allow-Origin if there is no matching origin by @uki00a in https://github.com/honojs/hono/pull/3510Full Changelog: https://github.com/honojs/hono/compare/v4.6.4...v4.6.5
chore: upgrade dependencies by @yusukebe in https://github.com/honojs/hono/pull/3446
crypto-js from dev dependencies by @yusukebe in https://github.com/honojs/hono/pull/3447createMiddleware by @yusukebe in https://github.com/honojs/hono/pull/3498globalThis by @sapphi-red in https://github.com/honojs/hono/pull/3500override to toStringToBuffer in classes extending JSXNode by @yusukebe in https://github.com/honojs/hono/pull/3505Full Changelog: https://github.com/honojs/hono/compare/v4.6.3...v4.6.4
This release has many new features, but each feature is small, so we've released it as a patch release.
This release has many new features, but each feature is small, so we've released it as a patch release.
runtime_tests to runtime-tests by @yusukebe in https://github.com/honojs/hono/pull/3419every middleware work with short-circuiting middlewares by @paolostyle in https://github.com/honojs/hono/pull/3441renderToString by @usualoma in https://github.com/honojs/hono/pull/3432Full Changelog: https://github.com/honojs/hono/compare/v4.6.2...v4.6.3
chore(lint): ESLint v9 by @yusukebe in https://github.com/honojs/hono/pull/3393
Full Changelog: https://github.com/honojs/hono/compare/v4.6.1...v4.6.2
fix(build): improve addExtension esbuild plugin by @kt3k in https://github.com/honojs/hono/pull/3405
Full Changelog: https://github.com/honojs/hono/compare/v4.6.0...v4.6.1
One of the highlights of this release is the Context Storage Middleware. Let's introduce it.
Hono v4.6.0 is now available!
One of the highlights of this release is the Context Storage Middleware. Let's introduce it.
Many users may have been waiting for this feature. The Context Storage Middleware uses AsyncLocalStorage to allow handling of the current Context object even outside of handlers.
For example, let’s define a Hono app with a variable message: string.
type Env = {
Variables: {
message: string
}
}
const app = new Hono<Env>()
To enable Context Storage Middleware, register contextStorage() as middleware at the top and set the message value.
import { contextStorage } from 'hono/context-storage'
//...
app.use(contextStorage())
app.use(async (c, next) => {
c.set('message', 'Hello!')
await next()
})
getContext() returns the current Context object, allowing you to get the value of the message variable outside the handler.
import { getContext } from 'hono/context-storage'
app.get('/', (c) => {
return c.text(getMessage())
})
// Access the variable outside the handler.
const getMessage = () => {
return getContext<Env>().var.message
}
In the case of Cloudflare Workers, you can also access the Bindings outside the handler by using this middleware.
type Env = {
Bindings: {
KV: KVNamespace
}
}
const app = new Hono<Env>()
app.use(contextStorage())
const setKV = (value: string) => {
return getContext<Env>().env.KV.put('key', value)
}
Thanks @marceloverdijk !
c.env.eventContext in handleMiddleware https://github.com/honojs/hono/pull/3332WSContext https://github.com/honojs/hono/pull/3337Content-Encoding when stream is true https://github.com/honojs/hono/pull/3355precompressed option https://github.com/honojs/hono/pull/3366Promise<string> or (async) JSX.Element in streamSSE https://github.com/honojs/hono/pull/3344onFound option https://github.com/honojs/hono/pull/3396Full Changelog: https://github.com/honojs/hono/compare/v4.5.11...v4.6.0
fix(jsx): race condition in ErrorBoundary with event loop by @usualoma in https://github.com/honojs/hono/pull/3343
Twitter to X by @yusukebe in https://github.com/honojs/hono/pull/3354Full Changelog: https://github.com/honojs/hono/compare/v4.5.10...v4.5.11
chore(test): replace deprecated vitest type by @yasuaki640 in https://github.com/honojs/hono/pull/3338
Full Changelog: https://github.com/honojs/hono/compare/v4.5.9...v4.5.10
test(types): broken test in future versions of typescript by @m-shaka in https://github.com/honojs/hono/pull/3310
NO_COLOR by @ryuapp in https://github.com/honojs/hono/pull/3306type (MIME) attribute types by @ssssota in https://github.com/honojs/hono/pull/3305Full Changelog: https://github.com/honojs/hono/compare/v4.5.8...v4.5.9
This could cause unexpected behavior, leading to a vulnerability. If you are using the CSRF Protection Middleware, please upgrade to version 4.5.8 or…
Before this release, in versions 4.5.7 and below, the CSRF Protection Middleware did not treat requests including Content-Types with uppercase letters (e.g., Application/x-www-form-urlencoded) as potential attacks, allowing them to pass.
This could cause unexpected behavior, leading to a vulnerability. If you are using the CSRF Protection Middleware, please upgrade to version 4.5.8 or higher immediately.
For more details, see the report here: https://github.com/honojs/hono/security/advisories/GHSA-rpfr-3m35-5vx5
fix(jsx/dom): Fixed a bug that caused Script elements to turn into Style elements. by @usualoma in https://github.com/honojs/hono/pull/3294
target and formtarget attribute types by @ssssota in https://github.com/honojs/hono/pull/3299Full Changelog: https://github.com/honojs/hono/compare/v4.5.6...v4.5.7
fix(jsx): handle async component error explicitly and throw the error in the response by @usualoma in https://github.com/honojs/hono/pull/3274
Full Changelog: https://github.com/honojs/hono/compare/v4.5.5...v4.5.6
fix(jsx): allow null, undefined, and boolean to be returned from function component by @usualoma in https://github.com/honojs/hono/pull/3241
c.header by @nakasyou in https://github.com/honojs/hono/pull/3221c.header by @nakasyou in https://github.com/honojs/hono/pull/3255. and not end / by @yusukebe in https://github.com/honojs/hono/pull/3256Full Changelog: https://github.com/honojs/hono/compare/v4.5.4...v4.5.5
fix(jsx): corrects the type of 'draggable' attribute in intrinsic-elements.ts by @yasuaki640 in https://github.com/honojs/hono/pull/3224
param in ValidationTargets supports optional param by @yusukebe in https://github.com/honojs/hono/pull/3229Full Changelog: https://github.com/honojs/hono/compare/v4.5.3...v4.5.4
fix(validator): Add double quotation marks to multipart checker regex by @CPlusPatch in https://github.com/honojs/hono/pull/3195
application/json with a charset as JSON by @yusukebe in https://github.com/honojs/hono/pull/3199self.fetch correctly by @yusukebe in https://github.com/honojs/hono/pull/3200Full Changelog: https://github.com/honojs/hono/compare/v4.5.2...v4.5.3
fix(helper/adapter): don't check navigator is undefined by @yusukebe in https://github.com/honojs/hono/pull/3171
navigator is undefined by @yusukebe in https://github.com/honojs/hono/pull/3171navigator is undefined by @yusukebe in https://github.com/honojs/hono/pull/3173Full Changelog: https://github.com/honojs/hono/compare/v4.5.1...v4.5.2
chore: remove rimraf and use bun shell by @nakasyou in https://github.com/honojs/hono/pull/3146
@experimental from createApp by @yusukebe in https://github.com/honojs/hono/pull/3164query in ws by @yusukebe in https://github.com/honojs/hono/pull/3169Full Changelog: https://github.com/honojs/hono/compare/v4.5.0...v4.5.1
fix(vercel): remove deprecated address type by @ryuapp in https://github.com/honojs/hono/pull/3115
Hono v4.5.0 is now available!
We have added three new built-in middleware. Now Hono is bringing 20 built-in middleware!
Amazing! These truly make Hono batteries-included framework.
Let's go through the new features in this release.
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!
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!
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!
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!
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!
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: https://github.com/honojs/hono/pull/2960
Thanks @usualoma!
@hono/react-compatPlus, 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
interface as Bindings/VariablesYou 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!
getConnInfo for Vercel Adapter https://github.com/honojs/hono/pull/3085getConnInfo helper for Lambda@Edge https://github.com/honojs/hono/pull/3099jsx/dom/server module for compatibility with react-dom/server by @usualoma in https://github.com/honojs/hono/pull/2930unknown from AddressType by @yasuaki640 in https://github.com/honojs/hono/pull/2958conninfo.test.ts by @yusukebe in https://github.com/honojs/hono/pull/3059undefined for AddressType by @yusukebe in https://github.com/honojs/hono/pull/3112getConnInfo for vercel adapter by @promer94 in https://github.com/honojs/hono/pull/3085getConnInfo helper for Lambda@Edge by @yasuaki640 in https://github.com/honojs/hono/pull/3099interfaces as Bindings / Variables by @ottomated in https://github.com/honojs/hono/pull/3136ContextVariableMap in Context<any> by @yusukebe in https://github.com/honojs/hono/pull/3134Full Changelog: https://github.com/honojs/hono/compare/v4.4.13...v4.5.0
Nothing published for this version
Nothing published for this version
chore: update benchmark by @yusukebe in https://github.com/honojs/hono/pull/3102
string[] | File[] for RPC form value by @yusukebe in https://github.com/honojs/hono/pull/3117app.use(path, mw) return correct schema type by @yusukebe in https://github.com/honojs/hono/pull/3128Full Changelog: https://github.com/honojs/hono/compare/v4.4.12...v4.4.13
fix(aws-lambda): set cookies with comma is bugged by @NamesMT in https://github.com/honojs/hono/pull/3084
path when chaining after use by @yusukebe in https://github.com/honojs/hono/pull/3087download attribute is set to a boolean value. by @oon00b in https://github.com/honojs/hono/pull/3094@module docs by @yusukebe in https://github.com/honojs/hono/pull/3101Full Changelog: https://github.com/honojs/hono/compare/v4.4.11...v4.4.12
refactor: remove unnecessary async keyword from router tests by @K-tecchan in https://github.com/honojs/hono/pull/3061
hono/client by @naporin0624 in https://github.com/honojs/hono/pull/3066HandlerInterface's (path, handler)s overloads down by @NamesMT in https://github.com/honojs/hono/pull/3072Full Changelog: https://github.com/honojs/hono/compare/v4.4.10...v4.4.11
chore(jsr): export JWT utils by @ryuapp in https://github.com/honojs/hono/pull/3056
Full Changelog: https://github.com/honojs/hono/compare/v4.4.9...v4.4.10
perf(context): improve initializing Context by @yusukebe in https://github.com/honojs/hono/pull/3046
Context by @yusukebe in https://github.com/honojs/hono/pull/3046package.json and README by @yusukebe in https://github.com/honojs/hono/pull/3052Full Changelog: https://github.com/honojs/hono/compare/v4.4.8...v4.4.9
fix(jsx): add an explicit type by @yusukebe in https://github.com/honojs/hono/pull/3007
env for codecov GitHub Actions by @yusukebe in https://github.com/honojs/hono/pull/3010Full Changelog: https://github.com/honojs/hono/compare/v4.4.7...v4.4.8
use correct return type for c.html depending on input by @asmadsen in https://github.com/honojs/hono/pull/2973
Full Changelog: https://github.com/honojs/hono/compare/v4.4.6...v4.4.7
fix(aws-lambda): handle multiple cookies in streaming responses by @KnisterPeter in https://github.com/honojs/hono/pull/2926
Full Changelog: https://github.com/honojs/hono/compare/v4.4.5...v4.4.6
fix(cors): allow custom vary header by @fzn0x in https://github.com/honojs/hono/pull/2934
Hono to JSX and export JSX namespace by @yusukebe in https://github.com/honojs/hono/pull/2937app.route() required by @yusukebe in https://github.com/honojs/hono/pull/2945app.on() by @yusukebe in https://github.com/honojs/hono/pull/2946parseBody and remove unnecessary check by @yusukebe in https://github.com/honojs/hono/pull/2947Full Changelog: https://github.com/honojs/hono/compare/v4.4.4...v4.4.5
fix(typo): Fix typo in request.test.ts by @yasuaki640 in https://github.com/honojs/hono/pull/2899
Prettify as duplicated with Simplify by @NamesMT in https://github.com/honojs/hono/pull/2914never by @NamesMT in https://github.com/honojs/hono/pull/2915c.redirect() supports TypedResponse by @yusukebe in https://github.com/honojs/hono/pull/2908- and _ by @yusukebe in https://github.com/honojs/hono/pull/2910_ prefix to TypedResponse properties by @yusukebe in https://github.com/honojs/hono/pull/2917SimplifyDeepArray should now actually be "deep" by @NamesMT in https://github.com/honojs/hono/pull/2920text and html for coverage reporter by @yusukebe in https://github.com/honojs/hono/pull/2923types.ts for type definitions by @yusukebe in https://github.com/honojs/hono/pull/2924Full Changelog: https://github.com/honojs/hono/compare/v4.4.3...v4.4.4
ci: Update workflow name of release.yml by @siguici in https://github.com/honojs/hono/pull/2874
deno.land/x to JSR by @yusukebe in https://github.com/honojs/hono/pull/2879wrangler to workerd by @yusukebe in https://github.com/honojs/hono/pull/2888hono/quick and hono/tiny by @yusukebe in https://github.com/honojs/hono/pull/2892replaceRequest option for app.mount by @yusukebe in https://github.com/honojs/hono/pull/2852Full Changelog: https://github.com/honojs/hono/compare/v4.4.2...v4.4.3
fix: add return types of void function by @EdamAme-x in https://github.com/honojs/hono/pull/2870
Full Changelog: https://github.com/honojs/hono/compare/v4.4.1...v4.4.2
refactor(pretty-json): remove useless condition by @6km in https://github.com/honojs/hono/pull/2815
{ server: server } by @nakasyou in https://github.com/honojs/hono/pull/2812Full Changelog: https://github.com/honojs/hono/compare/v4.4.0...v4.4.1
Hono v4.4.0 is now available! Let's take a look at the new features.
Hono v4.4.0 is now available! Let's take a look at the new features.
Now, Hono is available on JSR - a new JavaScript/TypeScript registry! You can install the Hono package from JSR right now. If you want to run your Hono app on Deno, you can install it with the following command:
deno add @hono/hono
Then, use it in your code!
// main.ts
import { Hono } from '@hono/hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello JSR!'))
export default app
And run it:
deno serve main.ts
If you edit the deno.json and set the paths appropriately, the exact same code that you are familiar with will work in Deno, Cloudflare Workers, and Bun.
deno.json:
{
"imports": {
"hono": "jsr:@hono/hono@^4.4.0"
}
}
https://github.com/honojs/hono/assets/10682/e2269e61-60c4-418b-9e5b-acead219362c
JSR is not exclusive to Deno. You can use it with npm and Bun.
# npm
npx jsr add @hono/hono
# bun
bunx jsr add @hono/hono
And, removing "slow types" has improved the performance of TypeScript type inference.
With the introduction of JSR, the previous package publishing from deno.land/x will be obsolete.
The ConnInfo Helper is a helper helps you to get the connection information. For example, you can get the client's remote address easily.
import { Hono } from 'hono'
import { getConnInfo } from 'hono/deno' // For Deno
const app = new Hono()
app.get('/', (c) => {
const info = getConnInfo(c) // info is `ConnInfo`
return c.text(`Your remote address is ${info.remote.address}`)
})
export default app
Thank you for creating the feature, @nakasyou!
The Timeout Middleware is a middleware enables you to easily manage request timeouts in your application.
Here is a simple example:
import { Hono } from 'hono'
import { timeout } from 'hono/timeout'
const app = new Hono()
// Applying a 5-second timeout
app.use('/api', timeout(5000))
// Handling a route
app.get('/api/data', async (c) => {
// Your route handler logic
return c.json({ data: 'Your data here' })
})
Thank you for creating the feature, @watany-dev!
We are now trying to improve the JSDocs. In the PR, we've added the JSDocs for all middleware. Thank you, @goisaki!
getPath https://github.com/honojs/hono/pull/2714parseBody https://github.com/honojs/hono/pull/2675parseBody https://github.com/honojs/hono/pull/2771parseBody by @fzn0x in https://github.com/honojs/hono/pull/2675@cloudflare/workers-types by @yusukebe in https://github.com/honojs/hono/pull/2773c.req.param() by @usualoma in https://github.com/honojs/hono/pull/2780on condition for publish-to-jsr by @yusukebe in https://github.com/honojs/hono/pull/2786index.ts by @yusukebe in https://github.com/honojs/hono/pull/2793jsr.json by @yusukebe in https://github.com/honojs/hono/pull/2803v4.4.0 by @yusukebe in https://github.com/honojs/hono/pull/2769Full Changelog: https://github.com/honojs/hono/compare/v4.3.9...v4.4.0
Nothing published for this version
fix(middleware/jwt): fix incorrect assumption in jwt impl by @boehs in https://github.com/honojs/hono/pull/2775
Full Changelog: https://github.com/honojs/hono/compare/v4.3.10...v4.3.11
fix(secure-header): Replace NodeJS Buffer API by @watany-dev in https://github.com/honojs/hono/pull/2761
RETAINED_304_HEADERS by @yusukebe in https://github.com/honojs/hono/pull/2763Full Changelog: https://github.com/honojs/hono/compare/v4.3.9...v4.3.10
fix(factory): export CreateHandlersInterface by @yusukebe in https://github.com/honojs/hono/pull/2752
CreateHandlersInterface by @yusukebe in https://github.com/honojs/hono/pull/2752Full Changelog: https://github.com/honojs/hono/compare/v4.3.8...v4.3.9
test(validator): compatibility with Node.js v20.13.1 by @yusukebe in https://github.com/honojs/hono/pull/2682
v20.13.1 by @yusukebe in https://github.com/honojs/hono/pull/2682any by @fzn0x in https://github.com/honojs/hono/pull/2684Partial for the options by @yusukebe in https://github.com/honojs/hono/pull/2712Partial for the options by @yusukebe in https://github.com/honojs/hono/pull/2713ResponseInit to c.body by @codeflows in https://github.com/honojs/hono/pull/2690Full Changelog: https://github.com/honojs/hono/compare/v4.3.7...v4.3.8
doc(ssg): Define the default value for Content-Type by @watany-dev in https://github.com/honojs/hono/pull/2666
Full Changelog: https://github.com/honojs/hono/compare/v4.3.6...v4.3.7
feat(cache): improved customizability by @MathurAditya724 in https://github.com/honojs/hono/pull/2652
Files by @yusukebe in https://github.com/honojs/hono/pull/2665Full Changelog: https://github.com/honojs/hono/compare/v4.3.5...v4.3.6
refactor(context): remove some any by @yusukebe in https://github.com/honojs/hono/pull/2658
any by @yusukebe in https://github.com/honojs/hono/pull/2658fetch signature for better compatibility with deno serve by @usualoma in https://github.com/honojs/hono/pull/2661Full Changelog: https://github.com/honojs/hono/compare/v4.3.4...v4.3.5
chore: update the pull request template by @yusukebe in https://github.com/honojs/hono/pull/2647
Full Changelog: https://github.com/honojs/hono/compare/v4.3.3...v4.3.4
fix(types): relax the type of c.req.param() by @yusukebe in https://github.com/honojs/hono/pull/2613
c.req.param() by @yusukebe in https://github.com/honojs/hono/pull/2613@typescript-eslint/unbound-method by @yusukebe in https://github.com/honojs/hono/pull/2622createFactory() destruction by @yusukebe in https://github.com/honojs/hono/pull/2623form supports multiple values with foo[] by @yusukebe in https://github.com/honojs/hono/pull/2639Full Changelog: https://github.com/honojs/hono/compare/v4.3.2...v4.3.3
fix(types): correct inferring when Method has Endponts as Union by @yusukebe in https://github.com/honojs/hono/pull/2610
Full Changelog: https://github.com/honojs/hono/compare/v4.3.1...v4.3.2
fix(types): ToSchema compatibility by @NamesMT in https://github.com/honojs/hono/pull/2605
ToSchema compatibility by @NamesMT in https://github.com/honojs/hono/pull/2605Full Changelog: https://github.com/honojs/hono/compare/v4.3.0...v4.3.1
serveStatic exported by hono/cloudflare-workers has been deprecated. If you create an application which serves static asset files, use Cloudflare Page…
Hono v4.3.0 is now available! Let's take a look at the new features.
Thanks to @kosei28, @nakasyou, and @NamesMT, the RPC mode has been improved!
c.text() is typedThe response of c.text() was just a Response object, not typed.
const routes = app.get('/about/me', (c) => {
return c.text('Me!') // the response is not typed
})
With this release, it will be a TypedResponse and you can get the type within the client created by hc.
const client = hc<typeof routes>('http://localhost:8787')
const res = await client.about.me.$get()
const text = await res.text() // text is typed as "Me!"
const json = await res.json() // json is never!
We added the tests for the responses of c.json() to have the correct types and support inferring all primitives. The all tests below are passed!
const app = new Hono()
const route = app
.get('/api/string', (c) => c.json('a-string'))
.get('/api/number', (c) => c.json(37))
.get('/api/boolean', (c) => c.json(true))
.get('/api/generic', (c) => c.json(Math.random() > 0.5 ? Boolean(Math.random()) : Math.random()))
type AppType = typeof route
const client = hc<AppType>('http://localhost')
const stringFetch = await client.api.string.$get()
const stringRes = await stringFetch.json()
const numberFetch = await client.api.number.$get()
const numberRes = await numberFetch.json()
const booleanFetch = await client.api.boolean.$get()
const booleanRes = await booleanFetch.json()
const genericFetch = await client.api.generic.$get()
const genericRes = await genericFetch.json()
type stringVerify = Expect<Equal<'a-string', typeof stringRes>>
expect(stringRes).toBe('a-string')
type numberVerify = Expect<Equal<37, typeof numberRes>>
expect(numberRes).toBe(37)
type booleanVerify = Expect<Equal<true, typeof booleanRes>>
expect(booleanRes).toBe(true)
type genericVerify = Expect<Equal<number | boolean, typeof genericRes>>
expect(typeof genericRes === 'number' || typeof genericRes === 'boolean').toBe(true)
// using .text() on json endpoint should return string
type textTest = Expect<Equal<Promise<string>, ReturnType<typeof genericFetch.text>>>
If you explicitly specify the status code, such as 200 or 404, in c.json(). It will be added as a type for passing to the client.
// server.ts
const app = new Hono().get(
'/posts',
zValidator(
'query',
z.object({
id: z.string()
})
),
async (c) => {
const { id } = c.req.valid('query')
const post: Post | undefined = await getPost(id)
if (post === undefined) {
return c.json({ error: 'not found' }, 404) // Specify 404
}
return c.json({ post }, 200) // Specify 200
}
)
export type AppType = typeof app
You can get the data by the status code.
// client.ts
const client = hc<AppType>('http://localhost:8787/')
const res = await client.posts.$get({
query: {
id: '123'
}
})
if (res.status === 404) {
const data: { error: string } = await res.json()
console.log(data.error)
}
if (res.ok) {
const data: { post: Post } = await res.json()
console.log(data.post)
}
// { post: Post } | { error: string }
type ResponseType = InferResponseType<typeof client.posts.$get>
// { post: Post }
type ResponseType200 = InferResponseType<typeof client.posts.$get, 200>
The compatibility of hono/jsx/dom has been improved. Now, these React libraries work with hono/jsx/dom!
The below demo is working with hono/jsx/dom, not React.
If you want to use React libraries with hono/jsx/dom, set-up tsconfig.json and vite.config.ts like the followings:
tsconfig.json:
{
"compilerOptions": {
"paths": {
"react": ["./node_modules/hono/dist/jsx/dom"],
"react-dom": ["./node_modules/hono/dist/jsx/dom"]
}
}
}
vite.config.ts:
import { defineConfig } from 'vite'
export default defineConfig({
resolve: {
alias: {
react: 'hono/jsx/dom',
'react-dom': 'hono/jsx/dom'
}
}
})
Thanks @usualoma!
createApp() in Factory HelpercreateApp() method is added to Factory Helper. If you use this method with createFactory(), you can avoid redundancy in the definition of the Env type.
If your application is like this, you have to set the Env in two places:
import { createMiddleware } from 'hono/factory'
type Env = {
Variables: {
myVar: string
}
}
// 1. Set the `Env` to `new Hono()`
const app = new Hono<Env>()
// 2. Set the `Env` to `createMiddleware()`
const mw = createMiddleware<Env>(async (c, next) => {
await next()
})
app.use(mw)
By using createFactory() and createApp(), you can set the Env only in one place.
import { createFactory } from 'hono/factory'
// ...
// Set the `Env` to `createFactory()`
const factory = createFactory<Env>()
const app = factory.createApp()
// factory also has `createMiddleware()`
const mw = factory.createMiddleware(async (c, next) => {
await next()
})
serveStatic for Cloudflare WorkersserveStatic exported by hono/cloudflare-workers has been deprecated. If you create an application which serves static asset files, use Cloudflare Pages instead.
headerName option https://github.com/honojs/hono/pull/2514crossOrigin in TimingOptions to be a function https://github.com/honojs/hono/pull/2359init option https://github.com/honojs/hono/pull/2592headerName option by @eliasbrange in https://github.com/honojs/hono/pull/2514serveStatic by @yusukebe in https://github.com/honojs/hono/pull/2583ToSchema & WebSocket Helper types by @NamesMT in https://github.com/honojs/hono/pull/2588createApp() by @yusukebe in https://github.com/honojs/hono/pull/2573init option by @NamesMT in https://github.com/honojs/hono/pull/2592Full Changelog: https://github.com/honojs/hono/compare/v4.2.9...v4.3.0
fix(context): correct set-cookie header values if c.res is set by @yusukebe in https://github.com/honojs/hono/pull/2570
Full Changelog: https://github.com/honojs/hono/compare/v4.2.8...v4.2.9
fix(types): useState() has no type errors without arguments by @ryuapp in https://github.com/honojs/hono/pull/2548
Full Changelog: https://github.com/honojs/hono/compare/v4.2.7...v4.2.8
This release fixes "Restricted Directory Traversal in serveStatic with deno".
This release fixes "Restricted Directory Traversal in serveStatic with deno".
Full Changelog: https://github.com/honojs/hono/compare/v4.2.6...v4.2.7
refactor(adapter/aws): Optimize multiple call of same conditions with polymorphism by @exoego in https://github.com/honojs/hono/pull/2521
$ws when not used WebSockets by @nakasyou in https://github.com/honojs/hono/pull/2532Full Changelog: https://github.com/honojs/hono/compare/v4.2.5...v4.2.6
fix(client): Allow calling toString and valueOf on the proxy object by @ibash in https://github.com/honojs/hono/pull/2510
Full Changelog: https://github.com/honojs/hono/compare/v4.2.4...v4.2.5
fix(jwt): Make JWT Header typ Field Optional to Enhance Compatibility by @naporin0624 in https://github.com/honojs/hono/pull/2488
typ Field Optional to Enhance Compatibility by @naporin0624 in https://github.com/honojs/hono/pull/2488baseUrl for testClient by @yusukebe in https://github.com/honojs/hono/pull/2496OutputTypeExcludeResponseType when InputType is unknown by @nagasawaryoya in https://github.com/honojs/hono/pull/2500Full Changelog: https://github.com/honojs/hono/compare/v4.2.3...v4.2.4
fix(ssg): use response header to mark as disabled routes for SSG by @usualoma in https://github.com/honojs/hono/pull/2477
package.json correctly by @yusukebe in https://github.com/honojs/hono/pull/2483Full Changelog: https://github.com/honojs/hono/compare/v4.2.2...v4.2.3
feat(jsx-renderer): pass the context as 2nd arg by @yusukebe in https://github.com/honojs/hono/pull/2459
null correctly by @yusukebe in https://github.com/honojs/hono/pull/2469Full Changelog: https://github.com/honojs/hono/compare/v4.2.1...v4.2.2
fix(jws): Only import necessary helper (not all helpers) by @nicksrandall in https://github.com/honojs/hono/pull/2458
Full Changelog: https://github.com/honojs/hono/compare/v4.2.0...v4.2.1
Hono v4.2.0 is now available! Let's take a look at the new features.
Hono v4.2.0 is now available! Let's take a look at the new features.
The number of algorithms that JWT util can handle has increased from only 3 to 13! This means that JWT util now implements many of the algorithms supported by JWT.
You can use these algorithms from the JWT middleware or JWT helpers. Thanks @Code-Hex!
Method Override Middleware has been added. This middleware override the method of the real request with the specified method.
HTML form does not allow you to send a DELETE method request. Instead, by sending an input with name as _method and a value of DELETE, you can call the handler registered in app.delete().
const app = new Hono()
// If no options are specified, the value of `_method` in the form,
// e.g. DELETE, is used as the method.
app.use('/posts', methodOverride({ app }))
app.delete('/posts', (c) => {
// ....
})
Trailing Slash Middleware resolves the handling of Trailing Slashes in GET requests. You can use appendTrailingSlash and trimTrailingSlash functions.
For example, it redirects a GET request to /about/me to /about/me/.
import { Hono } from 'hono'
import { appendTrailingSlash } from 'hono/trailing-slash'
const app = new Hono({ strict: true })
app.use(appendTrailingSlash())
app.get('/about/me/', (c) => c.text('With Trailing Slash'))
Thanks @rnmeow!
extensionMap https://github.com/honojs/hono/pull/2382userId hook https://github.com/honojs/hono/pull/2389payload https://github.com/honojs/hono/pull/2424options.origin function https://github.com/honojs/hono/pull/2436vary header option https://github.com/honojs/hono/pull/2426cause option https://github.com/honojs/hono/pull/2224NO_COLOR https://github.com/honojs/hono/pull/2228JwtTokenInvalid object as cause when JWT is invalid https://github.com/honojs/hono/pull/2448verifyToken option https://github.com/honojs/hono/pull/2449verifyUser option https://github.com/honojs/hono/pull/2450extentionMap by @watany-dev in https://github.com/honojs/hono/pull/2382payload by @nakasyou in https://github.com/honojs/hono/pull/2424vary header in cache middleware by @naporin0624 in https://github.com/honojs/hono/pull/2426crypto if not exist by @yusukebe in https://github.com/honojs/hono/pull/2445alg option value by @yusukebe in https://github.com/honojs/hono/pull/2446; by @yusukebe in https://github.com/honojs/hono/pull/2447JwtTokenInvalid object as cause when JWT is invalid by @yusukebe in https://github.com/honojs/hono/pull/2448verifyToken option by @yusukebe in https://github.com/honojs/hono/pull/2449verifyUser option by @yusukebe in https://github.com/honojs/hono/pull/2450Full Changelog: https://github.com/honojs/hono/compare/v4.1.7...v4.2.0
Nothing published for this version
fix(cache): check globalThis.caches by @yusukebe in https://github.com/honojs/hono/pull/2444
globalThis.caches by @yusukebe in https://github.com/honojs/hono/pull/2444Full Changelog: https://github.com/honojs/hono/compare/v4.1.6...v4.1.7
chore(benchmark): add "loop" script by @yusukebe in https://github.com/honojs/hono/pull/2431
caches is not defined by @yusukebe in https://github.com/honojs/hono/pull/2443Full Changelog: https://github.com/honojs/hono/compare/v4.1.5...v4.1.6
Your coding agent can read these notes before it upgrades. Set up the MCP server →