---
title: "Environment Variables"
description: "Read and configure environment variables in Bun, including automatic .env file support"
---

Bun reads your `.env` files automatically and provides idiomatic ways to read and write your environment variables programmatically. You can also configure parts of Bun's runtime behavior with Bun-specific environment variables.

## Setting environment variables

Bun reads the following files automatically (listed in order of increasing precedence).

- `.env`
- `.env.production`, `.env.development`, `.env.test` (depending on the value of `NODE_ENV`)
- `.env.local`

```ini .env icon="settings"
FOO=hello
BAR=world
```

You can also set variables on the command line.

<CodeGroup>

```sh Linux/macOS icon="terminal"
FOO=helloworld bun run dev
```

```sh Windows icon="windows"
# Using CMD
set FOO=helloworld && bun run dev

# Using PowerShell
$env:FOO="helloworld"; bun run dev
```

</CodeGroup>

<Accordion title="Cross-platform solution with Windows">

For a cross-platform solution, use [Bun Shell](/runtime/shell), for example through `bun exec`.

```sh
bun exec 'FOO=helloworld bun run dev'
```

On Windows, `package.json` scripts called with `bun run` automatically use the **Bun Shell**, so the following is also cross-platform.

```json package.json icon="file-json"
"scripts": {
  "dev": "NODE_ENV=development bun --watch app.ts",
},
```

</Accordion>

Or set them programmatically by assigning a property to `process.env`.

```ts
process.env.FOO = "hello";
```

---

## Manually specifying `.env` files

The `--env-file` flag overrides which `.env` files Bun loads. It works both when running a file with `bun` and when running `package.json` scripts.

```sh
bun --env-file=.env.1 src/index.ts

bun --env-file=.env.abc --env-file=.env.def run build
```

## Disabling automatic `.env` loading

Use `--no-env-file` to disable Bun's automatic `.env` file loading, for example in production or CI/CD pipelines where you want to rely solely on system environment variables.

```sh
bun run --no-env-file index.ts
```

You can also disable it in `bunfig.toml`:

```toml bunfig.toml icon="settings"
# Disable loading .env files
env = false
```

Files passed with `--env-file` still load even when default loading is disabled.

When Bun is invoked as `node` (for example via `bun --bun`, `bunx --bun`, or a `node` symlink pointing at Bun), automatic `.env` loading is disabled to match Node.js. This lets tools with their own mode-aware `.env` resolution, such as Vite's `loadEnv`, pick the correct `.env.{mode}` file instead of seeing Bun's pre-populated values as shell-set overrides. Explicit `--env-file` arguments are still honored.

---

## Quotation marks

Bun supports double quotes, single quotes, and template literal backticks:

```ini .env icon="settings"
FOO='hello'
FOO="hello"
FOO=`hello`
```

### Expansion

Bun automatically _expands_ environment variables, so you can reference previously-defined variables.

```ini .env icon="settings"
FOO=world
BAR=hello$FOO
```

```ts
process.env.BAR; // => "helloworld"
```

This is useful for constructing connection strings or other compound values.

```ini .env icon="settings"
DB_USER=postgres
DB_PASSWORD=secret
DB_HOST=localhost
DB_PORT=5432
DB_URL=postgres://$DB_USER:$DB_PASSWORD@$DB_HOST:$DB_PORT/$DB_NAME
```

To disable expansion, escape the `$` with a backslash.

```ini .env icon="settings"
FOO=world
BAR=hello\$FOO
```

```ts
process.env.BAR; // => "hello$FOO"
```

### `dotenv`

Bun reads `.env` files automatically, so `dotenv` and `dotenv-expand` are unnecessary.

## Reading environment variables

Read the current environment variables from `process.env`.

```ts
process.env.API_TOKEN; // => "secret"
```

Bun also exposes these variables as `Bun.env` and `import.meta.env`, both aliases of `process.env`.

```ts
Bun.env.API_TOKEN; // => "secret"
import.meta.env.API_TOKEN; // => "secret"
```

To print all currently-set environment variables, run `bun --print process.env`.

```sh
bun --print process.env
BAZ=stuff
FOOBAR=aaaaaa
<lots more lines>
```

## TypeScript

In TypeScript, all properties of `process.env` are typed as `string | undefined`.

```ts
Bun.env.whatever;
// string | undefined
```

