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

# @hile/http-next

> Serve Next.js pages and Hile API controllers from one Koa server and one port.

# @hile/http-next

Serve Next.js pages and Hile API controllers from one Koa server and one port.

## Choose This Package When

| User asks for                               | Use               | Also read                                                 |
| ------------------------------------------- | ----------------- | --------------------------------------------------------- |
| Run Next.js and API controllers on one port | `@hile/http-next` | `packages/http-next.md`, `recipes/http-next-fullstack.md` |

## Use When

Use `HttpNext` when a Next.js app and Hile API controllers should share the same HTTP server and port.

## Do Not Use When

* Do not use `@hile/http-next` for a pure API service; use `@hile/http`.
* Do not put Hile controllers inside `src/app` unless you intentionally change `controllerDirectory`.

## Install

```bash theme={null}
pnpm add @hile/http-next @hile/http next react react-dom
pnpm add -D @hile/cli
```

## Imports

```ts theme={null}
import HttpNext from '@hile/http-next'
import { defineService } from '@hile/core'
```

## Copy-Paste Example

```ts theme={null}
// src/services/http.boot.ts
import { defineService } from '@hile/core'
import HttpNext from '@hile/http-next'

export default defineService('http.next', async (shutdown) => {
  const app = new HttpNext({
    port: Number(process.env.HTTP_PORT ?? 3000),
    cwd: process.cwd(),
    publicPath: 'public',
  })
  const stop = await app.start()
  shutdown(stop)
  return app
})
```

## More Examples

Recommended layout:

```text theme={null}
src/
  app/              Next.js App Router pages
  controllers/      Hile API controllers, default prefix /-
  models/           Reusable business logic
  services/         *.boot.ts and app services
```

Use `loadModel()` from pages or controllers for domain logic. If a Next.js page uses runtime model data, mark the route dynamic:

```tsx theme={null}
export const dynamic = 'force-dynamic'
```

## Runtime And Lifecycle Notes

* `HttpNext` wraps an internal `Http` instance.
* It serves `publicPath`, then `.next/static`, then Hile controllers, then Next.js as the fallback handler.
* Development mode is determined by `process.env.NODE_ENV === 'development'`.
* Controller directory is `{cwd}/src/{controllerDirectory}` in development and `{cwd}/dist/{controllerDirectory}` in production.
* `specialControllers` load additional controller roots with their own prefixes.

## Anti-Patterns

* Putting API routes in Next.js when the app is intentionally using Hile controllers.
* Calling `loadService()` at module top level in Next.js files.
* Forgetting `cwd`; relative controller and Next artifact paths depend on it.

## Verification Checklist

* `HttpNext.start()` close function is registered with `shutdown`.
* Controllers live under the configured controller directory.
* API routes use the configured prefix, default `/-`.
* Next.js production build runs before `hile start` in production.

## Related Recipes

### HttpNext Fullstack App

## Complete Example

Boot:

```ts theme={null}
// src/services/http.boot.ts
import { defineService } from '@hile/core'
import HttpNext from '@hile/http-next'

export default defineService('http.next', async (shutdown) => {
  const app = new HttpNext({
    port: Number(process.env.HTTP_PORT ?? 3000),
    cwd: process.cwd(),
    publicPath: 'public',
  })
  const stop = await app.start()
  shutdown(stop)
  return app
})
```

API controller:

```ts theme={null}
// src/controllers/post.controller.ts
import { defineController } from '@hile/http'
import { loadModel } from '@hile/model'
import { getPost } from '../models/post/get-post.model'

export default defineController('GET', async () => {
  return loadModel(getPost, { id: 'demo' })
})
```

Next.js page:

```tsx theme={null}
// src/app/page.tsx
import { loadModel } from '@hile/model'
import { getPost } from '../models/post/get-post.model'

export const dynamic = 'force-dynamic'

export default async function Page() {
  const post = await loadModel(getPost, { id: 'demo' })
  return <main>{post.title}</main>
}
```

Model:

```ts theme={null}
// src/models/post/get-post.model.ts
import { defineModel } from '@hile/model'

export const getPost = defineModel(async (input: { id: string }) => {
  return { id: input.id, title: 'Hello from Hile' }
})
```

## Package-Local AI Guide

This package also ships `AI.md` in npm so agents can read accurate examples after installation.
