hono-pino
v0.10.3
Published
A pino logger plugin for hono
Readme
Hono + Pino
A pino logger plugin for hono.
Features
- Fast, minimal overhead logging for Hono
- Full pino compatibility
- Works in Node.js and browser
- Custom transports, including a built-in pretty/debug transport
- TypeScript support
Table of Contents
This repository is inspired by pino-http and nestjs-pino.
Runtime Support
[!IMPORTANT] This package uses pino. Pino is designed for Node.js and supports browser environments.
For edge environments (e.g. Cloudflare Workers), some advanced pino features may not work.
If fixing these issues is feasible, I will make an effort to implement it, but I cannot guarantee this.
Known issues:
transports: Alternative -> browser.write
Installation
# npm
npm install hono-pino pino
# pnpm
pnpm add hono-pino pino
# bun
bun add hono-pino pinoUsage
import { Hono } from 'hono'
import { pinoLogger } from 'hono-pino'
const app = new Hono()
.use(
pinoLogger({
pino: {level: "debug"}
}),
)
.get((c) => {
const { logger } = c.var;
const token = c.req.header("Authorization") ?? "";
logger.debug({ token });
const user = getAuthorizedUser(token);
logger.assign({ user });
const posts = getPosts();
logger.assign({ posts });
logger.setResMessage("Get posts success"); // optional
return c.text("");
});
await app.request("/", {
headers: {
Authorization: "Bearer token",
},
});
// output (formatted for easier reading)
{"level":20, "token":"Bearer token"}
{
"level": 30,
"msg": "Get posts success",
"user": {
"id": 1,
"name": "john"
},
"posts": [
{
"id": 1,
"title": "My first post"
},
{
"id": 2,
"title": "My second post"
}
],
"req": {
"headers": {
"authorization": "Bearer token"
},
"method": "GET",
"url": "/"
},
"reqId": 1,
"res": {
"headers": {},
"status": 200
},
"responseTime": 2
}Example
See examples
hono-pino/debug-log Transport
hono-pino/debug-log is a lightweight pino transport designed for development and debugging. It makes logs more readable, similar to pino-pretty, but with a focus on simplicity and customization.

Options
colorEnabled: Enable or disable color output (true|false|undefinedfor auto)messageKey: The key for the log message (default:msg)requestKey: The key for the request object (default:req)responseKey: The key for the response object (default:res)levelLabelMap: Map of log level numbers to their string labelsnormalLogFormat: Format string for normal logs (default:[{time}] {levelLabel} - {msg})httpLogFormat: Format string for HTTP logs (default:[{time}] {reqId} {req.method} {req.url} {res.status} ({responseTime}ms) - {msg} {bindings})timeFormatter: Function to format the time value (default:defaultTimeFormatter)bindingsFormatter: Function to format the context (bindings) (default:defaultBindingsFormat)levelFormatter: Function to format the log level label (default:defaultLevelFormatter)printer: Function to print the final log output (default:console.log)
See all options in src/debug-log/types.d.ts
Basic Usage (Node.js)
import pino from "pino";
import { Hono } from "hono";
import { pinoLogger } from "hono-pino";
import type { DebugLogOptions } from "hono-pino/debug-log";
const options: DebugLogOptions = {
// options...
};
const app = new Hono().use(
pinoLogger({
pino: pino({
base: null,
level: "trace",
transport: {
target: "hono-pino/debug-log",
options,
},
timestamp: pino.stdTimeFunctions.unixTime, // hh:mm:ss
// or
// timestamp: pino.stdTimeFunctions.epochTime, // hh:mm:ss.sss
}),
})
);Basic Usage (Browser)
import pino from "pino";
import { Hono } from "hono";
import { pinoLogger } from "hono-pino";
import { createHandler as debugLog } from "hono-pino/debug-log";
const app = new Hono().use(
pinoLogger({
pino: pino({
level: "trace",
browser: {
write: debugLog({
...options
}),
},
}),
})
);Options & Types
View the full options on GitHub or JSR
Logger Methods
class PinoLogger {
// Same as pino[logger level]
trace: pino.LogFn
debug: pino.LogFn
info: pino.LogFn
warn: pino.LogFn
error: pino.LogFn
fatal: pino.LogFn
// Get bindings (object)
bindings(): pino.Bindings
// Reset bindings
resetBindings(): void
// Assign bindings (default shallow merge)
assign(
bindings: pino.Bindings
opts?: {
/** deep merge */
deep?: boolean;
},
): void
}Contributing
Contributions, issues and feature requests are welcome! Feel free to check issues page or submit a pull request.
License
This project is MIT licensed.
API Documentation
See the full API docs at jsr.io/@maou-shonen/hono-pino
