Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
実用!Hono RPC2026
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
yodaka
April 22, 2026
Programming
400
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
実用!Hono RPC2026
yodaka
April 22, 2026
More Decks by yodaka
See All by yodaka
Honoとフロントエンドの 型安全性について
yodaka
9
3.4k
Other Decks in Programming
See All in Programming
AI駆動開発を妨げる技術的負債の解消アプローチ / ai-refactoring-approach
minodriven
12
5.9k
Developing with AI Agents — Codex, Claude Code & Cowork Practical Guide
x5gtrn
PRO
0
1.3k
LLMによるContent Moderationの本番運用の裏側と品質担保への挑戦
suikabar
3
740
ローカルLLMを使ってB2Bサービスを作っていての学び
yaotti
0
210
肥大化するレガシーコードに立ち向かうためのインターフェース分離と依存の逆転 / JJUG CCC 2026 Spring
hirokunimaeta
0
610
Signal Forms: Details & Live Coding @enterJS 2026 in Mannheim
manfredsteyer
PRO
0
190
The NotImplementedError Problem in Ruby
koic
1
920
Honoでのサプライチェーン侵害対策 〜 3つのライブラリに学ぶ
yusukebe
7
1.4k
The ROI of Quarkus for Spring Boot Applications
hollycummins
0
140
ふつうのFeature Flag実践入門
irof
8
4.2k
Agentic UI
manfredsteyer
PRO
0
190
AIで効率化できた業務・日常
ochtum
0
140
Featured
See All Featured
Leading Effective Engineering Teams in the AI Era
addyosmani
9
2.1k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
2
870
ReactJS: Keep Simple. Everything can be a component!
pedronauck
666
130k
The World Runs on Bad Software
bkeepers
PRO
72
12k
How to train your dragon (web standard)
notwaldorf
97
6.7k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
310
RailsConf 2023
tenderlove
30
1.5k
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
310
Navigating Weather and Climate Data
rabernat
0
230
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.2k
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
2
1.6k
Context Engineering - Making Every Token Count
addyosmani
9
980
Transcript
🔥 LT — Hono RPC 実用! Hono RPC2026 TypeScript でAPI
開発するなら知っておきたいRPC tRPC / oRPC / Hono RPC yodaka 2026.04.21
ABOUT ME 自己紹介 ALBUM · yo_gen ▶ よだか yodaka →
フリーランスWeb Developer → Next.js / Hono / TypeScript / Flutter / Vue.js → TSKaigiスタッフ → 最近は型パズルと音楽制作 —ギターロック好き必聴のアルバム作りました。聴い てね STAFF · TSKAIGI 2026 TSKaigi 2026 ベルサール羽田空港 2026.05.22—23 2 DAYS 実用!Hono RPC 2026 / yodaka 01 / 19
TODAY'S TAKEAWAY Hono RPCの強みは Honoの上で成り立っている ことにある 実用!Hono RPC 2026 /
yodaka 02 / 19
AGENDA 今日はなす5つのこと 01 Hono RPCとは何か(さくっと) 02 今日の題材 — 予約アプリの構成 03
RPCで型を渡す — Next.js 側 04 OpenAPIで型を渡す — Flutter 側 05 推しポイント 実用!Hono RPC 2026 / yodaka 03 / 19
00 — BEFORE RPC そもそもHonoとは Web標準ベースの、小さくて速いフレームワーク • ランタイム差異を吸収するポータビリティ Cloudflare Workers,
Fastly Compute, Deno, Bun, AWS Lambda,... • Web標準 https://wintercg.org/ (WinterTC) • 軽量・高速 Hono x 402,820 ops/sec ±4.78% (80 runs sampled) hono/tiny preset is under 14kB. Zero dependencies. Web Standards only. • 豊富なミドルウェア、カスタマイズ性 CORS、CSRF、JWT、Logger… • RPCやミドルウェアを使った、フロントエンドとの型共有 import { Hono } from 'hono' const app = new Hono() app.get('/', c => c.text('Hello Hono!') ) app.get('/health', c => c.json({ ok: true }) ) export default app 実用!Hono RPC 2026 / yodaka 04 / 19
01 — HONO RPC Hono RPCとは Hono本体の、フロントエンドへの型共有の仕組み • Honoのルーターの型をそのままクライアントへ •
hc<AppType>() で呼び出し • パス・リクエスト・レスポンスまで型がつく • コード生成なし・ランタイムへの影響ほぼゼロ // server import { Hono } from 'hono' const app = new Hono() .get('/posts/:id', c => c.json({ id: c.req.param('id') }) ) export type AppType = typeof app // client import { hc } from 'hono/client' const client = hc<AppType>(baseUrl) const res = await client.posts[':id'] .$get({ param: { id: '1' } }) 実用!Hono RPC 2026 / yodaka 05 / 19
02 — PROJECT 今日の題材は、ある予約アプリ 飲食店の店舗と来店者が使うシステムをひとつのHonoで捌く WEB Next.js 来店者向け ADMIN Next.js
店舗管理画面 APP Flutter 来店者ネイティブ pnpm monorepo │ Hono on ECS (Node.js) │ 3 front-ends → 1 Hono 実用!Hono RPC 2026 / yodaka 06 / 19
02 — PROJECT 型の渡し方は、クライアントごとに2通り Hono ROUTER + TYPES Next.js (Web)
来店者向け Next.js (Admin) 店舗向け Flutter ネイティブアプリ RPC (hc) RPC (hc) OpenAPI 実用!Hono RPC 2026 / yodaka 07 / 19
03 — RPC APIを定義する Standard Schema Validatorを使えば、ハンドラ内に型がつく BACKEND/SRC/ADMIN.TS import {
Hono } from 'hono' import { sValidator } from '@hono/standard-validator' import { z } from 'zod' export const adminRouter = new Hono() .post( '/posts', sValidator('json', z.object({ title: z.string(), body: z.string(), })), (c) => { // ↓ title: string, body: string に推論される const { title, body } = c.req.valid('json') return c.json({ ok: true }) } ) 実用!Hono RPC 2026 / yodaka 08 / 19
03 — RPC sValidator(Standard Schema) v4.7.0〜: Zod / Valibot /
ArkType を同じ記法で扱える共通バリデーター • 以前はZod Validatorで書いていた Zodにロックインされ、RPCとOpenAPIで書き味も分かれていた • v4.7.0で @hono/standard-validator 登場 Standard Schema という共通インターフェース経由で統一 • Zod / Valibot / ArkType を同じ sValidator で ライブラリ選定に縛られず、ハンドラ内の型も同じように推論 MIXING ZOD + VALIBOT import { sValidator } from '@hono/standard-validator' import { z } from 'zod' import * as v from 'valibot' app.get('/:slug', sValidator('param', v.object({ slug: v.string(), })), sValidator('query', z.object({ name: z.string(), })), (c) => { // ↓ どちらも型付きで取れる const { slug } = c.req.valid('param') const { name } = c.req.valid('query') return c.json({ slug, name }) } ) 実用!Hono RPC 2026 / yodaka 09 / 19
03 — RPC 型をエクスポートする ルーターの型をそのまま外に出すだけ BACKEND/SRC/INDEX.TS import { adminRouter, webRouter,
spRouter } from './routers' const app = new Hono() .route('/sp', spRouter) .route('/web', webRouter) .route('/admin', adminRouter) // 👇 これがクライアントに渡る" 契約" export type AdminAppType = typeof adminRouter export type WebAppType = typeof webRouter pnpm workspace なので、フロントからは import type で拾うだけ。 実用!Hono RPC 2026 / yodaka 10 / 19
03 — RPC クライアントで型を受け取る hc に型を渡すだけで、型安全なAPIクライアントの出来上がり FRONTEND/LIB/CLIENT.TS import { hc
} from 'hono/client' import type { AdminAppType } from 'backend/src' export const client = hc< AdminAppType >(baseUrl, { headers: { authorization: `Bearer ${token}` }, }) 実用!Hono RPC 2026 / yodaka 11 / 19
03 — RPC 呼び出しも、ぜんぶ型安全 FRONTEND/APP/POSTS/PAGE.TSX const res = await client.
posts.$post ({ json: { // ↓ title/body がサジェスト、型が違うと怒られる title: 'Hello', body: 'Hono is a cool project', }, }) if (res.ok) { const data = await res.json() // ← これも型がつく } PATH パスがサジェストされる INPUT Body / Queryに型 OUTPUT レスポンスも推論 実用!Hono RPC 2026 / yodaka 12 / 19
03 — RPC SWR / TanStack Queryとも相性◎ parseResponse でレスポンス処理を、$path() でキャッシュキーを、それぞ
れ型安全に • parseResponse でfetcherが一行に v4.9.0〜: ok判定 + json取り出しを内包、NGなら DetailedError をthrow • $path() をSWRのキャッシュキーに v4.12.0〜: $url()と違いパス文字列をそのまま返す(キー用途にぴったり) • パスパラメータもtype-safeに組み立て client.api.posts[':id'].$path({ param: { id } }) • hookの戻り値は InferResponseType で推論 引数側は InferRequestType で受け取れる FRONTEND/HOOKS/USEPOSTS.TS import { parseResponse, type, type InferResponseType } from 'hono/client' import { client } from '@/lib/client' import useSWR from 'swr' const $get = client.api.posts.$get type Posts = InferResponseType<typeof $get> export function usePosts() { return useSWR<Posts>( client.api.posts.$path() , // ← キャッシュキー () => parseResponse($get()), ) } 実用!Hono RPC 2026 / yodaka 13 / 19
04 — FLUTTER FlutterにはRPCが 通じないので、 OpenAPIで橋渡し。 同じHono から、別の出口が生えるイメージです。 実用!Hono RPC
2026 / yodaka 14 / 19
04 — FLUTTER hono-openapiでルートに説明と型をのせる 素のHonoのまま、describeRoute と validator を挟むだけ SCHEMAS import
{ Hono } from 'hono' import { z } from 'zod' import { describeRoute, resolver, validator, } from 'hono-openapi' const paramsSchema = z.object({ id: z.string(), }) const postSchema = z.object({ id: z.string(), title: z.string().meta({ example: ' 予約完了', }), }) ROUTE export const posts = new Hono().get( '/posts/:id', describeRoute({ description: ' 投稿の取得', responses: { 200: { content: { 'application/json': { schema: resolver(postSchema), }, } }, }, }), validator('param', paramsSchema), (c) => { const { id } = c.req.valid('param') return c.json({ id, title: ' 予約完了' }) } ) 実用!Hono RPC 2026 / yodaka 15 / 19
04 — FLUTTER ルート定義と実装が、同じチェーンに並ぶ DESCRIBEROUTE + VALIDATOR + HANDLER .get(
'/posts/:id', describeRoute({ responses: { 200: { content: { 'application/json': { schema: resolver( postSchema ), } }, } } }), validator('param', paramsSchema), (c) => { const { id } = c.req.valid('param') return c.json({ id, title: ' 予約完了' }) } ) ✔ 素のHonoのチェーンを保つのでRPCの型もその まま流れる ✔ validatorで c.req.valid() に 型がのる ✔ describeRouteで OpenAPIスキーマも同じ場所に 集約 実用!Hono RPC 2026 / yodaka 16 / 19
04 — FLUTTER FlutterクライアントをOpenAPIから生成 01 HonoがOpenAPI JSONをホスト app.get('/openapi', openAPIRouteHandler(app, {…}))
02 JSON → YAMLへ変換スクリプト CI で実行、差分をPR 化 03 openapi-generator でDartクライ アント生成 Flutter はこのAPI を呼ぶだけ → Flutter側にも、ひと続きの型安全 実用!Hono RPC 2026 / yodaka 17 / 19
05 — REFLECTIONS Hono RPCの推しポイント 🔥 コード生成ゼロ ルーターの型をそのまま共有。tscが走ればOK。 🧩 Honoに乗せるだけ
Web標準APIで、Node/Workers/Bun/Deno/Lambda で動く。 ⚡ 書く側の認知負荷が低い 普通にAPIを書くだけで、型がクライアントに届く。 🌐 OpenAPIと"両立"できる RPCが効かない相手(Flutterなど)にはOpenAPI で。 実用!Hono RPC 2026 / yodaka 18 / 19
SUMMARY まとめ → Hono RPC は「Honoのルーター型をそのまま共有する」仕組み → TS同士なら、コード生成なしで型安全に呼び出せる → 相手がTSでない時は、Honoに生成させたOpenAPIを通して型安全に
→ 1つのHonoで、Web / Admin / ネイティブを面倒見られる 🔥 開発体験 × 型安全 × マルチクライアント — ぜんぶ欲しい人にHono RPC 実用!Hono RPC 2026 / yodaka 19 / 19
THANK YOU Happy Hono-ing. speaker yodaka hono https://hono.dev refs zenn.dev/yodaka/articles/ad49f29a54ceba