> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/honojs/hono/llms.txt
> Use this file to discover all available pages before exploring further.

# Node.js

> Deploy Hono applications on Node.js runtime

Node.js is the most popular JavaScript runtime. Hono works seamlessly with Node.js using built-in adapters or standard Web APIs.

## Quick Start

Create a new Hono project for Node.js:

<CodeGroup>
  ```bash npm theme={null}
  npm create hono@latest my-app
  ```

  ```bash yarn theme={null}
  yarn create hono my-app
  ```

  ```bash pnpm theme={null}
  pnpm create hono my-app
  ```
</CodeGroup>

Select "nodejs" as your template when prompted.

## Installation

Add Hono to your existing Node.js project:

```bash theme={null}
npm install hono
```

For Node.js v18+, you can use the built-in fetch adapter. For earlier versions, install an adapter:

```bash theme={null}
npm install @hono/node-server
```

## Basic Usage

### Using Node.js Adapter

Create your application with the Node.js adapter:

```typescript index.ts theme={null}
import { Hono } from 'hono'
import { serve } from '@hono/node-server'

const app = new Hono()

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

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

const port = 3000
console.log(`Server is running on http://localhost:${port}`)

serve({
  fetch: app.fetch,
  port,
})
```

### Using Native Node.js APIs

For Node.js v18.0.0+, you can use native fetch support:

```typescript index.ts theme={null}
import { Hono } from 'hono'
import { createServer } from 'node:http'

const app = new Hono()

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

const server = createServer((req, res) => {
  const url = new URL(req.url || '', `http://${req.headers.host}`)
  const request = new Request(url, {
    method: req.method,
    headers: req.headers as HeadersInit,
    body: req.method !== 'GET' && req.method !== 'HEAD' ? req : undefined,
  })

  app.fetch(request).then((response) => {
    res.statusCode = response.status
    response.headers.forEach((value, key) => {
      res.setHeader(key, value)
    })
    response.body?.pipeTo(new WritableStream({
      write(chunk) {
        res.write(chunk)
      },
      close() {
        res.end()
      },
    }))
  })
})

server.listen(3000, () => {
  console.log('Server is running on http://localhost:3000')
})
```

<Note>
  Using `@hono/node-server` is recommended as it handles request/response conversion automatically.
</Note>

## Running Your App

### With TypeScript

Using `tsx` for development:

```bash theme={null}
npx tsx index.ts
```

Or add to `package.json`:

```json package.json theme={null}
{
  "scripts": {
    "dev": "tsx watch index.ts",
    "start": "node dist/index.js",
    "build": "tsc"
  }
}
```

### With JavaScript

```bash theme={null}
node index.js
```

## Adapter Features

### Static Files

Serve static files using the node-server adapter:

```typescript theme={null}
import { Hono } from 'hono'
import { serve } from '@hono/node-server'
import { serveStatic } from '@hono/node-server/serve-static'

const app = new Hono()

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

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

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

### Connection Info

Get connection information:

```typescript theme={null}
import { Hono } from 'hono'
import { serve } from '@hono/node-server'
import { getConnInfo } from '@hono/node-server/conninfo'

const app = new Hono()

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

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

## Environment Variables

Load environment variables using `dotenv`:

```bash theme={null}
npm install dotenv
```

```env .env theme={null}
PORT=3000
API_KEY=your-secret-key
DATABASE_URL=postgres://localhost/mydb
```

```typescript index.ts theme={null}
import 'dotenv/config'
import { Hono } from 'hono'
import { serve } from '@hono/node-server'

const app = new Hono()

app.get('/config', (c) => {
  return c.json({
    apiKey: process.env.API_KEY,
    dbUrl: process.env.DATABASE_URL,
  })
})

const port = Number(process.env.PORT) || 3000
serve({ fetch: app.fetch, port })
```

## Database Integration

### PostgreSQL with Drizzle ORM

```bash theme={null}
npm install drizzle-orm postgres
```

```typescript theme={null}
import { Hono } from 'hono'
import { drizzle } from 'drizzle-orm/postgres-js'
import postgres from 'postgres'
import { serve } from '@hono/node-server'

