AI Workshop: learn to build apps with AI →
Hono: JSX templates

Join the AI Workshop and learn to build real-world apps with AI. A hands-on, practical program to level up your skills.


You can render HTML with c.html(). Hono also lets you write responses as JSX, which works well for mixing HTML and data.

JSX was introduced by React and is now used in many libraries. Here, Hono uses it on the server to generate HTML. No React runtime is involved—only the JSX-to-HTML transform.

To use JSX, add this at the top of your entry file:

/** @jsx jsx */
import { jsx } from 'hono/jsx'

Now we can use JSX in our Hono responses:

app.get('/', (c) => {
  const numbers = ['one', 'two', 'three']

  return c.html(
    <html>
      <head>
        <title>test</title>
      </head>
      <body>
        <h1>test</h1>
        {numbers.map((num) => (
          <p>{num}</p>
        ))}
      </body>
    </html>
  )
})

If you have not used JSX before, note that you no longer need template literals or manual HTML string building:

${numbers.map((num) => '<p>' + num + '</p>').join('\n')}

Data is embedded with the {expression} syntax. You can also build component-based UIs. Define a component, for example Numbers:

const Numbers = () => {
  const numbers = ['one', 'two', 'three']

  return (
    <div>
      {numbers.map((num) => (
        <p>{num}</p>
      ))}
    </div>
  )
}

and use it in the handler:

app.get('/', (c) => {
  return c.html(
    <html>
      <head>
        <title>test</title>
      </head>
      <body>
        <h1>test</h1>
        <Numbers />
      </body>
    </html>
  )
})

You can pass data as props:

const Numbers = ({ numbers }) => {
  return (
    <div>
      {numbers.map((num) => (
        <p>{num}</p>
      ))}
    </div>
  )
}

app.get('/', (c) => {
  const numbers = ['one', 'two', 'three']

  return c.html(
    <html>
      <head>
        <title>test</title>
      </head>
      <body>
        <h1>test</h1>
        <Numbers numbers={numbers} />
      </body>
    </html>
  )
})

You can move components to separate files as the app grows.

The syntax is similar to React, but this runs on the server, so you cannot use useState, useEffect, or other client-side APIs. It is still a good way to build server-rendered HTML.

Lessons in this unit:

0: Introduction
1: Your first Hono app
2: The Request object
3: Send a response to the client
4: Manage cookies
5: Work with HTTP headers
6: Handling redirects
7: Routing
8: ▶︎ JSX templates
9: Middleware
10: Hono on Node.js