Skip to content

feat(hono): add the Hono JSX adapter for Pages - #731

Draft
yusukebe wants to merge 2 commits into
mainfrom
feat/hono-adapter
Draft

yusukebe wants to merge 2 commits into
mainfrom
feat/hono-adapter

Conversation

@yusukebe

@yusukebe yusukebe commented Nov 6, 2026

Copy link
Copy Markdown

Adds @void/hono, a Pages adapter for Hono JSX, next to the React, Vue, Svelte and Solid adapters. Pages, layouts, and islands are written in TSX and rendered with hono/jsx on the server and hono/jsx/dom in the browser.

// vite.config.ts
import { voidHono } from '@void/hono/plugin';
import { voidPlugin } from 'void';

export default { plugins: [voidPlugin(), voidHono()] };

Of course, you can use React, and Hono JSX doesn't have all of React's features. But Hono JSX is small, and with Hono JSX, the app doesn't need a UI library dependency. I think Hono JSX is a good option for users. If they want to write an SSR-based website, they can use Hono JSX.

Where Hono JSX fits

Hono JSX suits apps that are mostly server-rendered: content sites, Markdown, island pages with a few interactive components, and apps whose server is already written with Hono. On the server this adapter is on par with the React adapter: SSR, loaders, actions, layouts and typed routes work the same way, and the public API has the same names.

It is not a replacement for the React adapter. The differences are in the browser:

  • Hydration: Hono JSX renders the page again instead of adopting the server DOM, so focus and values typed before hydration are lost.
  • Dev updates: there is no Fast Refresh. Editing an island resets its state, and other edits reload the page.
  • Deferred props: there is no streaming SSR with Suspense and use(). Deferred is { loading, value, error }, as in the Vue, Svelte and Solid adapters.
  • Transitions: router.visit() has no resolveOn: 'data', so it does not integrate with startTransition or useActionState.
  • Ecosystem: React component libraries do not work with Hono JSX.

Apps with a lot of client-side state are better served by the React adapter. In return the client runtime is small: the whole client build of playground/hono-pages is 29 kB gzipped, against 31 kB for the Solid playground with the same pages.

What is included

  • packages/hono: the adapter. It has the same public API as the other adapters: Form, Link, useForm, useIslandForm, useRouter, useNavigation, useParams, useShared, action, Deferred and InferProps. voidHono() takes the same viewTransitions and prefetch options.
  • @void/md: Markdown pages render through Hono JSX when the Hono adapter is installed, including islands and useFrontmatter().
  • void init / create-void: Hono is a starter choice.
  • playground/hono-pages: the Solid playground ported to Hono JSX. It runs the shared browser contract.
  • Docs: a Hono tab next to each Solid tab in the Pages guides, and an @void/hono section in the API reference.
  • CI scripts: Hono is added to the packed-init and packed-consumer framework lists.

Behavior worth knowing

  • Hydration: hydrateRoot in hono/jsx/dom renders the page again instead of adopting the server DOM. The resulting DOM matches the server HTML on the playground pages, but focus and values typed before hydration are lost. The adapter calls hydrateRoot, so it picks up real hydration when Hono supports it.
  • Dev updates: Hono JSX has no Fast Refresh. An edit to an island component replaces that island without a full reload, and its state resets. Other edits reload the page.
  • Island pages in dev: island pages load the Vite client in dev even when they have no islands, so an edit reloads the page. The other adapters send no script for such pages, and the page needs a manual reload. Production output is the same as the other adapters: no JavaScript without islands. I can align this with the other adapters if you prefer.
  • Render errors: when a page throws while rendering after a client navigation, router.visit() rejects with that error and the current page stays on screen.

Not included

  • The auth client (void/client/hono, useSession).
  • void gen ssr --hono.

Testing

  • Unit tests for the plugin, the server renderer, Link, the page client and the Markdown output.
  • Integration tests: the shared Pages browser contract against `playground/honooduction build, island CSS builds, and Markdown frontmatter with islands.
  • vp run build:all, vp run build:docs, vp run check, vp lint and vp fmt --check pass.
  • vp test run: all Hono tests pass. On my machine init.test.ts, init-install.test.ts and nitro.test.ts fail, and they fail the same way without this change.
  • Packed consumer acceptance with VOID_PACKED_FRAMEWORK=hono and pnpm passes. I did not run it with npm.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Nov 6, 2026 •

Copy link
Copy Markdown

🚀 Deploying Preview to Cloudflare 🚀

Preview URL: https://feat-hono-adapter-void-cloud.voidzero-docs.workers.dev (commit 4dda94d)

This URL reflects your latest Preview deployment

Preview Deployments by commit

Status Deployment URL Commit Updated (UTC) See this deployment's details
  • Build: Success ✅
  • Deployment: Success ✅

View logs ↗
https://1b7c8239-void-cloud.voidzero-docs.workers.dev 4dda94d 2026-11-06T08:47:39.619Z Visit the dashboard ↗
  • Build: Success ✅
  • Deployment: Success ✅

View logs ↗
https://da0f7c91-void-cloud.voidzero-docs.workers.dev ae94680 2026-11-06T08:24:45.492Z Visit the dashboard ↗

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant