# How to ship a Hono app on Vercel

**Author:** Ben Sabic

---

[Hono](https://hono.dev/) is a fast, lightweight web framework built on Web Standards. It gives you a small, zero-dependency core, a familiar middleware model, fast routing, and built-in helpers for tasks like streaming and validation, and it runs anywhere JavaScript runs.

On Vercel, you can deploy a Hono app with zero configuration: your routes become [Vercel Functions](https://vercel.com/docs/functions) running on [Fluid compute](https://vercel.com/fluid), and you get response streaming, preview deployments, and observability without extra setup.

This guide walks you through deploying a Hono app to Vercel from a template, the [Vercel CLI](https://vercel.com/docs/cli), or a Git repository, then configuring features such as streaming, middleware, cron jobs, the Bun runtime, and observability.

## Prerequisites

Before you begin, make sure you have:

- A [Vercel account](https://vercel.com/signup)
  
- Node.js 20+ and a package manager (e.g., npm)
  
- An existing Hono project, or a new one created from a [Hono template](https://vercel.com/templates/hono)
  
- A Git repository on GitHub, GitLab, or Bitbucket (if you want Git-based deployments)
  
- Vercel CLI installed (`npm i -g vercel`)
  

## How it works

When you deploy a Hono app, Vercel detects the framework and builds it for the Vercel runtime. Your exported Hono app handles requests through Vercel Functions, which run on Fluid compute by default. Your app scales with traffic, and you pay only for the compute your functions use, not for idle time.

Because Vercel ships zero-configuration detection for Hono, you don't set a build command or output directory. Vercel reads your project, finds the file that exports your Hono app, and applies the correct build settings.

## Deploy your Hono app

You can ship a Hono app to Vercel in three ways. Choose the one that fits where your code lives today.

### Option 1: Deploy from a template

The fastest way to ship a Hono app is to start from a template. Browse the [Hono templates gallery](https://vercel.com/templates/hono), pick a starter, and deploy it. Vercel clones the template to your Git provider, creates a project, and deploys it with zero configuration.

Templates to start from include:

- [**Hono on Vercel**](https://vercel.com/templates/hono/hono-on-vercel): A minimal Hono API that deploys with zero configuration. Start here if you're new to Hono on Vercel.
  
- [**Hono MCP remote server**](https://vercel.com/templates/hono/hono-mcp-remote-server): A remote MCP server built on Hono, with example tools that run math operations.
  
- [**Hono + AI SDK**](https://vercel.com/templates/hono/hono-ai-sdk): A Hono backend wired up with [AI SDK](https://vercel.com/kb/ai-sdk) for building AI features and streaming responses.
  
- [**Slack Bolt with Hono**](https://vercel.com/templates/hono/slack-bolt-with-hono): A starting point for Slack apps built with Bolt for JavaScript on Hono.
  
- [**Hono and Next.js Starter**](https://vercel.com/templates/hono/hono-nextjs): A Hono API paired with a Next.js App Router frontend in a single project.
  
- [**Caltext**](https://vercel.com/templates/hono/caltext): An iMessage calorie-tracking assistant built with AI SDK and [Chat SDK](https://vercel.com/kb/chat-sdk).
  

### Option 2: Start a new project with the Vercel CLI

To scaffold a new Hono project locally, use the [Vercel CLI init command](https://vercel.com/docs/cli/init). It clones Vercel's Hono example into a folder named `hono`.

1. Create the project:
   
   `vercel init nitro`
   
2. Install dependencies:
   
   `cd nitro npm install`
   
3. Develop locally at `http://localhost:3000`. Use the Vercel CLI, so your app runs with the same default export it uses in production:
   
   `vercel dev`
   
4. Create a [preview deployment](https://vercel.com/docs/deployments/environments#preview-environment-pre-production). The first run creates a Vercel project link:
   
   `vercel`
   
5. Promote your deployment to production:
   
   `vercel --prod`
   

### Option 3: Deploy an existing Hono app

If you already have a Hono app, deploy it from Git or from the command line.

**From Git**: Push your project to GitHub, GitLab, or Bitbucket, then import it at [vercel.com/new](https://vercel.com/new). Vercel detects Hono automatically and deploys it with zero configuration.

**From the CLI**: From your project's root directory, run `vercel` to create a preview deployment, then `vercel --prod` to go live. To pull project settings and environment variables for local development, run:

`vercel link vercel env pull`

For Vercel to detect your app, export your Hono instance as the default export from one of the recognized entry files, such as `app.ts`, `index.ts`, or `server.ts` at your project root or under `src/`:

`import { Hono } from 'hono'; const app = new Hono(); app.get('/', (c) => c.text('Hello from Hono on Vercel')); export default app;`

## Use Vercel features with Hono

After your app is deployed, you can layer Vercel features onto it. Some work automatically, and others take a few lines of configuration in `vercel.json`.

### Server routes run as Vercel Functions

Each route in your Hono app is served by [Vercel Functions](https://vercel.com/docs/functions). These functions use Fluid compute by default, which runs multiple requests concurrently within a single instance to reduce cold starts and the cost of I/O-bound work such as API calls and database queries. You don't configure anything to get this behavior.

Because Hono exports a single app, Vercel sends every incoming request to that app and lets Hono's router match the path. Your route handlers, middleware, and error handling all run inside Vercel Functions.

### Stream responses

Vercel Functions support streaming, so you can send data to the client as you produce it instead of waiting for the full response. Use Hono's `stream()` helper to stream text, server-sent events, or AI model output:

`import { Hono } from 'hono'; import { stream } from 'hono/streaming'; const app = new Hono(); app.get('/stream', (c) => { return stream(c, async (stream) => { stream.onAbort(() => { console.log('Client disconnected'); }); for (const chunk of ['Hello', ' ', 'from', ' ', 'Hono']) { await stream.write(chunk); await stream.sleep(200); } }); }); export default app;` Streaming pairs well with Fluid compute: while your function waits between chunks, the same instance can serve other requests. ### Combine Hono Middleware with Vercel Routing Middleware Hono and Vercel each have a middleware layer, and they solve different problems. [Hono Middleware](https://hono.dev/docs/concepts/middleware) runs inside your app's router, after the request reaches your function. Use it for app-level concerns such as logging, CORS, and authentication:

`import { Hono } from 'hono'; import { logger } from 'hono/logger'; import { cors } from 'hono/cors'; import { basicAuth } from 'hono/basic-auth'; const app = new Hono(); app.use(logger()); app.use('/posts/*', cors()); app.post('/posts/*', basicAuth({ username: 'admin', password: process.env.ADMIN_PASSWORD ?? '' })); export default app;`

[Vercel Routing Middleware](https://vercel.com/docs/routing-middleware) runs at the edge, before the request reaches your Hono app. Use it for rewrites, redirects, and header changes that should happen before any function runs. The two layers work together, with Routing Middleware shaping the request at the edge and Hono Middleware handling it inside your app.

### Serve static assets from the CDN

To serve static files such as images, fonts, or a favicon, place them in the `public/**` directory. Vercel serves them through its [CDN](https://vercel.com/docs/cdn) using default [headers](https://vercel.com/docs/headers), which you can override in `vercel.json`. Hono's own `serveStatic()` helper is ignored on Vercel, so rely on the `public` directory instead.

### Run scheduled tasks with cron jobs

Vercel [Cron Jobs](https://vercel.com/docs/cron-jobs) trigger a route on a schedule by sending an HTTP GET request to it. Define a route in your Hono app for the task, then register the schedule in `vercel.json`.

Define the route:

``import { Hono } from 'hono'; const app = new Hono(); app.get('/api/cron/cleanup', (c) => { if (c.req.header('authorization') !== `Bearer ${process.env.CRON_SECRET}`) { return c.text('Unauthorized', 401); } // Run your scheduled work here return c.json({ ok: true }); }); export default app;``

Register the schedule:

`{ "$schema": "https://openapi.vercel.sh/vercel.json", "crons": [{ "path": "/api/cron/cleanup", "schedule": "0 0 * * *" }] }` Vercel runs cron jobs only on production deployments. To stop anyone else from calling the route, set a `CRON_SECRET` environment variable in your [project settings](https://vercel.com/d?to=%2F%5Bteam%5D%2F%5Bproject%5D%2Fsettings%2Fenvironment-variables). Vercel sends it as a `Bearer` token in the `Authorization` header on every cron invocation, and your handler compares it before running the task.

### Use the Bun runtime

Hono runs your functions on Node.js by default. To run them on [Bun](https://vercel.com/docs/functions/runtimes/bun) instead, set `bunVersion` in `vercel.json`:

`{ "$schema": "https://openapi.vercel.sh/vercel.json", "bunVersion": "1.x" }`

Vercel detects the setting, runs your app on Bun in both `vercel dev` and production, and keeps it on Fluid compute. The Bun runtime is in public beta and supports most Node.js APIs. Set the major version only, and Vercel manages the minor and patch versions.

### Monitor performance with Observability

[Vercel Observability](https://vercel.com/products/observability) tracks your deployed functions automatically, with no setup. Open the [Observability page](https://vercel.com/d?to=%2F%5Bteam%5D%2F~%2Fobservability) in your project to see invocation counts, error rates, and duration for your Hono app, along with the requests your functions make to external APIs. On [Observability Plus](https://vercel.com/docs/observability/observability-plus), you also get longer retention and a latency breakdown by path.

## Best practices

### Export your app from a recognized entry point

Vercel finds your Hono app by looking for a default export at a fixed set of locations: `app`, `index`, or `server` (with a `.js`, `.ts`, or related extension) at your project root or under `src/`. Put your app at one of these paths so Vercel detects and deploys it correctly:

`import { Hono } from 'hono'; const app = new Hono(); // Add your routes here export default app;`

### Develop with the Vercel CLI

Run `vercel dev` for local development instead of a standalone server. It serves your app the same way production does, using your default export, so the behavior you test locally matches what you deploy. This also lets you exercise features such as cron routes and the Bun runtime before shipping.

## Resources and next steps

- Read the full [Hono on Vercel documentation](https://vercel.com/docs/frameworks/backend/hono)
  
- Browse [Hono templates](https://vercel.com/templates/hono) you can deploy in one step
  
- Learn how [Vercel Functions](https://vercel.com/docs/functions) run your server code
  
- Understand pricing and scaling with [Fluid compute](https://vercel.com/docs/fluid-compute)
  
- Run code before requests with [Routing Middleware](https://vercel.com/docs/routing-middleware)
  
- Defer background work from your routes with [Vercel Queues](https://vercel.com/docs/queues), or orchestrate multi-step tasks with [Vercel Workflows](https://vercel.com/docs/workflows)

---

[View full KB sitemap](/kb/sitemap.md)
