# Hono Hono [炎] - Tiny web framework for Cloudflare Workers and others. ```js const { Hono } = require('hono') const app = new Hono() app.get('/', () => new Response('Hono!!')) app.fire() ``` ## Feature - Fast - the router is implemented with Trie-Tree structure. - Tiny - use only standard API. - Portable - zero dependencies. - Flexible - you can make your own middlewares. - Optimized - for Cloudflare Workers and Fastly Compute@Edge. ## Benchmark ``` hono x 813,001 ops/sec ±2.96% (75 runs sampled) itty-router x 160,415 ops/sec ±3.31% (85 runs sampled) sunder x 307,438 ops/sec ±4.77% (73 runs sampled) Fastest is hono ✨ Done in 37.03s. ``` ## Install ``` $ yarn add hono ``` or ```sh $ npm install hono ``` ## Methods - app.**HTTP_METHOD**(path, callback) - app.**all**(path, callback) - app.**route**(path) - app.**use**(path, middleware) ## Routing ### Basic `app.HTTP_METHOD` ```js // HTTP Methods app.get('/', () => new Response('GET /')) app.post('/', () => new Response('POST /')) // Wildcard app.get('/wild/*/card', () => { return new Response('GET /wild/*/card') }) ``` `app.all` ```js // Any HTTP methods app.all('/hello', () => new Response('ALL Method /hello')) ``` ### Named Parameter ```js app.get('/user/:name', (c) => { const name = c.req.params('name') ... }) ``` ### Regexp ```js app.get('/post/:date{[0-9]+}/:title{[a-z]+}', (c) => { const date = c.req.params('date') const title = c.req.params('title') ... ``` ### Chained Route ```js app .route('/api/book') .get(() => {...}) .post(() => {...}) .put(() => {...}) ``` ## Middleware ### Builtin Middleware ```js const { Hono, Middleware } = require('hono') ... app.use('*', Middleware.poweredBy) ``` ### Custom Middleware ```js const logger = async (c, next) => { console.log(`[${c.req.method}] ${c.req.url}`) next() } const addHeader = async (c, next) => { next() c.res.headers.add('x-message', 'This is middleware!') } app.use('*', logger) app.use('/message/*', addHeader) app.get('/message/hello', () => 'Hello Middleware!') ``` ### Custom 404 Response ```js const customNotFound = async (c, next) => { next() if (c.res.status === 404) { c.res = new Response('Custom 404 Not Found', { status: 404 }) } } app.use('*', customNotFound) ``` ## Context ### req ```js app.get('/hello', (c) => { const userAgent = c.req.headers('User-Agent') ... }) ``` ### res ```js app.use('/', async (c, next) => { next() await c.res.headers.append('X-Debug', 'Debug message') }) ``` ## Request ### query ```js app.get('/search', (c) => { const query = c.req.query('q') ... }) ``` ### params ```js app.get('/entry/:id', (c) => { const id = c.req.params('id') ... }) ``` ## Related projects - koa - express - oak - itty-router - Sunder - goblin ## Author Yusuke Wada ## License MIT