---
title: JR2Config
description: "The shape of `jr2.config.ts`: the deployment facts of an Instance, which a Machine cannot carry."
---

# `JR2Config`

Type, in `@jr2/orchestrator/src/config.ts`. It is an export of `@jr2/orchestrator`, on the [Authoring surface](../authoring-surface.md) page, in Config.

```ts
type JR2Config = {
  name?: string;
  secrets?: readonly SecretEntry[];
  git?: GitConfig;
  harness?: HarnessConfig;
  sandbox?: SandboxConfig;
  priorityClasses?: PriorityClasses;
  registry?: string;
  kitRegistry?: string;
  platforms?: readonly string[];
  operator?: {
    manage?: boolean;
  };
};
```

The shape of `jr2.config.ts`: the deployment facts of an Instance, which a Machine cannot carry.
It holds the Instance's name, its secrets, how the cluster authenticates to Repos, what the
Harness can reach, where Sandboxes run, and where images go. It names no Repo, no model and no
Sandbox Image: a Machine names those itself.

Every field is optional, and an Instance can run with no `jr2.config.ts`. Write the file as
`export default defineConfig({ … })`. When the config loads, a file with no default export is
refused: `` <file> has no default export (use `export default defineConfig({…})`) ``. The load also
checks the shape of `git.credentials`, `secrets`, `harness.catalog` and `priorityClasses`. It
checks that `sandbox` is an object, and checks its `resources`. Each refusal names the field.
`jr2 up` checks the rest.

**Fields**

- `name` (optional): `string`

  The Instance's name. Its Kubernetes namespace is this name (`-n` overrides it), and
  `jr2 up` labels every object that it owns with it. Default: the name of the Instance folder.
- `secrets` (optional): `readonly SecretEntry[]`

  Every secret of the Instance, in one list. A secret goes where something names it. A Held
  secret goes where a `workspace()` lists it under `secrets` or an Agent's provider reads it. An
  Effect secret goes where an Effect names it with `secret("name")`. Its `hosts` is a Held
  secret's binding, never its placement: an entry that nothing names goes nowhere. A model API
  key goes here, never in `harness.env`. See [`SecretEntry`](../config.md#secrets). Each entry is checked when the
  config loads: `<file> at secrets[<i>]<path>: <problem>`, followed by the shape of an entry.
- `git` (optional): [`GitConfig`](../config.md#git)

  How the cluster authenticates to Repos, and the fence that a per-run url must pass. It is not
  a list of Repos: a Machine names its Repos in the Repo Slots of its `workspace()`. See
  [`GitConfig`](../config.md#git).
- `harness` (optional): [`HarnessConfig`](../config.md#harness)

  What the Harness can reach: a custom model provider, gateways for catalog providers, env
  vars, and CAs. See [`HarnessConfig`](../config.md#harness).
- `sandbox` (optional): [`SandboxConfig`](../config.md#sandbox)

  Which nodes are Sandbox nodes, and the Size of a Workspace that states none. Default: a
  Sandbox runs wherever an ordinary pod runs, at the kit's Size. See [`SandboxConfig`](../config.md#sandbox).
- `priorityClasses` (optional): [`PriorityClasses`](../config.md#priorityclasses)

  Existing PriorityClasses to use in place of the two that `jr2 up` creates. See
  [`PriorityClasses`](../config.md#priorityclasses).
- `registry` (optional): `string`

  The image registry prefix to which `jr2 up` pushes the images that it builds, such as
  `registry.example.com/team`. It changes between deployments, so read it from `process.env`
  (`.env`). Default: none; `jr2 up` loads the images into the kind cluster. On a cluster that is
  not kind, `jr2 up` then refuses:
  `` context <context> is not a kind cluster and no `registry` is configured ``.
- `kitRegistry` (optional): `string`

  The registry from which this cluster pulls the published Kit images: a mirror for a cluster
  that is self-hosted, air-gapped, or mirror-only. Default: none; the cluster pulls from the
  canonical home, `ghcr.io/snapwich/jr2-harness:<version>` and the others. Set, the cluster pulls
  the same tags from `<kitRegistry>/jr2-harness:<version>`. Fill the mirror with
  `jr2 kit push <registry>`; `jr2 up` never pushes to it. Read it from `process.env` (`.env`).
- `platforms` (optional): `readonly string[]`

  The platforms for which `jr2 up` builds its images, as docker platform strings, such as
  `["linux/arm64"]`. Default: the platforms of the cluster's schedulable nodes that the kit
  releases images for. `jr2 up` reports a node platform that it skips.

  Set it when the nodes cannot tell. One case is a node group that scales up from zero. Another
  is a set of nodes that need no image, such as an amd64 GPU group beside arm64 nodes. When you
  set it, it replaces the default. It adds to nothing and removes from nothing. The kit releases
  images for `linux/amd64` and `linux/arm64` only, so `jr2 up` refuses any other:
  `` `platforms` names <platforms> — the kit releases images for linux/amd64, linux/arm64 and nothing else ``.
- `operator` (optional): `object`

  Settings of the operator layer, for kit development.

  - `manage` (optional): `boolean`

    `false`: `jr2 up` does not converge the operator, and you run its controller yourself.
    Default: `true`.

**Example**

```ts
import { defineConfig, type JR2Config } from "@jr2/orchestrator";

const harness: JR2Config["harness"] = {
  provider: {
    id: "vllm",
    api: "openai-completions",
    baseUrl: process.env.VLLM_URL ?? "",
    models: { "Qwen/Qwen3.6-35B-A3B": { contextWindow: 131072, maxTokens: 16384 } },
  },
};

export default defineConfig({ name: "my-instance", harness });
```

**See also**

- [jr2.config.ts](../config.md)
- [Connect a model](../../get-started/connect-a-model.md)
- [Secrets and trust](../../concepts/secrets-and-trust.md)
- [ADR-0050: What code names, config declares; what the CLI names, discovery finds](../decisions/0050-what-code-names-config-declares-what-the-cli-names-discovery-finds.md)
