# Same-process calls

> Call your API directly when the client and server run in the same process.

## Useful when

- Server-rendered code and handlers share one JavaScript process.
- Tests should exercise validation, middleware, statuses, and codecs without opening a socket.

Use `inProcessTransport()` to call an implementation from the same JavaScript process. It runs validation, middleware, and the handler without making an HTTP request.

The example calls the server from [Build a task API](https://hulla.dev/guides/api/quick-start.md). Keep this client in server code: it imports the implementation directly.

```ts filename="src/api/local-client.ts"
import { createClient } from '@hulla/api/client'
import { inProcessTransport } from '@hulla/api/in-process'
import { contract } from './contract'
import { implementation } from './implementation'

const api = createClient(contract, {
  transport: inProcessTransport(implementation),
})

const result = await api.createTask({
  body: { title: 'Write the quick start' },
})

console.log(result.body.title) // Write the quick start
```

This is a zero-network call, not an HTTP simulation. Native JSON values pass directly instead of being stringified and parsed, so keep type-only JSON declarations JSON-compatible if the same contract also uses HTTP. Codecs still encode and decode their application values.

## Keep it server-only

Because the local client imports the implementation, place it behind a server-only module boundary. Browser code should build a separate client from the same contract with `fetchTransport()` or another remote transport. [Server and browser calls](https://hulla.dev/docs/api/full-stack/hybrid-rendering.md) explains how to choose and place each client across full-stack frameworks.

Use ordinary functions when no contract lifecycle is needed. In-process transport is useful when a local caller should observe the same validation, middleware, declared statuses, errors, and cancellation behavior as a remote caller.
