Security News
PyPI Introduces Digital Attestations to Strengthen Python Package Security
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.
Hono is a small, simple, and fast web framework for building web applications and APIs in Node.js. It is designed to be lightweight and efficient, making it suitable for high-performance applications.
Basic Routing
Hono allows you to define routes for your web application. In this example, a basic GET route is defined that responds with 'Hello, Hono!' when accessed.
const { Hono } = require('hono');
const app = new Hono();
app.get('/', (c) => c.text('Hello, Hono!'));
app.listen(3000);
Middleware Support
Hono supports middleware, allowing you to execute code before your route handlers. This example demonstrates a simple logger middleware that logs the request method and URL.
const { Hono } = require('hono');
const app = new Hono();
const logger = (c, next) => {
console.log(`${c.req.method} ${c.req.url}`);
return next();
};
app.use(logger);
app.get('/', (c) => c.text('Hello, Hono!'));
app.listen(3000);
Error Handling
Hono provides a way to handle errors globally. In this example, an error is thrown in the route handler, and the global error handler responds with a 500 status code and a message.
const { Hono } = require('hono');
const app = new Hono();
app.get('/', (c) => {
throw new Error('Something went wrong!');
});
app.onError((err, c) => {
c.status(500);
return c.text('Internal Server Error');
});
app.listen(3000);
Express is a widely-used web framework for Node.js, known for its simplicity and flexibility. It offers a robust set of features for web and mobile applications, including routing, middleware support, and more. Compared to Hono, Express has a larger community and more extensive documentation, but Hono aims to be more lightweight and faster.
Koa is a web framework designed by the team behind Express. It aims to be a smaller, more expressive, and more robust foundation for web applications and APIs. Koa uses async functions to help eliminate callback hell and improve error handling. Compared to Hono, Koa is more modern and has a different approach to middleware, using a stack-like structure.
Fastify is a web framework highly focused on providing the best developer experience with the least overhead and a powerful plugin architecture. It is designed for high performance and low overhead. Compared to Hono, Fastify is more feature-rich and has a more extensive ecosystem, but Hono aims to be simpler and more lightweight.
Hono[炎] - means flame🔥 in Japanese - is small, simple, and ultrafast web flamework for a Service Workers API based serverless such as Cloudflare Workers and Fastly Compute@Edge.
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Hono!!'))
app.fire()
Hono is fastest compared to other routers for Cloudflare Workers.
hono x 708,671 ops/sec ±2.58% (58 runs sampled)
itty-router x 159,610 ops/sec ±2.86% (87 runs sampled)
sunder x 322,846 ops/sec ±2.24% (86 runs sampled)
worktop x 223,625 ops/sec ±2.01% (95 runs sampled)
Fastest is hono
✨ Done in 57.83s.
Below is a demonstration to create an application of Cloudflare Workers with Hono.
You can install from npm registry:
yarn add hono
or
npm install hono
Instance of Hono
has these methods:
app.HTTP_METHOD
// HTTP Methods
app.get('/', (c) => c.text('GET /'))
app.post('/', (c) => c.text('POST /'))
// Wildcard
app.get('/wild/*/card', (c) => {
return c.text('GET /wild/*/card')
})
app.all
// Any HTTP methods
app.all('/hello', (c) => c.text('Any Method /hello'))
app.get('/user/:name', (c) => {
const name = c.req.param('name')
...
})
app.get('/post/:date{[0-9]+}/:title{[a-z]+}', (c) => {
const date = c.req.param('date')
const title = c.req.param('title')
...
app
.route('/api/book')
.get(() => {...})
.post(() => {...})
.put(() => {...})
You can customize 404 Not Found response:
app.get('*', (c) => {
return c.text('Custom 404 Error', 404)
})
app.get('/fetch-url', async (c) => {
const response = await fetch('https://example.com/')
return c.text(`Status is ${response.status}`)
})
import { Hono, Middleware } from 'hono'
...
app.use('*', Middleware.poweredBy())
app.use('*', Middleware.logger())
app.use(
'/auth/*',
Middleware.basicAuth({
username: 'hono',
password: 'acoolproject',
})
)
Available builtin middleware are listed on src/middleware.
You can write your own middleware:
// Custom logger
app.use('*', async (c, next) => {
console.log(`[${c.req.method}] ${c.req.url}`)
await next()
})
// Add a custom header
app.use('/message/*', async (c, next) => {
await next()
await c.res.headers.add('x-message', 'This is middleware!')
})
app.get('/message/hello', (c) => c.text('Hello Middleware!'))
app.use('*', async (c, next) => {
try {
await next()
} catch (err) {
console.error(`${err}`)
c.res = c.text('Custom Error Message', { status: 500 })
}
})
You can also do this:
// Output response time
app.use('*', async (c, next) => {
await next()
const responseTime = await c.res.headers.get('X-Response-Time')
console.log(`X-Response-Time: ${responseTime}`)
})
// Add X-Response-Time header
app.use('*', async (c, next) => {
const start = Date.now()
await next()
const ms = Date.now() - start
await c.res.headers.append('X-Response-Time', `${ms}ms`)
})
To handle Request and Reponse easily, you can use Context object:
// Get Request object
app.get('/hello', (c) => {
const userAgent = c.req.headers.get('User-Agent')
...
})
// Shortcut to get a header value
app.get('/shortcut', (c) => {
const userAgent = c.req.header('User-Agent')
...
})
// Query params
app.get('/search', (c) => {
const query = c.req.query('q')
...
})
// Captured params
app.get('/entry/:id', (c) => {
const id = c.req.param('id')
...
})
app.get('/welcome', (c) => {
c.header('X-Message', 'Hello!')
c.header('Content-Type', 'text/plain')
c.status(201)
c.statusText('201 Content Created')
return c.body('Thank you for comming')
/*
Same as:
return new Response('Thank you for comming', {
status: 201,
statusText: '201 Content Created',
headers: {
'X-Message': 'Hello',
'Content-Type': 'text/plain',
'Content-Length: '22'
}
})
*/
})
Render text as Content-Type:text/plain
:
app.get('/say', (c) => {
return c.text('Hello!')
})
Render JSON as Content-Type:application/json
:
app.get('/api', (c) => {
return c.json({ message: 'Hello!' })
})
Render HTML as Content-Type:text/html
:
app.get('/', (c) => {
return c.html('<h1>Hello! Hono!</h1>')
})
Redirect, default status code is 302
:
app.get('/redirect', (c) => c.redirect('/'))
app.get('/redirect-permanently', (c) => c.redirect('/', 301))
// Response object
app.use('/', (c, next) => {
next()
c.res.headers.append('X-Debug', 'Debug message')
})
// FetchEvent object
app.use('*', async (c, next) => {
c.event.waitUntil(
...
)
await next()
})
// Environment object for Cloudflare Workers
app.get('*', async c => {
const counter = c.env.COUNTER
...
})
app.fire()
do:
addEventListener('fetch', (event) => {
event.respondWith(this.handleEvent(event))
})
app.fetch()
is for Cloudflare Module Worker syntax.
export default {
fetch(request: Request, env: Env, event: FetchEvent) {
return app.fetch(request, env, event)
},
}
/*
or just do this:
export default app
*/
Using wrangler
or miniflare
, you can develop the application locally and publish it with few commands.
Let's write your first code for Cloudflare Workers with Hono.
Install Cloudflare Command Line "Wrangler"
npm i @cloudflare/wrangler -g
npm init
Make npm skeleton directory.
mkdir hono-example
cd hono-example
npm init -y
wrangler init
Init as a wrangler project.
wrangler init
npm install hono
Install hono
from npm registry.
npm i hono
Only 4 lines!!
import { Hono } from 'hono'
const app = new Hono()
app.get('/', (c) => c.text('Hello! Hono!'))
app.fire()
Run the development server locally. Then, access like http://127.0.0.1:8787/
in your Web browser.
wrangler dev
Deploy to Cloudflare. That's all!
wrangler publish
Implementation of the router is inspired by goblin. API design is inspired by express and koa. itty-router, Sunder, and worktop are the other routers or frameworks for Cloudflare Workers.
Contributions Welcome! You can contribute by the following way:
If you can, let's make Hono together!
Yusuke Wada https://github.com/yusukebe
Distributed under the MIT License. See LICENSE for more information.
FAQs
Web framework built on Web Standards
The npm package hono receives a total of 178,687 weekly downloads. As such, hono popularity was classified as popular.
We found that hono demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PyPI now supports digital attestations, enhancing security and trust by allowing package maintainers to verify the authenticity of Python packages.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.