---
title: ops-env
description: Boot time env loading for Node and Bun services on ops. The env file ops renders, read in process, with no $ expansion.
order: 0
---

When ops deploys a service it renders the service's secret group into one env file and
mounts it in the container at `/run/secrets/<name>`, with the name in `ENV_SECRET`. Ops
never puts those variables into the process environment itself. `@syncronet/ops-env` reads
that file into `process.env` before your app starts, on Node 22 or newer and on Bun, with
no runtime dependency.

## Install

The package is on the ops npm registry. Add the registry to the app's `.npmrc`, with a
token that may read packages:

```ini
@syncronet:registry=https://ops.syncronet.dev/npm/
//ops.syncronet.dev/npm/:_authToken=${OPS_NPM_TOKEN}
```

```sh
pnpm add @syncronet/ops-env
```

## The smallest setup

Preload it, so the variables are in place before the first line of your app runs:

```sh
node --import @syncronet/ops-env/register server.js
bun --preload @syncronet/ops-env/register server.ts
```

Or call it first thing in your own entry file:

```ts
import { load } from '@syncronet/ops-env'

load()
```

On your machine, with no `ENV_SECRET`, the same call reads `.env` from the working
directory, so the code is the same in both places.

- [Loading](loading.md): what `load()` reads, what wins, and when it stops the process.
- [Nuxt and Nitro](nuxt.md): why a Nuxt server needs the preload, and how to ship it.
- [The file format](format.md): what a line may hold, and why `$` is never expanded.
