# Compatibility

Will June run in your project, and what can your code safely depend on across versions? The table below answers the first; the rest of the page answers the second. For where each export is explained, see [Package surfaces](https://june.dev/docs/reference/packages.md).

## Requirements

| Requirement         | Supported           | Notes                                                   |
| ------------------- | ------------------- | ------------------------------------------------------- |
| Bun                 | `>=1.2.0`           | the runtime for the package and the CLI; nothing else   |
| `react`             | `^19.3.0`           | peer dependency: 19.3 or a later 19.x                   |
| `ai`                | `^7.0.137`          | peer dependency: 7.0.137 or a later 7.x                 |
| `@ai-sdk/openai`    | `^4.0.0`            | optional peer: only for `june/sdk/openai`               |
| `@ai-sdk/anthropic` | `^4.0.0`            | optional peer: only for `june/sdk/anthropic`            |
| `@ai-sdk/google`    | `^4.0.0`            | optional peer: only for `june/sdk/google`               |
| `@ai-sdk/xai`       | `^5.0.0`            | optional peer: only for `june/sdk/xai`                  |
| Module format       | ESM only            | `import`, not `require()`                               |
| Models              | any AI SDK provider | a provider package that works with your version of `ai` |

The ranges are the package's own `engines` and `peerDependencies`, and a test keeps this table in sync with them.

**Bun.** The `june` CLI requires it, and parts of the library call Bun's APIs directly: reading a JSONL file with `dataset()` or `copyCorpus()`, `trl()`, and `vertex()`. Node, Deno and browsers aren't supported.

**ESM only.** Every entrypoint is an ES module with `import` and `types` conditions and no CommonJS build. The `june/sdk/*` wrappers also use top-level `await` to load their provider, so tools that compile ES modules to CommonJS can't load them.

**Dependencies.** Besides its peers, June depends only on `react-reconciler` and `xstate`, at pinned versions. The `@ai-sdk/*` peers are optional: install the ones whose `june/sdk/*` wrapper you import. No other entrypoint loads them. Python's ML packages are only ever installed in the TRL runner's isolated environment.

## What you can depend on

Three tiers. **Stable** changes only with a major version, a deprecation period, or a version bump in its own format. **Less stable** may change in a minor version, with a changelog entry. **Not promised** can change at any time; don't build on it.

## Stable

**Entrypoints.** `june`, `june/train`, `june/trainers`, `june/copy`, `june/chat`, `june/tools`, `june/test` and the `june/sdk/*` provider wrappers, and the values they export, which are locked by a test:

| Entrypoint           | Values                                                                                                                                                                                                                                                        |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `june`               | `Agent`, `Step`, `Parallel`, `Catch`, `Tool`, `Bash`, `Inherit`, `RequireApproval`, `Namespace`, `defineCapabilities`, `defineAgent`, `run`, `start`, `useStep`, `useResource`, `useAgent`                                                                                                                                                     |
| `june/train`         | `dataset`, `fineTune`, `startFineTune`, `fineTuneJob`, `job`, `JobFailedError`, `evalSuite`, `grader`, `evaluate`, `compareEvaluations`, `casesFrom`, `FineTune`, `Evaluate`, `datasetFromSessions`, `preferenceDatasetFromSessions`, `evalCasesFromSessions` |
| `june/trainers`      | `trl`, `vertex`                                                                                                                                                                                                                                               |
| `june/copy`          | `copyCorpus`, `prepareVoice`, `PrepareVoiceError`, `voice`, `loadVoice`, `metadataRetriever`, `stylometry`, `judge`, `Write`                                                                                                                                  |
| `june/chat`          | `createChat`, `modelResponder`, `agentResponder`, `memoryStore`, `fileStore`, `fullContext`, `summaryContext`, `projectChatTrace`                                                                                                                             |
| `june/tools`         | `bashTool`                                                                                                                                                                                                                                                    |
| `june/test`          | `scriptedModel`, `callTools`                                                                                                                                                                                                                                  |
| `june/sdk/openai`    | `openai`                                                                                                                                                                                                                                                      |
| `june/sdk/anthropic` | `anthropic`                                                                                                                                                                                                                                                   |
| `june/sdk/google`    | `google`                                                                                                                                                                                                                                                      |
| `june/sdk/xai`       | `xai`                                                                                                                                                                                                                                                         |

Chat lives only under `june/chat`; the root `june` export doesn't re-export it, or any other entrypoint. Modules inside `dist/` are not part of the public surface.

**Missing providers.** Importing a `june/sdk/*` wrapper without its `@ai-sdk/*` package throws an error with `code: "JUNE_MISSING_PROVIDER_DEPENDENCY"` and the fields `provider`, `packageName` and `importPath`. Match on `code`, not the message. Any other failure while loading a provider is passed on as it is.

**Workflow types.** The types `june` exports, such as `RunHandle`, `RunResult`, `RunSnapshot`, `TraceNode` and `StepResult`. A compile test checks they still exist.

**Run snapshots.** `snapshot()` returns `{ version: 1, steps }`, each step with its `cacheKey` and `result`, as described in [Snapshots and resume](https://june.dev/docs/workflows/resume.md). `run()` and `start()` reject a snapshot with any other version rather than guess. Cache keys are opaque, and June doesn't promise the same key for the same step across versions; a key that doesn't match only means that step runs again.

**`june run --json`.** When the run succeeds, one JSON object with `steps`, `usage` and `tree`: trace nodes keep their `{ type, props, children }` shape, and step nodes the fields in [Traces and usage](https://june.dev/docs/workflows/traces.md#step-fields). New fields may be added. `usage`, and a step's `model` and `finishReason` values, come from the AI SDK and follow the `ai` version you install; `steps` and each `result` are whatever your steps returned. A failed run prints no JSON.

**Canonical example formats.** `completion` (`prompt`, `completion`), `conversation` (`messages`) and `preference` (`input`, `chosen`, `rejected`), each with optional `metadata`, and the JSONL reading rules in [Datasets](https://june.dev/docs/training/datasets.md).

**Fingerprints and splits.** A dataset's fingerprint, and which split an example lands in for a given seed, stay the same for the same examples across versions. A change to either algorithm is a breaking change, since it would silently change what a manifest's fingerprint means or leak test examples into training.

**The `Trainer` contract.** `id`, `capabilities`, `start`, `status` and `cancel`, and the shapes of `TrainingRequest`, `TrainingJob`, `TrainingStatus` and `TrainingOutput`. New optional request fields may be added; trainers must ignore fields they don't know.

**`ModelArtifact` discriminants.** `adapter`, `checkpoint` and `provider-model`, with their documented fields. New artifact types may be added, so handle unknown ones.

**Job states.** `queued`, `running`, `succeeded`, `failed` and `canceled`, with the last three final. `JobRef` and `JobSnapshot` shapes.

**`fineTune()`'s result.** `artifact`, `metrics`, `job` and `manifest`, and the manifest's `version: 1` format. A breaking change to the manifest bumps its `version`.

**Voice manifests.** `VoiceManifest` with `version: 1`.

**The TRL runner contract.** `config.json` with `version: 1`, and the `status.json` and `result.json` files, as described in [Local training](https://june.dev/docs/training/local.md#runs-and-their-files), so custom runners keep working.

**The chat contracts.** `Chat`, `Session`, `Turn`, `Responder` and `ResponseExecution`, `ChatStore`, `ContextBuilder`, and the `ChatEvent` and `ChatJournalEntry` unions. A compile test checks every exported type still exists; their documented fields are stable too. New optional fields and new event types may be added, so handle unknown event types.

**Chat journals.** Entries are `version: 1`: `session.created`, `turn.accepted`, `turn.completed`, `turn.failed`, `turn.canceled`, `turn.steered` and `feedback.recorded`, each with `id`, `sessionId` and `at`. New entry types may be added within version 1, and readers skip types they don't know. A breaking change to an entry bumps `version`, and June refuses to read entries with a version it doesn't know rather than guess. `fileStore()`'s layout, one `<session id>.jsonl` per session, is stable.

**The chat CLI.** `june chat` and `june ask`, `--session` on both and `--json` on `june ask`, and `june ask --json`'s object (`sessionId`, `turnId`, `text`, `metadata`).

## Less stable

These may change in a minor version, with a changelog entry. Where they're output, read their structure, not their text: parse `--json`, and match typed fields and event types rather than strings.

- Anything under a provider namespace: `providerOptions.vertex`, `artifact.metadata.vertex`, `TrainingJob.metadata.trl`, and so on. They follow their providers.
- Which provider HTTP responses `vertex()` retries, and its default retry timing.
- The TRL runner's Python dependency versions, and TRL defaults for unset hyperparameters.
- The teacher, writer and judge prompts in `june/copy`, and the stylometric features and retrieval weights' defaults. These are tuned as evals show what works; pin your own with `instructions`, `metadataRetriever(weights)` or a custom evaluator if you need them fixed.
- The text `june run` prints. Use `--json` for anything that parses output.
- The text `june chat` prints to stderr, and its slash commands.
- `summaryContext()`'s default instructions and the wording of its summary marker.
- The `MockLanguageModelV4` a `june/test` scripted model is, and the call options it records. They come from `ai/test` and follow the `ai` version you install.

## Not promised

June makes no promise about these. Code that depends on them will break without warning:

- Generated text: what a model writes, for the same prompt or not.
- Scores from model-based graders and evaluators, such as `judge()`, across versions or runs.
- Anything a provider decides: which models are tunable, how many examples they need, and what a tuned model costs.
- Modules inside `dist/`, and anything else you can't import from an entrypoint.
- The same cache key for the same step across June versions.
