Gathering detailed insights and metrics for hono-remix-adapter
Gathering detailed insights and metrics for hono-remix-adapter
Gathering detailed insights and metrics for hono-remix-adapter
Gathering detailed insights and metrics for hono-remix-adapter
npm install hono-remix-adapter
Typescript
Module System
Min. Node Version
Node Version
NPM Version
TypeScript (99.26%)
JavaScript (0.74%)
Total Downloads
0
Last Day
0
Last Week
0
Last Month
0
Last Year
0
270 Stars
92 Commits
16 Forks
7 Watchers
2 Branches
7 Contributors
Updated on Jul 11, 2025
Latest Version
0.5.4
Package Id
hono-remix-adapter@0.5.4
Unpacked Size
21.95 kB
Size
5.37 kB
File Count
14
NPM Version
10.8.2
Node Version
20.18.0
Published on
Dec 06, 2024
Cumulative downloads
Total Downloads
Last Day
0%
NaN
Compared to previous day
Last Week
0%
NaN
Compared to previous week
Last Month
0%
NaN
Compared to previous month
Last Year
0%
NaN
Compared to previous year
2
1
13
3
hono-remix-adapter
is a set of tools for adapting between Hono and Remix. It is composed of a Vite plugin and handlers that enable it to support platforms like Cloudflare Workers and Node.js. You just create Hono app, and it will be applied to your Remix app.
1// server/index.ts 2import { Hono } from 'hono' 3 4const app = new Hono() 5 6app.use(async (c, next) => { 7 await next() 8 c.header('X-Powered-By', 'Remix and Hono') 9}) 10 11app.get('/api', (c) => { 12 return c.json({ 13 message: 'Hello', 14 }) 15}) 16 17export default app
This means you can create API routes with Hono's syntax and use a lot of Hono's built-in middleware and third-party middleware.
[!WARNING]
hono-remix-adapter
is currently unstable. The API may be changed without announcement in the future.
1npm i hono-remix-adapter hono
Edit your vite.config.ts
:
1// vite.config.ts 2import serverAdapter from 'hono-remix-adapter/vite' 3 4export default defineConfig({ 5 plugins: [ 6 // ... 7 remix(), 8 serverAdapter({ 9 entry: 'server/index.ts', 10 }), 11 ], 12})
Write your Hono app:
1// server/index.ts 2import { Hono } from 'hono' 3 4const app = new Hono() 5 6//... 7 8export default app
To support Cloudflare Workers and Cloudflare Pages, add the adapter in @hono/vite-dev-server
for development.
1// vite.config.ts 2import adapter from '@hono/vite-dev-server/cloudflare' 3import serverAdapter from 'hono-remix-adapter/vite' 4 5export default defineConfig({ 6 plugins: [ 7 // ... 8 remix(), 9 serverAdapter({ 10 adapter, // Add Cloudflare adapter 11 entry: 'server/index.ts', 12 }), 13 ], 14})
To deploy your app to Cloudflare Workers, you can write the following handler on worker.ts
:
1// worker.ts 2import handle from 'hono-remix-adapter/cloudflare-workers' 3import * as build from './build/server' 4import server from './server' 5 6export default handle(build, server)
Specify worker.ts
in your wrangler.toml
:
1name = "example-cloudflare-workers" 2compatibility_date = "2024-11-06" 3main = "./worker.ts" 4assets = { directory = "./build/client" }
To deploy your app to Cloudflare Pages, you can write the following handler on functions/[[path]].ts
:
1// functions/[[path]].ts 2import handle from 'hono-remix-adapter/cloudflare-pages' 3import * as build from '../build/server' 4import server from '../server' 5 6export const onRequest = handle(build, server)
If you want to run your app on Node.js, you can use hono-remix-adapter/node
. Write main.ts
:
1// main.ts 2import { serve } from '@hono/node-server' 3import { serveStatic } from '@hono/node-server/serve-static' 4import handle from 'hono-remix-adapter/node' 5import * as build from './build/server' 6import { getLoadContext } from './load-context' 7import server from './server' 8 9server.use( 10 serveStatic({ 11 root: './build/client', 12 }) 13) 14 15const handler = handle(build, server, { getLoadContext }) 16 17serve({ fetch: handler.fetch, port: 3010 })
Run main.ts
with tsx
:
1tsx main.ts
Or you can compile to a pure JavaScript file with esbuild
with the command below:
1esbuild main.ts --bundle --outfile=main.mjs --platform=node --target=node16.8 --format=esm --banner:js='import { createRequire as topLevelCreateRequire } from "module"; const require = topLevelCreateRequire(import.meta.url);'
getLoadContext
If you want to add extra context values when you use Remix routes, like in the following use case:
1// app/routes/_index.tsx 2import type { LoaderFunctionArgs } from '@remix-run/cloudflare' 3import { useLoaderData } from '@remix-run/react' 4 5export const loader = ({ context }) => { 6 return { extra: context.extra } 7} 8 9export default function Index() { 10 const { extra } = useLoaderData<typeof loader>() 11 return <h1>Extra is {extra}</h1> 12}
First, create the getLoadContext
function and export it:
1// load-context.ts 2import type { AppLoadContext } from '@remix-run/cloudflare' 3import type { PlatformProxy } from 'wrangler' 4 5type Cloudflare = Omit<PlatformProxy, 'dispose'> 6 7declare module '@remix-run/cloudflare' { 8 interface AppLoadContext { 9 cloudflare: Cloudflare 10 extra: string 11 } 12} 13 14type GetLoadContext = (args: { 15 request: Request 16 context: { cloudflare: Cloudflare } 17}) => AppLoadContext 18 19export const getLoadContext: GetLoadContext = ({ context }) => { 20 return { 21 ...context, 22 extra: 'stuff', 23 } 24}
Then import the getLoadContext
and add it to the serverAdapter
as an argument in your vite.config.ts
:
1// vite.config.ts 2import adapter from '@hono/vite-dev-server/cloudflare' 3import { vitePlugin as remix } from '@remix-run/dev' 4import serverAdapter from 'hono-remix-adapter/vite' 5import { defineConfig } from 'vite' 6import { getLoadContext } from './load-context' 7 8export default defineConfig({ 9 plugins: [ 10 // ... 11 remix(), 12 serverAdapter({ 13 adapter, 14 getLoadContext, 15 entry: 'server/index.ts', 16 }), 17 ], 18})
For Cloudflare Workers, you can add it to the handler
function:
1// worker.ts 2import handle from 'hono-remix-adapter/cloudflare-workers' 3import * as build from './build/server' 4import { getLoadContext } from './load-context' 5import app from './server' 6 7export default handle(build, app, { getLoadContext })
You can also add it for Cloudflare Pages:
1// functions/[[path]].ts 2import handle from 'hono-remix-adapter/cloudflare-pages' 3import { getLoadContext } from 'load-context' 4import * as build from '../build/server' 5import server from '../server' 6 7export const onRequest = handle(build, server, { getLoadContext })
This way is almost the same as Remix.
You can get the Hono context in Remix routes. For example, you can pass the value with c.set()
from your Hono instance in the server/index.ts
:
1// server/index.ts 2import { Hono } from 'hono' 3 4const app = new Hono<{ 5 Variables: { 6 message: string 7 } 8}>() 9 10app.use(async (c, next) => { 11 c.set('message', 'Hi from Hono') 12 await next() 13}) 14 15export default app
In the Remix route, you can get the context from args.context.hono.context
:
1// app/routes/_index.tsx 2import type { LoaderFunctionArgs } from '@remix-run/cloudflare' 3import { useLoaderData } from '@remix-run/react' 4 5export const loader = ({ context }) => { 6 const message = args.context.hono.context.get('message') 7 return { message } 8} 9 10export default function Index() { 11 const { message } = useLoaderData<typeof loader>() 12 return <h1>Message is {message}</h1> 13}
To enable type inference, config the load-context.ts
like follows:
1// load-context.ts 2import type { AppLoadContext } from '@remix-run/cloudflare' 3import type { Context } from 'hono' 4import type { PlatformProxy } from 'wrangler' 5 6type Env = { 7 Variables: { 8 message: string 9 } 10} 11 12type Cloudflare = Omit<PlatformProxy, 'dispose'> 13 14declare module '@remix-run/cloudflare' { 15 interface AppLoadContext { 16 cloudflare: Cloudflare 17 hono: { 18 context: Context<Env> 19 } 20 extra: string 21 } 22} 23 24type GetLoadContext = (args: { 25 request: Request 26 context: { 27 cloudflare: Cloudflare 28 hono: { context: Context<Env> } 29 } 30}) => AppLoadContext 31 32export const getLoadContext: GetLoadContext = ({ context }) => { 33 return { 34 ...context, 35 extra: 'stuff', 36 } 37}
If you want to add Auth Middleware, e.g. Basic Auth middleware, please be careful that users can access the protected pages with SPA tradition. To prevent this, add a loader
to the page:
1// app/routes/admin 2export const loader = async () => { 3 return { props: {} } 4}
Yusuke Wada https://github.com/yusukebe
MIT
No vulnerabilities found.
No security vulnerabilities found.