const client = postgres(process.env.DATABASE_URL!)
const db = drizzle(client)

const app = new Hono()

app.get('/users', async (c) => {
  const users = await db.select().from(usersTable)
  return c.json(users)
})

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

### MongoDB

```bash theme={null}
npm install mongodb
```

```typescript theme={null}
import { Hono } from 'hono'
import { MongoClient } from 'mongodb'
import { serve } from '@hono/node-server'

const client = new MongoClient(process.env.MONGODB_URI!)
await client.connect()

const db = client.db('myapp')
const app = new Hono()

app.get('/users', async (c) => {
  const users = await db.collection('users').find().toArray()
  return c.json(users)
})

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

## Middleware

### CORS

```typescript theme={null}
import { Hono } from 'hono'
import { cors } from 'hono/cors'
import { serve } from '@hono/node-server'

const app = new Hono()

app.use('/*', cors())

app.get('/', (c) => c.text('CORS enabled'))

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

### Logger

```typescript theme={null}
import { Hono } from 'hono'
import { logger } from 'hono/logger'
import { serve } from '@hono/node-server'

const app = new Hono()

app.use('*', logger())

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

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

## Testing

Use any Node.js testing framework. Example with Vitest:

```bash theme={null}
npm install -D vitest
```

```typescript index.test.ts theme={null}
import { describe, it, expect } from 'vitest'
import app from './index'

describe('API Tests', () => {
  it('GET /', async () => {
    const res = await app.request('http://localhost/')
    expect(res.status).toBe(200)
    expect(await res.text()).toBe('Hello Node.js!')
  })

  it('GET /api/hello', async () => {
    const res = await app.request('http://localhost/api/hello')
    expect(res.status).toBe(200)
    const json = await res.json()
    expect(json.message).toBe('Hello from Node.js!')
  })
})
```

Run tests:

```bash theme={null}
npx vitest
```

## Deployment

### VPS/Cloud Server

<Steps>
  <Step title="Build your application">
    ```bash theme={null}
    npm run build
    ```
  </Step>

  <Step title="Install dependencies on server">
    ```bash theme={null}
    npm install --production
    ```
  </Step>

  <Step title="Run with PM2">
    Install PM2:

    ```bash theme={null}
    npm install -g pm2
    ```

    Start your app:

    ```bash theme={null}
    pm2 start dist/index.js --name my-hono-app
    pm2 save
    pm2 startup
    ```
  </Step>
</Steps>

### Docker

Create a `Dockerfile`:

```dockerfile Dockerfile theme={null}
FROM node:20-alpine

WORKDIR /app

COPY package*.json ./
RUN npm ci --only=production

COPY . .

EXPOSE 3000

CMD ["node", "dist/index.js"]
```

Build and run:

```bash theme={null}
docker build -t my-hono-app .
docker run -p 3000:3000 my-hono-app
```

### Heroku

Create a `Procfile`:

```Procfile theme={null}
web: node dist/index.js
```

Deploy:

```bash theme={null}
git push heroku main
```

## Best Practices

<AccordionGroup>
  <Accordion title="Use process managers in production">
    Use PM2 or systemd to keep your app running and handle restarts.
  </Accordion>

  <Accordion title="Enable clustering for multi-core">
    Use Node.js cluster module or PM2 cluster mode for better performance.
  </Accordion>

  <Accordion title="Handle errors gracefully">
    Implement proper error handling and logging.
  </Accordion>

  <Accordion title="Use TypeScript">
    TypeScript provides better type safety and developer experience.
  </Accordion>
</AccordionGroup>

## Performance Tips

* Use Node.js v20+ for best performance
* Enable HTTP/2 with the `http2` module
* Implement caching strategies (Redis, in-memory)
* Use a reverse proxy (nginx, Caddy) in production
* Enable gzip/brotli compression

## Resources

<CardGroup cols={2}>
  <Card title="Node.js Documentation" icon="book" href="https://nodejs.org/docs">
    Official Node.js documentation
  </Card>

  <Card title="@hono/node-server" icon="npm" href="https://github.com/honojs/node-server">
    Node.js adapter for Hono
  </Card>
</CardGroup>
