Skip to content

Releases: honojs/hono

v4.5.0

16 Jul 14:23
Compare
Choose a tag to compare

Hono v4.5.0 is now available!

We have added three new built-in middleware. Now Hono is bringing 20 built-in middleware!

  1. Basic Authentication
  2. Bearer Authentication
  3. Body Limit
  4. Cache
  5. Combine
  6. Compress
  7. CORS
  8. CSRF Protection
  9. ETag
  10. IP Restriction
  11. JSX Renderer
  12. JWT
  13. Logger
  14. Method Override
  15. Pretty JSON
  16. Request ID
  17. Secure Headers
  18. Timeout
  19. Timing
  20. 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

New Contributors

Full Changelog: v4.4.13...v4.5.0

v4.4.13

11 Jul 09:24
Compare
Choose a tag to compare

What's Changed

Full Changelog: v4.4.12...v4.4.13

v4.4.12

06 Jul 07:13
Compare
Choose a tag to compare

What's Changed

New Contributors

Full Changelog: v4.4.11...v4.4.12

v4.4.11

03 Jul 01:54
Compare
Choose a tag to compare

What's Changed

  • refactor: remove unnecessary async keyword from router tests by @K-tecchan in #3061
  • fix(validator): don't return a FormData if formData is cached by @yusukebe in #3067
  • fix(client): Add Query Parameter Support to WebSocket Client in hono/client by @naporin0624 in #3066
  • refactor(types): move HandlerInterface's (path, handler)s overloads down by @NamesMT in #3072
  • test(helper/dev): fix typo of test case name by @yasuaki640 in #3073
  • fix(stream): Fixed a problem that onAbort() is called even if request is normally closed in deno by @usualoma in #3079

New Contributors

Full Changelog: v4.4.10...v4.4.11

v4.4.10

29 Jun 22:55
Compare
Choose a tag to compare

What's Changed

  • chore(jsr): export JWT utils by @ryuapp in #3056
  • fix(streaming): call stream.abort() explicitly when request is aborted by @usualoma in #3042
  • fix(client): set Path as the default of Original by @m-shaka in #3058

New Contributors

Full Changelog: v4.4.9...v4.4.10

v4.5.0-rc.2

29 Jun 08:40
2d3bc55
Compare
Choose a tag to compare
v4.5.0-rc.2 Pre-release
Pre-release

This is a pre-release.

v4.4.9

27 Jun 09:23
Compare
Choose a tag to compare

What's Changed

  • perf(context): improve initializing Context by @yusukebe in #3046
  • fix(types): correct inferring env when routes channing by @yusukebe in #3051
  • docs: update the description of package.json and README by @yusukebe in #3052
  • fix(timing): prevent duplicate applications by @yusukebe in #3054

Full Changelog: v4.4.8...v4.4.9

v4.4.8

24 Jun 21:24
Compare
Choose a tag to compare

What's Changed

Full Changelog: v4.4.7...v4.4.8

v4.4.7

19 Jun 06:24
Compare
Choose a tag to compare

What's Changed

  • use correct return type for c.html depending on input by @asmadsen in #2973
  • test: test uncovered return statement by @yasuaki640 in #2985
  • test: Update request.test.ts to remove duplicate checks by @JoaquimLey in #2984
  • fix(types): env variables override ContextVariableMap by @KaelWD in #2987

New Contributors

Full Changelog: v4.4.6...v4.4.7

v4.4.6

13 Jun 22:09
Compare
Choose a tag to compare

What's Changed

  • fix(aws-lambda): handle multiple cookies in streaming responses by @KnisterPeter in #2926

Full Changelog: v4.4.5...v4.4.6