> ## 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/core

> Define async services, resolve dependencies, and manage graceful shutdown in dependency order.

# @hile/core

Define async services, resolve dependencies, and manage graceful shutdown in dependency order.

## Choose This Package When

| User asks for                                     | Use                                          | Also read                    |
| ------------------------------------------------- | -------------------------------------------- | ---------------------------- |
| Start an app, manage lifecycle, graceful shutdown | `@hile/core`, `@hile/cli`, `@hile/bootstrap` | `packages/core-lifecycle.md` |

## Use When

Use these packages when an app needs managed startup, singleton resources, dependency ordering, environment-file loading, graceful shutdown, logs, Redis, or SQL database connections.

## Do Not Use When

* Do not use `loadService()` at module top level.
* Do not use `auto_load_packages` for file paths. It accepts package names only.
* Do not use the default `@hile/ioredis` or `@hile/typeorm` services when one app needs multiple Redis or database connections; define separate services with separate keys.

## Install

```bash theme={null}
pnpm add @hile/core @hile/logger @hile/ioredis @hile/typeorm
pnpm add -D @hile/cli
```

## Imports

```ts theme={null}
import { defineService, loadService, container } from '@hile/core'
import { createLogger } from '@hile/logger'
import redisService, { createRedis } from '@hile/ioredis'
import typeormService, { createDataSource, transaction } from '@hile/typeorm'
```

## Copy-Paste Example

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

export default defineService('http', async (shutdown) => {
  const http = new Http({ port: Number(process.env.HTTP_PORT ?? 3000) })
  await http.load(new URL('../controllers', import.meta.url).pathname)
  const close = await http.listen()
  shutdown(close)
  return http
})
```

Run:

```bash theme={null}
hile start --dev --env-file .env
```

## More Examples

Use `package.json` auto-load for integration services that default-export a Hile service:

```json theme={null}
{
  "type": "module",
  "scripts": {
    "dev": "hile start --dev --env-file .env",
    "start": "hile start --env-file .env.prod"
  },
  "hile": {
    "auto_load_packages": ["@hile/logger", "@hile/ioredis", "@hile/typeorm"]
  }
}
```

Inside another service, load dependencies:

```ts theme={null}
import { defineService, loadService } from '@hile/core'
import redisService from '@hile/ioredis'
import typeormService from '@hile/typeorm'

export default defineService('user.service', async () => {
  const [redis, ds] = await Promise.all([
    loadService(redisService),
    loadService(typeormService),
  ])
  return { redis, ds }
})
```

## Runtime And Lifecycle Notes

* `defineService(key, fn)` registers a service factory and does not execute it.
* `loadService(service)` executes the factory on first call and returns the cached value afterwards.
* The `shutdown` callback registers teardown functions; they run in LIFO order.
* The container tracks dependencies when service factories call `loadService()`.
* `container.shutdown()` triggers registered teardowns.
* `@hile/bootstrap` loads env files first, sets `NODE_ENV`, imports auto-load packages, scans boot files, and installs exit hooks.
* `@hile/logger.createLogger()` returns `{ logger, teardown }`.
* `@hile/ioredis.createRedis()` waits for `connect`.
* `@hile/typeorm.createDataSource()` initializes a TypeORM `DataSource`.

## Anti-Patterns

* Reusing one service key for unrelated factories.
* Missing `shutdown()` callbacks for network connections or servers.
* Assuming TypeORM env config fills entities automatically when `TYPEORM_ENTITIES` is not set.
* Calling `transaction()` and manually committing; the helper commits or rolls back internally.

## Verification Checklist

* Boot files default-export `defineService(...)`.
* Long-lived resources register teardown callbacks.
* `auto_load_packages` contains package names, not local files.
* `hile start --dev` can find `src/**/*.boot.ts`.
* Production build emits `dist/**/*.boot.js`.

## Related Recipes

### HTTP API + Model + TypeORM

## Complete Example

Controller:

```ts theme={null}
// src/controllers/users/[id].controller.ts
import { defineController } from '@hile/http'
import { loadModel } from '@hile/model'
import { getUser } from '../../models/users/get-user.model'

export default defineController('GET', async (ctx) => {
  return loadModel(getUser, { userId: String(ctx.params.id) })
})
```

Model:

```ts theme={null}
// src/models/users/get-user.model.ts
import { defineModel } from '@hile/model'
import typeormService from '@hile/typeorm'
import { User } from '../../entities/user.entity'

export const getUser = defineModel({
  services: [typeormService] as const,
  async main([ds], input: { userId: string }) {
    const user = await ds.getRepository(User).findOneBy({ id: input.userId })
    if (!user) return { found: false }
    return { found: true, user }
  },
})
```

Boot file:

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

export default defineService('http', async (shutdown) => {
  const http = new Http({ port: Number(process.env.HTTP_PORT ?? 3000) })
  await http.load(new URL('../controllers', import.meta.url).pathname)
  const close = await http.listen()
  shutdown(close)
  return http
})
```

Package config:

```json theme={null}
{
  "type": "module",
  "scripts": {
    "dev": "hile start --dev --env-file .env",
    "start": "hile start --env-file .env.prod"
  },
  "hile": {
    "auto_load_packages": ["@hile/typeorm"]
  }
}
```

## Package-Local AI Guide

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