Что такое Hono
Hono — небольшой и быстрый веб-фреймворк для серверов на JavaScript и TypeScript. Он связывает адреса с функциями, разбирает данные запроса и помогает отправить ответ: текст, JSON или HTML. Курс написан для Hono 4 и TypeScript, основная платформа — Node.js 22 или новее.
Веб-стандарты
Главная особенность Hono — он построен на веб-стандартах. Запрос в нём — это объект Request, ответ — объект Response. Это те же классы, с которыми работает fetch() в браузере, они описаны в стандарте и есть во всех современных средах.
Весь Hono сводится к одной функции: она получает Request и возвращает Response.
// src/index.ts
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Привет, Hono!'))
// app.fetch — функция вида (request) => response
const res = await app.fetch(new Request('http://localhost/'))
console.log(await res.text()) // Привет, Hono!Здесь приложение вызвано напрямую, без сервера: в него передан запрос, обратно пришёл ответ. Именно так его вызывает любая платформа.
Рантаймы
Рантайм — программа, которая выполняет JavaScript на сервере. Раньше почти всегда это был Node.js, теперь их несколько, и Hono работает во всех:
| Рантайм | Как запускается Hono |
|---|---|
| Node.js | через пакет @hono/node-server |
| Bun | встроенный сервер Bun вызывает app.fetch |
| Deno | Deno.serve(app.fetch) |
| Cloudflare Workers | платформа сама вызывает app.fetch |
Код маршрутов при этом одинаковый. Меняется только файл, который запускает сервер. В курсе используется Node.js, об остальных платформах рассказывает урок о развёртывании.
Что будет в курсе
Сквозной пример — JSON API блога: статьи и комментарии к ним, плюс несколько HTML-страниц. По ходу курса вы разберёте:
- маршруты, параметры адреса и тело запроса;
- middleware — общие действия для многих маршрутов;
- проверку данных с библиотекой zod;
- HTML-страницы на JSX;
- базу данных SQLite;
- вход по JWT и cookie;
- тесты и развёртывание.
Hono и Express
Если вы знакомы с Express, многое покажется похожим: app.get(), middleware, app.use(). Разница в том, что обработчик Hono получает один объект контекста c и возвращает ответ через return, а не вызывает методы объекта res. Кроме того, Hono изначально написан на TypeScript и знает типы параметров, тела запроса и ответа.
Частая ошибка
В обработчике забывают return:
// src/index.ts
app.get('/', (c) => {
c.text('Привет') // ответ создан, но не возвращён
})Hono ждёт, что обработчик вернёт Response. Без return запрос завершится ошибкой 500, а в терминале появится сообщение Context is not finalized. Пишите return c.text(...) или стрелочную функцию без фигурных скобок.