Important
Deprecated: It appears Astro liked the idea of this package, because they went ahead and built it into Astro v7! :) With native Hono support in core, this package is no longer needed. New projects should follow the Astro Hono routing docs directly. See Migrating to Astro v7 below for upgrade steps.
Still on Astro v5 or v6? Those versions don't have the native integration, so this package still works there — the full docs are preserved in LEGACY.md.
Define server actions with built-in validation, error handling, and a pre-built hono client for calling the routes.
This integration works with all Astro adapters including:
@astrojs/cloudflare@astrojs/node@astrojs/vercel@astrojs/netlify
To see how to get started on Astro v5/v6, check out the package README or the preserved docs in LEGACY.md.
Astro v7 added native Hono integration via the astro/hono module and a custom entrypoint file (src/fetch.ts), which replaces this integration. See the official guide: Using with Hono.
npx astro upgrade # upgrade to Astro v7
npm remove @gnosticdev/hono-actionsThen remove the integration from your Astro config:
import { defineConfig } from 'astro/config'
-import honoActions from '@gnosticdev/hono-actions'
export default defineConfig({
output: 'server',
- integrations: [honoActions()]
})Convert your actions file (e.g. src/hono.ts) into a standard Hono app. defineHonoAction becomes a regular app.post() route with a Zod validator (e.g. @hono/zod-validator):
// src/server/api.ts
import { Hono } from 'hono'
import { zValidator } from '@hono/zod-validator'
import { z } from 'astro/zod'
export const api = new Hono()
api.post(
'/myAction',
zValidator('json', z.object({ name: z.string() })),
async (c) => {
const { name } = c.req.valid('json')
return c.json({ message: `Hello ${name}!` })
}
)Create a src/fetch.ts entrypoint that mounts your routes under your previous basePath (default /api) and registers Astro's handlers as Hono middleware:
// src/fetch.ts
import { Hono } from 'hono'
import { actions, middleware, pages, i18n } from 'astro/hono'
import { api } from './server/api'
const app = new Hono()
// Mount your routes under /api (or your previously configured basePath)
app.route('/api', api)
// Keep the rest of Astro (native actions, middleware, pages, i18n) working
app.use(actions())
app.use(middleware())
app.use(pages())
app.use(i18n())
export default apphonoClient can be swapped for Hono's own hc client, typed by the app exported from src/fetch.ts:
// src/lib/client.ts
import { hc } from 'hono/client'
import type app from '../fetch'
export const honoClient = hc<typeof app>('/')Usage stays nearly identical:
const res = await honoClient.api.myAction.$post({ json: { name: 'John' } })
const data = await res.json()MIT Licensed. Made by gnosticdev.
Created using astro-integration-template.