Skip to main content
Deno is a modern, secure runtime for JavaScript and TypeScript. Hono works seamlessly with Deno with full TypeScript support out of the box.

Quick Start

Create a new Hono project for Deno:
deno run -A npm:create-hono@latest my-app
Select “deno” as your template when prompted.

Installation

No installation needed! Import Hono directly from a CDN:
import { Hono } from 'https://deno.land/x/hono/mod.ts'
Or use npm specifiers:
import { Hono } from 'npm:hono@latest'

Basic Usage

Create your application in main.ts:
main.ts
import { Hono } from 'https://deno.land/x/hono/mod.ts'

const app = new Hono()

app.get('/', (c) => c.text('Hello Deno!'))

app.get('/api/hello', (c) => {
  return c.json({ message: 'Hello from Deno!' })
})

Deno.serve(app.fetch)
Deno’s Deno.serve() expects a fetch function. Pass app.fetch directly.

Running Your App

deno run --allow-net main.ts
Or with custom port:
main.ts
import { Hono } from 'https://deno.land/x/hono/mod.ts'

const app = new Hono()

app.get('/', (c) => c.text('Hello Deno!'))

Deno.serve({ port: 3000 }, app.fetch)

Adapter Features

The Deno adapter provides several utilities:

Static Files

Serve static files from a directory:
import { Hono } from 'https://deno.land/x/hono/mod.ts'
import { serveStatic } from 'https://deno.land/x/hono/adapter/deno/index.ts'

const app = new Hono()

app.use('/static/*', serveStatic({ root: './' }))
app.use('/favicon.ico', serveStatic({ path: './favicon.ico' }))

app.get('/', (c) => c.text('Hello!'))

Deno.serve(app.fetch)

WebSocket Support

Upgrade HTTP connections to WebSocket:
import { Hono } from 'https://deno.land/x/hono/mod.ts'
import { upgradeWebSocket } from 'https://deno.land/x/hono/adapter/deno/index.ts'

const app = new Hono()

app.get(
  '/ws',
  upgradeWebSocket((c) => {
    return {
      onMessage(event, ws) {
        console.log(`Message from client: ${event.data}`)
        ws.send('Hello from server!')
      },
      onClose: () => {
        console.log('Connection closed')
      },
    }
  })
)

Deno.serve(app.fetch)

Connection Info

Get connection information including IP address:
import { Hono } from 'https://deno.land/x/hono/mod.ts'
import { getConnInfo } from 'https://deno.land/x/hono/adapter/deno/index.ts'

const app = new Hono()

app.get('/info', (c) => {
  const info = getConnInfo(c)
  return c.json({
    remote: info.remote,
  })
})

Deno.serve(app.fetch)

Static Site Generation (SSG)

Generate static files from your Hono app:
import { Hono } from 'https://deno.land/x/hono/mod.ts'
import { toSSG } from 'https://deno.land/x/hono/adapter/deno/index.ts'

const app = new Hono()

app.get('/', (c) => c.html('<h1>Home</h1>'))
app.get('/about', (c) => c.html('<h1>About</h1>'))

// Generate static files
toSSG(app, { dir: './dist' })

Deno Deploy

Deploy your Hono app to Deno Deploy’s edge network.
1

Create your app

Create a Hono application:
main.ts
import { Hono } from 'https://deno.land/x/hono/mod.ts'

const app = new Hono()

app.get('/', (c) => c.text('Hello Deno Deploy!'))

Deno.serve(app.fetch)
2

Deploy with deployctl

Install and use deployctl:
deno install -A --no-check -r -f https://deno.land/x/deploy/deployctl.ts
deployctl deploy --project=my-project main.ts
3

Deploy via Git

Alternatively, connect your Git repository:
  1. Go to Deno Deploy
  2. Click “New Project”
  3. Connect your GitHub repository
  4. Select the entry file (e.g., main.ts)
  5. Deploy

Using Deno KV

Integrate with Deno’s built-in key-value database:
import { Hono } from 'https://deno.land/x/hono/mod.ts'

const app = new Hono()
const kv = await Deno.openKv()

app.get('/kv/:key', async (c) => {
  const key = c.req.param('key')
  const result = await kv.get([key])
  
  if (!result.value) {
    return c.notFound()
  }
  
  return c.json({ value: result.value })
})

app.post('/kv/:key', async (c) => {
  const key = c.req.param('key')
  const body = await c.req.json()
  
  await kv.set([key], body.value)
  
  return c.json({ message: 'Saved' })
})

Deno.serve(app.fetch)

Environment Variables

Access environment variables:
import { Hono } from 'https://deno.land/x/hono/mod.ts'

const app = new Hono()

app.get('/config', (c) => {
  const apiKey = Deno.env.get('API_KEY')
  return c.json({ configured: !!apiKey })
})

Deno.serve(app.fetch)
Run with environment variables:
API_KEY=secret deno run --allow-net --allow-env main.ts
Or use a .env file with a library like dotenv.

Configuration

Create a deno.json configuration file:
deno.json
{
  "tasks": {
    "dev": "deno run --allow-net --allow-read --allow-env --watch main.ts",
    "start": "deno run --allow-net --allow-read --allow-env main.ts"
  },
  "imports": {
    "hono": "https://deno.land/x/hono/mod.ts",
    "hono/": "https://deno.land/x/hono/"
  },
  "compilerOptions": {
    "jsx": "react-jsx",
    "jsxImportSource": "hono/jsx"
  }
}
Run tasks:
deno task dev   # Development with watch mode
deno task start # Production

Using JSX

Hono’s JSX works great with Deno:
import { Hono } from 'https://deno.land/x/hono/mod.ts'
import { jsx } from 'https://deno.land/x/hono/middleware.ts'

const app = new Hono()

app.get('/', (c) => {
  return c.html(
    <html>
      <head>
        <title>Hono + Deno</title>
      </head>
      <body>
        <h1>Hello from Deno!</h1>
      </body>
    </html>
  )
})

Deno.serve(app.fetch)

Best Practices

Define imports in deno.json for cleaner import statements.
Use deno.lock to lock dependency versions for reproducible builds.
Only grant the permissions your app needs (e.g., --allow-net, --allow-read).
Use Deno KV for built-in, distributed key-value storage.

Development Features

Watch Mode

Auto-reload on file changes:
deno run --allow-net --watch main.ts

Type Checking

Deno type-checks TypeScript by default. Skip checking for faster startup:
deno run --allow-net --no-check main.ts

Testing

Write tests using Deno’s built-in test runner:
main.test.ts
import { assertEquals } from "https://deno.land/std/assert/mod.ts"
import app from "./main.ts"

Deno.test("GET /", async () => {
  const res = await app.request('http://localhost/')
  assertEquals(res.status, 200)
  assertEquals(await res.text(), 'Hello Deno!')
})
Run tests:
deno test --allow-net

Resources

Deno Manual

Official Deno documentation

Deno Deploy

Deploy to the edge with Deno Deploy

Build docs developers (and LLMs) love