To get autocompletion and tell TypeScript to treat a variable as a non-optional string, use [interface merging](https://www.typescriptlang.org/docs/handbook/declaration-merging.html#merging-interfaces).

```ts
declare module "bun" {
  interface Env {
    AWESOME: string;
  }
}
```

Add this declaration to any file in your project. It globally adds the `AWESOME` property to `process.env` and `Bun.env`.

```ts
process.env.AWESOME; // => string
```

## Configuring Bun

Bun reads these environment variables to configure aspects of its behavior.

| Name                                     | Description                                                                                                                                                                                                                                                                                                                                                                   |
| ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `NODE_TLS_REJECT_UNAUTHORIZED`           | `NODE_TLS_REJECT_UNAUTHORIZED=0` disables SSL certificate validation. Useful for testing and debugging, but be very hesitant to use it in production. Node.js introduced this variable; Bun keeps the name for compatibility.                                                                                                                                                 |
| `BUN_CONFIG_VERBOSE_FETCH`               | If `BUN_CONFIG_VERBOSE_FETCH=curl`, then fetch requests log the URL, method, request headers and response headers to the console. This also works with `node:http`. `BUN_CONFIG_VERBOSE_FETCH=1` is equivalent to `BUN_CONFIG_VERBOSE_FETCH=curl` except without the `curl` output.                                                                                           |
| `BUN_RUNTIME_TRANSPILER_CACHE_PATH`      | The runtime transpiler caches the transpiled output of source files larger than 4 KB, which makes CLIs using Bun load faster. If `BUN_RUNTIME_TRANSPILER_CACHE_PATH` is set, the cache is written to that directory. If it is set to an empty string or the string `"0"`, caching is disabled. If it is unset, the cache is written to the platform-specific cache directory. |
| `TMPDIR`                                 | Bun occasionally requires a directory to store intermediate assets during bundling or other operations. If unset, defaults to the platform-specific temporary directory: `/tmp` on Linux, `/private/tmp` on macOS.                                                                                                                                                            |
| `NO_COLOR`                               | If `NO_COLOR=1`, then ANSI color output is [disabled](https://no-color.org/).                                                                                                                                                                                                                                                                                                 |
| `FORCE_COLOR`                            | If `FORCE_COLOR=1`, then ANSI color output is forced on, even if `NO_COLOR` is set.                                                                                                                                                                                                                                                                                           |
| `BUN_CONFIG_MAX_HTTP_REQUESTS`           | Sets the maximum number of concurrent HTTP requests sent by fetch and `bun install`. Defaults to `256`. Lower it if you run into rate limits or connection issues.                                                                                                                                                                                                            |
| `BUN_CONFIG_NO_CLEAR_TERMINAL_ON_RELOAD` | If `BUN_CONFIG_NO_CLEAR_TERMINAL_ON_RELOAD=true`, then `bun --watch` does not clear the console on reload                                                                                                                                                                                                                                                                     |
| `DO_NOT_TRACK`                           | Disable uploading crash reports to `bun.report` on crash. On macOS & Windows, crash report uploads are enabled by default. Other telemetry is not sent, though we plan to add some. If `DO_NOT_TRACK=1`, then auto-uploading crash reports and telemetry are both [disabled](https://do-not-track.dev/).                                                                      |
| `BUN_OPTIONS`                            | Prepends command-line arguments to any Bun execution. For example, `BUN_OPTIONS="--hot"` makes `bun run dev` behave like `bun --hot run dev`.                                                                                                                                                                                                                                 |

## Runtime transpiler caching

For files larger than 4 KB, Bun caches transpiled output into `$BUN_RUNTIME_TRANSPILER_CACHE_PATH` or the platform-specific cache directory. This makes CLIs using Bun load faster.

The cache is global and shared across all projects, and it is content-addressable, so it never contains duplicate entries. It is safe to delete at any time, even while a Bun process is running.

Disable this cache when using ephemeral filesystems like Docker. Bun's Docker images disable it automatically.

### Disable the runtime transpiler cache

To disable the runtime transpiler cache, set `BUN_RUNTIME_TRANSPILER_CACHE_PATH` to an empty string or the string `"0"`.

```sh
BUN_RUNTIME_TRANSPILER_CACHE_PATH=0 bun run dev
```

### What does it cache?

It caches:

- The transpiled output of source files larger than 4 KB.
- The sourcemap for the transpiled output of the file

Cached files use the `.pile` extension.
