Skip to content
Skillv1.0.0

hono

Build ultra-fast web APIs and full-stack apps with Hono — runs on Cloudflare Workers, Deno, Bun, Node.js, and any WinterCG-compatible runtime.

by Sam-06060(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from Sam-06060/jarvis-assistant (modules/agent_skills/awesome-skills/playbooks/hono/SKILL.md). Install upstream with npx skills add Sam-06060/jarvis-assistant --skill hono. Copyright stays with the author.

Hono Web Framework

Overview

Hono (炎, "flame" in Japanese) is a small, ultrafast web framework built on Web Standards (Request/Response/fetch). It runs anywhere: Cloudflare Workers, Deno Deploy, Bun, Node.js, AWS Lambda, and any WinterCG-compatible runtime — with the same code. Hono's router is one of the fastest available, and its middleware system, built-in JSX support, and RPC client make it a strong choice for edge APIs, BFFs, and lightweight full-stack apps.

When to Use This Skill

  • Use when building a REST or RPC API for edge deployment (Cloudflare Workers, Deno Deploy)
  • Use when you need a minimal but type-safe server framework for Bun or Node.js
  • Use when building a Backend for Frontend (BFF) layer with low latency requirements
  • Use when migrating from Express but wanting better TypeScript support and edge compatibility
  • Use when the user asks about Hono routing, middleware, c.req, c.json, or hc() RPC client

How It Works

Step 1: Project Setup

Cloudflare Workers (recommended for edge):

npm create hono@latest my-api
# Select: cloudflare-workers
cd my-api
npm install
npm run dev    # Wrangler local dev
npm run deploy # Deploy to Cloudflare

Bun / Node.js:

mkdir my-api && cd my-api
bun init
bun add hono
// src/index.ts (Bun)
import { Hono } from 'hono';

const app = new Hono();

app.get('/', c => c.text('Hello Hono!'));

export default {
  port: 3000,
  fetch: app.fetch,
};

Step 2: Routing

import { Hono } from 'hono';

const app = new Hono();

// Basic methods
app.get('/posts', c => c.json({ posts: [] }));
app.post('/posts', c => c.json({ created: true }, 201));
app.put('/posts/:id', c => c.json({ updated: true }));
app.delete('/posts/:id', c => c.json({ deleted: true }));

// Route params and query strings
app.get('/posts/:id', async c => {
  const id = c.req.param('id');
  const format = c.req.query('format') ?? 'json';
  return c.json({ id, format });
});

// Wildcard
app.get('/static/*', c => c.text('static file'));

export default app;

Chained routing:

app
  .get('/users', listUsers)
  .post('/users', createUser)
  .get('/users/:id', getUser)
  .patch('/users/:id', updateUser)
  .delete('/users/:id', deleteUser);

Step 3: Middleware

Hono middleware works exactly like fetch interceptors — before and after handlers:

import { Hono } from 'hono';
import { logger } from 'hono/logger';
import { cors } from 'hono/cors';
import { bearerAuth } from 'hono/bearer-auth';

const app = new Hono();

// Built-in middleware
app.use('*', logger());
app.use('/api/*', cors({ origin: 'https://myapp.com' }));
app.use('/api/admin/*', bearerAuth({ token: process.env.API_TOKEN! }));

// Custom middleware
app.use('*', async (c, next) => {
  c.set('requestId', crypto.randomUUID());
  await next();
  c.header('X-Request-Id', c.get('requestId'));
});

Available built-in middleware: logger, cors, csrf, etag, cache, basicAuth, bearerAuth, jwt, compress, bodyLimit, timeout, prettyJSON, secureHeaders.

Step 4: Request and Response Helpers

app.post('/submit', async c => {
  // Parse body
  const body = await c.req.json<{ name: string; email: string }>();
  const form = await c.req.formData();
  const text = await c.req.text();

  // Headers and cookies
  const auth = c.req.header('authorization');
  const token = getCookie(c, 'session');

  // Responses
  return c.json({ ok: true });                        // JSON
  return c.text('hello');                             // plain text
  return c.html('<h1>Hello</h1>');                    // HTML
  return c.redirect('/dashboard', 302);              // redirect
  return new Response(stream, { status: 200 });       // raw Response
});

Step 5: Zod Validator Middleware

import { zValidator } from '@hono/zod-validator';
import { z } from 'zod';

const createPostSchema = z.object({
  title: z.string().min(1).max(200),
  body: z.string().min(1),
  tags: z.array(z.string()).default([]),
});

app.post(
  '/posts',
  zValidator('json', createPostSchema),
  async c => {
    const data = c.req.valid('json'); // fully typed
    const post = await db.post.create({ data });
    return c.json(post, 201);
  }
);

Step 6: Route Groups and App Composition

// src/routes/posts.ts
import { Hono } from 'hono';

const posts = new Hono();

posts.get('/', async c => { /* list posts */ });
posts.post('/', async c => { /* create post */ });
posts.get('/:id', async c => { /* get post */ });

export default posts;
// src/index.ts
import { Hono } from 'hono';
import posts from './routes/posts';
import users from './routes/users';

const app = new Hono().basePath('/api');

app.route('/posts', posts);
app.route('/users', users);

export default app;

Step 7: RPC Client (End-to-End Type Safety)

Hono's RPC mode exports route types that the hc client consumes — similar to tRPC but using fetch conventions:

// server: src/routes/posts.ts
import { Hono } from 'hono';
import { zValidator } from '@hono/zod-validator';
import { z } from 'zod';

const posts = new Hono()
  .get('/', c => c.json({ posts: [{ id: '1', title: 'Hello' }] }))
  .post(
    '/',
    zValidator('json', z.object({ title: z.string() })),
    async c => {
      const { title } = c.req.valid('json');
      return c.json({ id: '2', title }, 201);
    }
  );

export default posts;
export type PostsType = typeof posts;
// client: src/client.ts
import { hc } from 'hono/client';
import type { PostsType } from '../server/routes/posts';

const client = hc<PostsType>('/api/posts');

// Fully typed — autocomplete on routes, params, and responses
const { posts } = await client.$get().json();
const newPost = await client.$post({ json: { title: 'New Post' } }).json();

Examples

Example 1: JWT Auth Middleware

import { Hono } from 'hono';
import { jwt, sign } from 'hono/jwt';

const app = new Hono();
const SECRET = process.env.JWT_SECRET!;

app.post('/login', async c => {
  const { email, password } = await c.req.json();
  const user = await validateUser(email, password);
  if (!user) return c.json({ error: 'Invalid credentials' }, 401);

  const token = await sign({ sub: user.id, exp: Math.floor(Date.now() / 1000) + 3600 }, SECRET);
  return c.json({ token });
});

app.use('/api/*', jwt({ secret: SECRET }));
app.get('/api/me', async c => {
  const payload = c.get('jwtPayload');
  const user = await getUserById(payload.sub);
  return c.json(user);
});

export default app;

Example 2: Cloudflare Workers with D1 Database

// src/index.ts
import { Hono } from 'hono';

type Bindings = {
  DB: D1Database;
  API_TOKEN: string;
};

const app = new Hono<{ Bindings: Bindings }>();

app.get('/users', async c => {
  const { results } = await c.env.DB.prepare('SELECT * FROM users LIMIT 50').all();
  return c.json(results);
});

app.post('/users', async c => {
  const { name, email } = await c.req.json();
  await c.env.DB.prepare('INSERT INTO users (name, email) VALUES (?, ?)')
    .bind(name, email)
    .run();
  return c.json({ created: true }, 201);
});

export default app;

Example 3: Streaming Response

import { stream, streamText } from 'hono/streaming';

app.get('/stream', c =>
  streamText(c, async stream => {
    for (const chunk of ['Hello', ' ', 'World']) {
      await stream.write(chunk);
      await stream.sleep(100);
    }
  })
);

Best Practices

  • ✅ Use route groups (sub-apps) to keep handlers in separate files — app.route('/users', usersRouter)
  • ✅ Use zValidator for all request body, query, and param validation
  • ✅ Type Cloudflare Workers bindings with the Bindings generic: new Hono<{ Bindings: Env }>()
  • ✅ Use the RPC client (hc) when your frontend and backend share the same repo
  • ✅ Prefer returning c.json()/c.text() over new Response() for cleaner code
  • ❌ Don't use Node.js-specific APIs (fs, path, process) if you want edge portability
  • ❌ Don't add heavy dependencies — Hono's value is its tiny footprint on edge runtimes
  • ❌ Don't skip middleware typing — use generics (Variables, Bindings) to keep c.get() type-safe

Security & Safety Notes

  • Always validate input with zValidator before using data from requests.
  • Use Hono's built-in csrf middleware on mutation endpoints when serving HTML/forms.
  • For Cloudflare Workers, store secrets in wrangler.toml [vars] (non-secret) or wrangler secret put (secret) — never hardcode them in source.
  • When using bearerAuth or jwt, ensure tokens are validated server-side — do not trust client-provided user IDs.
  • Rate-limit sensitive endpoints (auth, password reset) with Cloudflare Rate Limiting or a custom middleware.

Common Pitfalls

  • Problem: Handler returns undefined — response is empty Solution: Always return a response from handlers: return c.json(...) not just c.json(...).

  • Problem: Middleware runs after the response is sent Solution: Call await next() before post-response logic; Hono runs code after next() as the response travels back up the chain.

  • Problem: c.env is undefined on Node.js Solution: Cloudflare env bindings only exist in Workers. Use process.env on Node.js.

  • Problem: Route not matching — gets a 404 Solution: Check that app.route('/prefix', subRouter) uses the same prefix your client calls. Sub-routers should not repeat the prefix in their own routes.

Related Skills

  • @cloudflare-workers-expert — Deep dive into Cloudflare Workers platform specifics
  • @trpc-fullstack — Alternative RPC approach for TypeScript full-stack apps
  • @zod-validation-expert — Detailed Zod schema patterns used with @hono/zod-validator
  • @nodejs-backend-patterns — When you need a Node.js-specific backend (not edge)

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/sam-06060-jarvis-assistant-hono/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

sam-06060-jarvis-assistant-hono.ocm.jsonjson
{
  "ocm": "1",
  "id": "sam-06060-jarvis-assistant-hono",
  "kind": "skill",
  "name": "hono",
  "description": "Build ultra-fast web APIs and full-stack apps with Hono — runs on Cloudflare Workers, Deno, Bun, Node.js, and any WinterCG-compatible runtime.",
  "publisher": "Sam-06060",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "general"
    ],
    "tags": [
      "skill-md",
      "hono",
      "edge",
      "cloudflare-workers",
      "bun",
      "deno",
      "api",
      "typescript",
      "web-standards",
      "github"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "Build ultra-fast web APIs and full-stack apps with Hono — runs on Cloudflare Workers, Deno, Bun, Node.js, and any WinterCG-compatible runtime."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "github",
      "repository": "https://github.com/Sam-06060/jarvis-assistant",
      "path": "modules/agent_skills/awesome-skills/playbooks/hono/SKILL.md",
      "ref": "a50a3aa6b39fb0e1b7db88bef1bfc9c93606e126",
      "url": "https://github.com/Sam-06060/jarvis-assistant/blob/a50a3aa6b39fb0e1b7db88bef1bfc9c93606e126/modules/agent_skills/awesome-skills/playbooks/hono/SKILL.md",
      "key": "Sam-06060/jarvis-assistant/modules/agent_skills/awesome-skills/playbooks/hono/SKILL.md"
    }
  },
  "instructions": "# Hono Web Framework\n\n## Overview\n\nHono (炎, \"flame\" in Japanese) is a small, ultrafast web framework built on Web Standards (`Request`/`Response`/`fetch`). It runs anywhere: Cloudflare Workers, Deno Deploy, Bun, Node.js, AWS Lambda, and any WinterCG-compatible runtime — with the same code. Hono's router is one of the fastest available, and its middleware system, built-in JSX support, and RPC client make it a strong choice for edge APIs, BFFs, and lightweight full-stack apps.\n\n## When to Use This Skill\n\n- Use when building a REST or RPC API for edge deployment (Cloudflare Workers, Deno Deploy)\n",
  "cost": {
    "context_tokens": 2499
  }
}

Fetch it by URL: GET /api/v1/registry/sam-06060-jarvis-assistant-hono/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.