···74747575## Documentation
76767777-See the [docs/](./docs/) directory:
7878-7979-- [Getting Started](./docs/getting-started.md) — installation, quick start, workflow
8080-- [Configuration](./docs/configuration.md) — all config options (changelog, pre-mode, fixed/linked groups)
8181-- [Usage](./docs/usage.md) — full command reference, release files, version rules, internals
7777+See the full documentation at [oxrls.dev](https://oxrls.dev) or browse the [docs app](./apps/docs) in this repository.
82788379## Build
8480
···11+---
22+title: Configuration
33+description: All configuration options for oxrls
44+---
55+66+oxrls looks for configuration in the following locations (in order of priority):
77+88+1. `.oxrls/config.json` — in the project root or any parent directory
99+2. `oxrls.json` — in the project root or any parent directory
1010+3. `.oxrls.json` — hidden file variant
1111+1212+If no config file is found, oxrls uses sensible defaults.
1313+1414+## Default config
1515+1616+```json
1717+{
1818+ "$schema": "https://oxrelease.dev/schema.json",
1919+ "releaseDir": ".oxrls",
2020+ "changelog": true,
2121+ "generatePackagesChangelog": true,
2222+ "generateGlobalChangelog": false,
2323+ "updateInternalDependencies": "patch",
2424+ "baseBranch": "main",
2525+ "access": "public",
2626+ "syncCargoToml": false,
2727+ "fixed": [],
2828+ "linked": [],
2929+ "preMode": []
3030+}
3131+```
3232+3333+## Options
3434+3535+### `releaseDir`
3636+3737+Default: `".oxrls"`
3838+3939+The directory where release files, pre-release state, and the release plan are stored.
4040+4141+```json
4242+{ "releaseDir": ".oxrls" }
4343+```
4444+4545+You can change this if you prefer a different name:
4646+4747+```json
4848+{ "releaseDir": ".changes" }
4949+```
5050+5151+### `changelog` (legacy)
5252+5353+Default: `true`
5454+5555+Setting this to `false` disables all changelog generation, regardless of the more specific flags below. This exists for backward compatibility.
5656+5757+```json
5858+{ "changelog": false }
5959+```
6060+6161+### `generatePackagesChangelog`
6262+6363+Default: `true`
6464+6565+Generate individual `CHANGELOG.md` files per workspace package.
6666+6767+```json
6868+{ "generatePackagesChangelog": false }
6969+```
7070+7171+### `generateGlobalChangelog`
7272+7373+Default: `false`
7474+7575+Generate a single `CHANGELOG.md` at the project root aggregating all package changes.
7676+7777+```json
7878+{ "generateGlobalChangelog": true }
7979+```
8080+8181+**Solo repo fallback**: if the workspace has only one package and per-package changelogs are enabled, oxrls automatically generates a global changelog instead.
8282+8383+### `updateInternalDependencies`
8484+8585+Default: `"patch"`
8686+8787+Controls when internal dependency ranges are updated for workspace packages that depend on each other.
8888+8989+| Value | Behavior |
9090+| ---------- | ------------------------------------------- |
9191+| `"always"` | Always update ranges |
9292+| `"patch"` | Update when dependency got at least a patch |
9393+| `"minor"` | Update only for minor or major |
9494+| `"major"` | Update only for major |
9595+| `"never"` | Never update |
9696+9797+```json
9898+{ "updateInternalDependencies": "minor" }
9999+```
100100+101101+### `baseBranch`
102102+103103+Default: `"main"`
104104+105105+The base branch of your repository. Used for changelog integration.
106106+107107+```json
108108+{ "baseBranch": "main" }
109109+```
110110+111111+### `access`
112112+113113+Default: `"public"`
114114+115115+The default npm access level for publishing. Can be overridden per-package via `publishConfig.access` in `package.json`.
116116+117117+| Value | Description |
118118+| -------------- | ---------------------------------- |
119119+| `"public"` | Publicly accessible on npm |
120120+| `"restricted"` | Restricted (requires authentication) |
121121+122122+```json
123123+{ "access": "restricted" }
124124+```
125125+126126+### `syncCargoToml`
127127+128128+Default: `false`
129129+130130+When enabled, oxrls also bumps the version in `Cargo.toml` files that are found alongside `package.json`. This is useful for Rust projects that also publish npm packages (e.g., napi-rs projects).
131131+132132+```json
133133+{ "syncCargoToml": true }
134134+```
135135+136136+### `fixed`
137137+138138+Default: `[]`
139139+140140+Groups of packages that **always share the same version**. When any package in a fixed group is bumped, all packages in that group are bumped to the same new version (the highest current version + the highest bump type in the group).
141141+142142+Supports glob patterns and `!` negation:
143143+144144+```json
145145+{
146146+ "fixed": [
147147+ ["@scope/core", "@scope/utils"],
148148+ ["@scope/design-system", "@scope/theme"],
149149+ ["@scope/*", "!@scope/standalone"]
150150+ ]
151151+}
152152+```
153153+154154+If `@scope/core` is bumped to `1.3.0` and `@scope/utils` is at `1.2.0`, both end up at `1.3.0`.
155155+156156+### `linked`
157157+158158+Default: `[]`
159159+160160+Groups of packages that **share the same bump type**. When a package in a linked group receives a bump, all packages in that group get the highest bump type found in the group. Each keeps its own version number.
161161+162162+This is a unique oxrls feature — it sits between "completely independent" and "always the same version" (fixed groups).
163163+164164+Supports glob patterns and `!` negation:
165165+166166+```json
167167+{
168168+ "linked": [
169169+ ["@scope/hooks", "@scope/utils"],
170170+ ["@scope/ui/*", "!@scope/ui-legacy"]
171171+ ]
172172+}
173173+```
174174+175175+If `@scope/hooks` gets a `minor` bump and `@scope/utils` gets a `patch`, both are treated as `minor`. Each increments from its own current version.
176176+177177+### `preMode`
178178+179179+Default: `[]`
180180+181181+Pre-release mode configuration. Packages listed here automatically produce pre-release versions during bump. See the [Pre-releases](/docs/pre-releases) page for full details.
182182+183183+```json
184184+{
185185+ "preMode": [
186186+ {
187187+ "tag": "beta",
188188+ "packages": ["@scope/experimental-*", "@scope/new-feature"]
189189+ },
190190+ {
191191+ "tag": "alpha",
192192+ "packages": ["@scope/early-access-*"]
193193+ }
194194+ ]
195195+}
196196+```
197197+198198+Different packages can have different pre-release tags. A package can only be in one pre-mode at a time.
199199+200200+## Creating config
201201+202202+```bash
203203+# Interactive wizard
204204+oxrls init
205205+206206+# Specify custom release directory
207207+oxrls init --release-dir .changes
208208+209209+# Skip wizard, use defaults
210210+oxrls init --non-interactive
211211+212212+# Overwrite existing config
213213+oxrls init --force
214214+```
+167
apps/docs/content/docs/index.mdx
···11+---
22+title: Getting Started
33+description: Install from npm and run your first release with oxrls
44+---
55+66+**oxrls** (short for _oxrelease_) is a Rust-powered release management CLI for JavaScript/TypeScript monorepos. It handles version bumps, changelogs, internal dependency updates, pre-release versions, and npm publishing.
77+88+## Install from npm
99+1010+Install oxrls as a dev dependency in your project:
1111+1212+```bash
1313+npm install @bdbchgg/oxrls --save-dev
1414+```
1515+1616+Or with pnpm:
1717+1818+```bash
1919+pnpm add @bdbchgg/oxrls --save-dev
2020+```
2121+2222+Or with yarn:
2323+2424+```bash
2525+yarn add @bdbchgg/oxrls --dev
2626+```
2727+2828+## Add to package.json
2929+3030+Add oxrls commands to your `package.json` scripts for convenience:
3131+3232+```json
3333+{
3434+ "scripts": {
3535+ "oxrls": "oxrls",
3636+ "changeset": "oxrls new",
3737+ "bump": "oxrls bump",
3838+ "release": "oxrls release"
3939+ }
4040+}
4141+```
4242+4343+Now you can run `npm run oxrls` (or `pnpm oxrls`) instead of `npx oxrls`.
4444+4545+Once installed, verify it works:
4646+4747+```bash
4848+npx oxrls --help
4949+```
5050+5151+## Initialize
5252+5353+```bash
5454+oxrls init
5555+```
5656+5757+This starts an interactive wizard that sets up your project step by step:
5858+5959+1. **Release directory** — where release files are stored (default: `.oxrls`)
6060+2. **Changelog preferences** — per-package, global, or none
6161+3. **Base branch** — usually `main`
6262+4. **Internal dependency strategy** — when to update cross-package versions
6363+5. **npm access** — `public` or `restricted`
6464+6. **Cargo.toml sync** — whether to bump Rust crate versions alongside npm packages
6565+7. **Linked groups** — packages that share the same bump type
6666+8. **Fixed groups** — packages that always share the same version
6767+6868+The wizard creates `.oxrls/config.json` with your settings.
6969+7070+You can also skip the wizard:
7171+7272+```bash
7373+oxrls init --non-interactive
7474+```
7575+7676+## Create a release file
7777+7878+```bash
7979+# Interactive — select packages, choose bump type, write summary
8080+oxrls new
8181+8282+# Non-interactive
8383+oxrls new --package @scope/core:patch --summary "Fix transaction mapping bug"
8484+8585+# Multiple packages
8686+oxrls new \
8787+ --package @scope/core:patch \
8888+ --package @scope/react:minor \
8989+ --summary "Improve editor behavior"
9090+```
9191+9292+This creates a markdown release file in `.oxrls/` with a descriptive name like `a3f2-calm-fox.md`.
9393+9494+## Preview and bump
9595+9696+```bash
9797+# See pending release files and calculated bumps
9898+oxrls status
9999+100100+# Preview what would happen
101101+oxrls bump --dry-run
102102+103103+# Apply version bumps, update deps, generate changelogs
104104+oxrls bump
105105+```
106106+107107+The `bump` command:
108108+109109+1. Reads and validates all pending release files
110110+2. Merges bump types (major > minor > patch)
111111+3. Resolves fixed and linked group constraints
112112+4. Applies pre-release tags if configured
113113+5. Updates all `package.json` versions
114114+6. Updates internal dependency ranges
115115+7. Generates changelogs
116116+8. Saves a release plan for the next step
117117+118118+If anything fails, nothing is written.
119119+120120+## Publish
121121+122122+```bash
123123+# Publish all bumped packages to npm
124124+oxrls release
125125+126126+# Preview without publishing
127127+oxrls release --dry-run
128128+129129+# Publish with a custom dist-tag
130130+oxrls release --tag next
131131+```
132132+133133+oxrls handles the details:
134134+135135+- Skips private packages
136136+- Checks if a version already exists on the registry before publishing
137137+- Reads `publishConfig.access` and `publishConfig.registry` from each package's `package.json`
138138+- Uses the right dist-tag (pre-release tag, `--tag` override, or `latest`)
139139+140140+## Full workflow example
141141+142142+```bash
143143+# Install
144144+npm install @bdbchgg/oxrls --save-dev
145145+146146+# Initialize
147147+oxrls init
148148+149149+# Record changes
150150+oxrls new --package @scope/core:patch --summary "Fix transaction mapping bug"
151151+152152+# Preview
153153+oxrls status
154154+oxrls bump --dry-run
155155+156156+# Apply
157157+oxrls bump
158158+159159+# Publish
160160+oxrls release
161161+```
162162+163163+## Requirements
164164+165165+- Node.js 18+ project with `package.json`
166166+- npm, pnpm, or yarn for publishing
167167+- A Git repository (for changelog integration)
···11+---
22+title: Pre-releases
33+description: Manage alpha, beta, and rc releases with oxrls
44+---
55+66+oxrls has built-in support for pre-release versions (alpha, beta, rc, or any tag you define). Pre-release versions are useful for testing changes before a stable release.
77+88+## How it works
99+1010+When a package is in pre-release mode, `oxrls bump` produces versions like `1.2.4-beta.1` instead of `1.2.4`. The pre-release tag is also used as the npm dist-tag during `oxrls release`.
1111+1212+## Configuration
1313+1414+You can configure pre-release mode in two ways:
1515+1616+### Via config file
1717+1818+Add `preMode` entries to your `.oxrls/config.json`:
1919+2020+```json
2121+{
2222+ "preMode": [
2323+ {
2424+ "tag": "beta",
2525+ "packages": ["@scope/experimental-*"]
2626+ },
2727+ {
2828+ "tag": "alpha",
2929+ "packages": ["@scope/early-access-*"]
3030+ }
3131+ ]
3232+}
3333+```
3434+3535+Each entry specifies a tag and the packages it applies to. Package names support glob patterns and `!` negation:
3636+3737+```json
3838+{
3939+ "preMode": [
4040+ {
4141+ "tag": "rc",
4242+ "packages": ["@scope/*", "!@scope/stable-core"]
4343+ }
4444+ ]
4545+}
4646+```
4747+4848+A package can only belong to one pre-mode entry at a time.
4949+5050+### Via CLI
5151+5252+Use the `pre` command for interactive management:
5353+5454+```bash
5555+# Interactive: select packages and enter a tag
5656+oxrls pre
5757+5858+# Enter pre-release mode
5959+oxrls pre enter beta --package @scope/pkg-c
6060+oxrls pre enter beta --package @scope/pkg-c --package @scope/pkg-d
6161+oxrls pre enter beta --package "@scope/pre-*"
6262+6363+# Migrate from one tag to another
6464+oxrls pre enter rc --package @scope/pkg-c --force
6565+6666+# Exit pre-release mode
6767+oxrls pre exit --package @scope/pkg-c
6868+oxrls pre exit --package "@scope/pre-*"
6969+7070+# Show current status
7171+oxrls pre status
7272+```
7373+7474+Package name resolution supports:
7575+7676+- **Exact names**: `@scope/pkg-c`
7777+- **Partial names**: `pkg-c` resolves to `@scope/pkg-c` by suffix matching
7878+- **Globs**: `"@scope/pre-*"`
7979+- **Negation**: `"!@scope/special"` (in config only)
8080+8181+## Version behavior
8282+8383+When `oxrls bump` runs, pre-release versions are computed as follows:
8484+8585+| Current version | Bump | Result |
8686+| --------------- | ------ | ---------------- |
8787+| `1.2.3` | patch | `1.2.4-beta.1` |
8888+| `1.2.3` | minor | `1.3.0-beta.1` |
8989+| `1.2.3` | major | `2.0.0-beta.1` |
9090+| `1.2.4-beta.1` | patch | `1.2.4-beta.2` |
9191+| `1.2.4-beta.5` | minor | `1.2.4-beta.6` |
9292+9393+Key behaviors:
9494+9595+- **First pre-release bump**: The base version is bumped first (e.g., `1.2.3` → `1.2.4`), then the tag is appended with counter 1.
9696+- **Subsequent bumps**: Only the pre-release counter increments. The base version stays the same.
9797+- **Tag migration**: Moving from `beta` to `rc` resets the counter to 1 (`1.2.4-rc.1`).
9898+- **Exit pre-release mode**: The version drops the tag entirely (`1.2.4-beta.3` → `1.2.4`).
9999+100100+## State file
101101+102102+Pre-release state is stored in `.oxrls/pre.json`:
103103+104104+```json
105105+{
106106+ "@scope/pkg-c": { "tag": "beta", "count": 3 },
107107+ "@scope/pkg-d": { "tag": "alpha", "count": 1 }
108108+}
109109+```
110110+111111+This file is managed automatically during `oxrls bump`.
112112+113113+### Atomic counters
114114+115115+The pre-release counter is **only saved after all file writes succeed**. If `oxrls bump` fails partway through, the counter does not increment. This means a retry produces the same pre-release version — no wasted pre-release numbers.
116116+117117+## Publishing
118118+119119+Pre-release versions are published with the appropriate npm dist-tag:
120120+121121+```bash
122122+# Automatically uses the pre-release tag (e.g., --tag beta)
123123+oxrls release
124124+125125+# Override the dist-tag
126126+oxrls release --tag next
127127+```
128128+129129+If a package has a pre-release version like `2.0.0-rc.1`, oxrls publishes with `--tag rc` automatically.
130130+131131+## Mixed pre-release and stable
132132+133133+A single `oxrls bump` can handle both pre-release and stable packages:
134134+135135+- Pre-release packages get their tagged versions
136136+- Stable packages get normal versions
137137+- Changelogs are generated for both, but pre-release entries are consumed without generating duplicate entries on the next cycle
+309
apps/docs/content/docs/usage.mdx
···11+---
22+title: Command Reference
33+description: Complete reference for all oxrls commands and their options
44+---
55+66+## `oxrls init`
77+88+Initialize oxrls configuration in your project.
99+1010+```bash
1111+oxrls init [OPTIONS]
1212+```
1313+1414+**Options:**
1515+1616+| Option | Description |
1717+| --------------------- | -------------------------------------------- |
1818+| `--force` | Overwrite existing config |
1919+| `--release-dir <DIR>` | Custom release directory (default: `.oxrls`) |
2020+| `--non-interactive` | Skip the config wizard and use defaults |
2121+2222+**Interactive mode** (default): walks you through all config options step by step via a terminal wizard:
2323+2424+1. Release directory
2525+2. Changelog preferences (per-package, global, or none)
2626+3. Base branch
2727+4. Internal dependency update strategy
2828+5. Default npm access
2929+6. Cargo.toml sync (toggle on/off)
3030+7. Linked package groups (monorepo only)
3131+8. Fixed package groups (monorepo only)
3232+3333+**Non-interactive mode** creates config with defaults.
3434+3535+---
3636+3737+## `oxrls new`
3838+3939+Create a new release file describing version bumps for one or more packages.
4040+4141+```bash
4242+oxrls new [OPTIONS]
4343+```
4444+4545+**Interactive mode** (no flags): select packages from your workspace, choose one bump type for all, enter summary + optional details.
4646+4747+**Non-interactive mode:**
4848+4949+```bash
5050+oxrls new --package @scope/core:patch --summary "Fix bug"
5151+oxrls new \
5252+ --package @scope/core:patch \
5353+ --package @scope/react:minor \
5454+ --summary "Improve editor behavior"
5555+```
5656+5757+**Options:**
5858+5959+| Option | Description |
6060+| ---------------------------- | -------------------------------- |
6161+| `-p`, `--package <PKG:TYPE>` | Package + bump type (repeatable) |
6262+| `--summary <TEXT>` | Summary of the change |
6363+| `--details <TEXT>` | Optional body text |
6464+6565+**Generated file:**
6666+6767+```markdown
6868+---
6969+'@scope/core': patch
7070+'@scope/react': minor
7171+---
7272+7373+Improve editor behavior.
7474+```
7575+7676+Files use random descriptive names like `a3f2-calm-fox.md`.
7777+7878+**Release file format rules:**
7979+8080+- Frontmatter is required (delimited by `---`)
8181+- Bump types: `patch`, `minor`, `major`
8282+- Body must not be empty
8383+- Unknown packages produce a clear error
8484+8585+---
8686+8787+## `oxrls status`
8888+8989+Show pending release files and their calculated version bumps.
9090+9191+```bash
9292+oxrls status
9393+```
9494+9595+Displays:
9696+9797+- All pending `.md` files in the release directory
9898+- Parsed bump types per package
9999+- Calculated version bumps (same logic as `bump --dry-run`)
100100+101101+---
102102+103103+## `oxrls bump`
104104+105105+Consume all pending release files and apply version bumps.
106106+107107+```bash
108108+oxrls bump [--dry-run] [--archive]
109109+```
110110+111111+**Options:**
112112+113113+| Option | Description |
114114+| ----------- | -------------------------------------------------------------- |
115115+| `--dry-run` | Preview changes without writing anything |
116116+| `--archive` | Move consumed release files to `.oxrls/archive/` instead of deleting |
117117+118118+**Process:**
119119+120120+1. Read and validate all pending release files
121121+2. Merge bump types (major > minor > patch)
122122+3. Resolve pre-release tags and counters
123123+4. Apply fixed and linked group constraints
124124+5. Compute new versions
125125+6. Update `package.json` versions
126126+7. Update internal dependency ranges in dependent packages
127127+8. Generate or update `CHANGELOG.md` files
128128+9. Save release plan for `oxrls release`
129129+10. Consume release files (delete or archive)
130130+131131+**Safety**: read everything → validate → compute plan → write files. If anything fails, nothing is written.
132132+133133+---
134134+135135+## `oxrls check`
136136+137137+CI-friendly status check. Designed for release pipelines.
138138+139139+```bash
140140+oxrls check
141141+```
142142+143143+**Exit codes:**
144144+145145+| Exit code | Status | Meaning |
146146+| --------- | ------------------ | ------------------------------------------ |
147147+| 0 | `PendingReleases` | Release files exist — run `bump` |
148148+| 1 | `ReadyToRelease` | Release plan exists — run `release` |
149149+| 0 | `NothingToRelease` | Nothing pending, nothing to do |
150150+151151+**Example CI workflow:**
152152+153153+```yaml
154154+# After merging a PR with release files:
155155+oxrls check # exits 0
156156+oxrls bump # applies bumps, creates releaseplan.txt
157157+git commit -am "chore: bump versions"
158158+git push
159159+160160+# Then trigger publish step:
161161+oxrls check # exits 1 (ReadyToRelease)
162162+oxrls release # publishes to npm
163163+```
164164+165165+---
166166+167167+## `oxrls release`
168168+169169+Publish bumped packages to npm.
170170+171171+```bash
172172+oxrls release [--dry-run] [--tag <TAG>]
173173+```
174174+175175+**Options:**
176176+177177+| Option | Description |
178178+| ----------- | ------------------------------ |
179179+| `--dry-run` | Preview without publishing |
180180+| `--tag` | Override npm dist-tag for all packages |
181181+182182+Reads `.oxrls/releaseplan.txt` — a plain text list of package names, one per line, alphabetically sorted. This file is created by `oxrls bump`.
183183+184184+**Behavior:**
185185+186186+| Condition | Action |
187187+| --------- | ------ |
188188+| Private package (`"private": true`) | Skipped |
189189+| Version mismatch | Error — `package.json` version must match expected |
190190+| Already published | Skipped (checks `npm view <pkg>@<version> version`) |
191191+| No dist-tag override | Uses pre-release tag from version, or `"latest"` |
192192+| Pre-release version | Auto-tagged with pre-release tag |
193193+| Custom registry | Reads `publishConfig.registry` from `package.json` |
194194+| Access level | Reads `publishConfig.access` → falls back to config |
195195+196196+After successful publishing, `releaseplan.txt` is removed.
197197+198198+```bash
199199+oxrls release --dry-run # preview
200200+oxrls release # publish everything
201201+oxrls release --tag next # override dist-tag for all packages
202202+```
203203+204204+---
205205+206206+## `oxrls pre`
207207+208208+Manage pre-release mode for packages.
209209+210210+```bash
211211+oxrls pre [SUBCOMMAND]
212212+```
213213+214214+**Interactive mode** (no subcommand): select packages from a list, then enter a tag name (defaults to `beta`).
215215+216216+### `oxrls pre enter`
217217+218218+Enter pre-release mode for one or more packages.
219219+220220+```bash
221221+oxrls pre enter <TAG> --package <PATTERN> [OPTIONS]
222222+```
223223+224224+| Flag | Description |
225225+| ---- | ----------- |
226226+| `--package` / `-p` | Package name or glob pattern (repeatable) |
227227+| `--force` | Force migration when package is already in pre-mode under a different tag |
228228+229229+```bash
230230+# Enter beta for a single package
231231+oxrls pre enter beta --package @scope/pkg-c
232232+233233+# Enter beta for multiple packages
234234+oxrls pre enter beta --package @scope/pkg-c --package @scope/pkg-d
235235+236236+# Enter beta using a glob pattern
237237+oxrls pre enter beta --package "@scope/pre-*"
238238+239239+# Migrate from one tag to another
240240+oxrls pre enter rc --package @scope/pkg-c --force
241241+```
242242+243243+### `oxrls pre exit`
244244+245245+Exit pre-release mode for one or more packages.
246246+247247+```bash
248248+oxrls pre exit --package <PATTERN>
249249+```
250250+251251+```bash
252252+oxrls pre exit --package @scope/pkg-c
253253+oxrls pre exit --package "@scope/pre-*"
254254+```
255255+256256+### `oxrls pre status`
257257+258258+Show the current pre-release state for all packages.
259259+260260+```bash
261261+oxrls pre status
262262+```
263263+264264+**Package name resolution** works across all `pre` subcommands:
265265+266266+| Input | Matches |
267267+| ----- | ------- |
268268+| `@scope/pkg-c` | Exact name |
269269+| `pkg-c` | Suffix match — resolves to `@scope/pkg-c` |
270270+| `"@scope/pre-*"` | Glob pattern |
271271+| `"!@scope/special"` | Negation (in config only) |
272272+273273+---
274274+275275+## Version bump rules
276276+277277+| Current | Bump | Result |
278278+| ------- | ----- | ------ |
279279+| `1.2.3` | patch | `1.2.4` |
280280+| `1.2.3` | minor | `1.3.0` |
281281+| `1.2.3` | major | `2.0.0` |
282282+| `0.2.3` | major | `1.0.0` |
283283+| `0.2.3` | minor | `0.3.0` |
284284+| `0.2.3` | patch | `0.2.4` |
285285+286286+Multiple bumps for the same package: **major > minor > patch**. If a package receives both a `patch` and a `major` bump, the `major` wins.
287287+288288+## Internal dependency updates
289289+290290+oxrls updates dependency ranges in `dependencies`, `devDependencies`, `peerDependencies`, and `optionalDependencies`:
291291+292292+| Original | Updated |
293293+| ------------------ | ------------------ |
294294+| `^1.2.3` | `^1.2.4` |
295295+| `~1.2.3` | `~1.2.4` |
296296+| `1.2.3` | `1.2.4` |
297297+| `workspace:*` | `workspace:*` |
298298+| `workspace:^` | `workspace:^` |
299299+| `workspace:~` | `workspace:~` |
300300+| `workspace:^1.2.3` | `workspace:^1.2.4` |
301301+302302+oxrls uses range intelligence to avoid false matches — it will not match `^1.2.3` inside `^1.2.30` when updating to `1.2.4`.
303303+304304+## Exit codes
305305+306306+| Code | Meaning |
307307+| ---- | ------- |
308308+| 0 | Success |
309309+| 1 | Error or `ReadyToRelease` (check command) |
+105
apps/docs/content/docs/vs-changesets.mdx
···11+---
22+title: oxrls vs Changesets
33+description: How oxrls differs from Changesets
44+---
55+66+oxrls follows the same release file workflow that Changesets popularized (create release files → bump → publish), but it makes different design choices in a few areas.
77+88+## Globbing for groups
99+1010+oxrls supports glob patterns and `!` negation in all package-name lists in the config — `fixed`, `linked`, and `preMode`.
1111+1212+In Changesets, you list exact package names:
1313+1414+```json
1515+{
1616+ "fixed": [["@scope/core", "@scope/utils"]]
1717+}
1818+```
1919+2020+In oxrls, you can use globs:
2121+2222+```json
2323+{
2424+ "fixed": [
2525+ ["@scope/core", "@scope/utils"],
2626+ ["@scope/*", "!@scope/standalone"]
2727+ ]
2828+}
2929+```
3030+3131+This means you can define a fixed or linked group for all packages under a scope without updating the config when new packages are added. The same glob support applies to `preMode` package patterns.
3232+3333+## Linked groups
3434+3535+Changesets supports `fixed` groups (same version for all members). oxrls adds `linked` groups — packages that share the same bump type but keep their own version numbers.
3636+3737+```json
3838+{
3939+ "linked": [["@scope/hooks", "@scope/utils"]]
4040+}
4141+```
4242+4343+If `@scope/hooks` gets a `minor` bump and `@scope/utils` gets a `patch`, both are treated as `minor`. Each increments from its own current version. This is useful when packages are tightly coupled but don't need to be version-locked.
4444+4545+## Per-package pre-release mode
4646+4747+In Changesets, pre-release is usually a global mode — either the whole repo is in pre-release or it isn't.
4848+4949+oxrls takes a per-package approach. Different packages can have different pre-release tags simultaneously:
5050+5151+```json
5252+{
5353+ "preMode": [
5454+ { "tag": "beta", "packages": ["@scope/experimental-*"] },
5555+ { "tag": "alpha", "packages": ["@scope/early-access-*"] }
5656+ ]
5757+}
5858+```
5959+6060+You can also manage this via CLI:
6161+6262+```bash
6363+oxrls pre enter beta --package @scope/core
6464+oxrls pre enter alpha --package @scope/experimental-feature
6565+```
6666+6767+And a single `oxrls bump` can handle a mix of pre-release and stable packages in one run.
6868+6969+## Other differences
7070+7171+### `syncCargoToml`
7272+7373+oxrls can bump versions in `Cargo.toml` alongside `package.json` — useful for Rust + npm projects (napi-rs, Tauri, etc.).
7474+7575+### CI check command
7676+7777+oxrls has a `check` command designed for multi-step CI pipelines. It uses exit codes to signal the current state:
7878+7979+```bash
8080+oxrls check # exit 0 = pending or nothing, exit 1 = ready to release
8181+```
8282+8383+### Pre-release counters
8484+8585+oxrls saves pre-release counters only after all file writes succeed. If a `bump` fails partway through, the counter is not incremented — a retry produces the same version. This avoids wasting pre-release numbers on failed runs.
8686+8787+### Internal dependency strategies
8888+8989+oxrls lets you control when internal dependency ranges update:
9090+9191+| Strategy | Behavior |
9292+| -------- | -------- |
9393+| `patch` | Update when dependency got at least a patch (default) |
9494+| `minor` | Update only for minor or major |
9595+| `major` | Update only for major |
9696+| `always` | Always update |
9797+| `never` | Never update |
9898+9999+### Random file names
100100+101101+Release files get descriptive names like `a3f2-calm-fox.md` instead of timestamp-based names.
102102+103103+### Archive mode
104104+105105+`oxrls bump --archive` moves consumed release files to `.oxrls/archive/` instead of deleting them.
+1
apps/docs/lib/cn.ts
···11+export { twMerge as cn } from 'tailwind-merge'
+12
apps/docs/lib/layout.shared.tsx
···11+import type { BaseLayoutProps } from 'fumadocs-ui/layouts/shared'
22+import { appName, gitConfig } from './shared'
33+44+export function baseOptions(): BaseLayoutProps {
55+ return {
66+ nav: {
77+ // JSX supported
88+ title: appName,
99+ },
1010+ githubUrl: `https://github.com/${gitConfig.user}/${gitConfig.repo}`,
1111+ }
1212+}
···11-# Configuration
22-33-oxrls looks for `.oxrls/config.json` or `..oxrls/config.json` in the project root or any parent directory.
44-55-## Default config
66-77-```json
88-{
99- "$schema": "https://oxrelease.dev/schema.json",
1010- "releaseDir": ".oxrls",
1111- "changelog": true,
1212- "generatePackagesChangelog": true,
1313- "generateGlobalChangelog": false,
1414- "updateInternalDependencies": "patch",
1515- "baseBranch": "main",
1616- "access": "public",
1717- "fixed": [],
1818- "linked": [],
1919- "preMode": []
2020-}
2121-```
2222-2323-## Options
2424-2525-### `releaseDir`
2626-2727-Default: `".oxrls"`
2828-2929-```json
3030-{ "releaseDir": ".oxrls" }
3131-```
3232-3333-### `changelog` (legacy)
3434-3535-Default: `true`
3636-3737-Setting this to `false` disables all changelog generation, regardless of the new flags below.
3838-3939-### `generatePackagesChangelog`
4040-4141-Default: `true`
4242-4343-Generate individual `CHANGELOG.md` files per workspace package.
4444-4545-```json
4646-{ "generatePackagesChangelog": false }
4747-```
4848-4949-### `generateGlobalChangelog`
5050-5151-Default: `false`
5252-5353-Generate a single `CHANGELOG.md` at the project root aggregating all package changes.
5454-5555-```json
5656-{ "generateGlobalChangelog": true }
5757-```
5858-5959-**Solo repo fallback**: if the workspace has only one package and per-package changelogs are enabled, oxrls automatically generates a global changelog instead.
6060-6161-### `updateInternalDependencies`
6262-6363-Default: `"patch"`
6464-6565-Controls when internal dependency ranges are updated:
6666-6767-| Value | Behavior |
6868-| ---------- | ------------------------------------------- |
6969-| `"always"` | Always update ranges |
7070-| `"patch"` | Update when dependency got at least a patch |
7171-| `"minor"` | Update only for minor or major |
7272-| `"major"` | Update only for major |
7373-| `"never"` | Never update |
7474-7575-### `baseBranch`
7676-7777-Default: `"main"`
7878-7979-### `access`
8080-8181-Default: `"public"`
8282-8383-Either `"public"` or `"restricted"`. Overridable per-package via `publishConfig.access` in `package.json`.
8484-8585-### `fixed`
8686-8787-Default: `[]`
8888-8989-Groups of packages that **always share the same version**. When any member is bumped, all members get bumped to the same new version (highest old version + max bump type).
9090-9191-Supports glob patterns and `!` negation:
9292-9393-```json
9494-{
9595- "fixed": [
9696- ["@scope/design-system", "@scope/theme"],
9797- ["@scope/*", "!@scope/standalone"]
9898- ]
9999-}
100100-```
101101-102102-### `linked`
103103-104104-Default: `[]`
105105-106106-Groups of packages that **share the same bump type**. When a member receives a bump, all members in the group get the highest bump type found in the group.
107107-108108-Supports glob patterns and `!` negation:
109109-110110-```json
111111-{
112112- "linked": [["@scope/hooks", "@scope/utils"]]
113113-}
114114-```
115115-116116-### `preMode`
117117-118118-Default: `[]`
119119-120120-Pre-release mode configuration. Packages listed here produce pre-release versions with a tag suffix.
121121-122122-```json
123123-{
124124- "preMode": [
125125- {
126126- "tag": "beta",
127127- "packages": ["@scope/experimental-*", "@scope/new-feature"]
128128- },
129129- {
130130- "tag": "alpha",
131131- "packages": ["@scope/early-access-*"]
132132- }
133133- ]
134134-}
135135-```
136136-137137-**Per-package granularity**: different packages can have different pre-release tags. A package can only be in one pre-mode at a time.
138138-139139-**Version behavior:**
140140-| Scenario | Result |
141141-|----------|--------|
142142-| `1.2.3` + patch + beta | `1.2.4-beta.1` |
143143-| `1.2.3` + major + rc | `2.0.0-rc.1` |
144144-| Bump again in beta | `1.2.4-beta.2` |
145145-| Exit pre-mode | `1.2.4` (normal) |
146146-| Migrate beta → rc | counter resets → `2.0.0-rc.1` |
147147-148148-**State file**: `.oxrls/pre.json` tracks per-package counters. Auto-managed during `oxrls bump`.
149149-150150-## Creating config
151151-152152-```bash
153153-oxrls init
154154-oxrls init --release-dir .changes
155155-oxrls init --force # overwrite existing
156156-```
-98
packages/oxrls/docs/getting-started.md
···11-# Getting Started with oxrls
22-33-**oxrls** (short for _oxrelease_) is a Rust-powered release management CLI for JavaScript/TypeScript monorepos. It handles version bumps, changelogs, internal dependency updates, pre-release versions, and npm publishing.
44-55-## Installation
66-77-Build from source:
88-99-```bash
1010-cargo build --release
1111-```
1212-1313-The binary is at `target/release/oxrls`. Install to PATH:
1414-1515-```bash
1616-cargo install --path .
1717-```
1818-1919-## Quick start
2020-2121-### 1. Initialize
2222-2323-```bash
2424-oxrls init
2525-```
2626-2727-Creates `.oxrls/config.json` with defaults and a `.oxrls/` directory.
2828-2929-### 2. Create a release file
3030-3131-```bash
3232-# Interactive — select packages, choose bump type, write summary
3333-oxrls new
3434-3535-# Non-interactive
3636-oxrls new --package @scope/core:patch --summary "Fix transaction mapping bug"
3737-3838-# Multiple packages
3939-oxrls new \
4040- --package @scope/core:patch \
4141- --package @scope/react:minor \
4242- --summary "Improve editor behavior"
4343-```
4444-4545-### 3. Preview and apply
4646-4747-```bash
4848-oxrls status # shows pending release files and calculated bumps
4949-oxrls bump --dry-run # preview without writing
5050-oxrls bump # apply version bumps, update deps, generate changelogs
5151-```
5252-5353-### 4. Publish
5454-5555-```bash
5656-oxrls release # publish all bumped packages to npm
5757-oxrls release --dry-run # preview without publishing
5858-oxrls release --tag beta # publish with a custom npm dist-tag
5959-```
6060-6161-## Example workflow
6262-6363-```bash
6464-oxrls init
6565-6666-# Record changes
6767-oxrls new --package @scope/core:patch --summary "Fix transaction mapping bug"
6868-6969-# Apply
7070-oxrls status
7171-oxrls bump --dry-run
7272-oxrls bump
7373-7474-# Publish
7575-oxrls release
7676-```
7777-7878-After `oxrls bump`:
7979-8080-- Package versions are updated in `package.json`
8181-- Internal dependency ranges are updated
8282-- `CHANGELOG.md` is created/updated
8383-- Release files are consumed
8484-- A `.oxrls/releaseplan.txt` is written for `oxrls release`
8585-8686-## Workspace detection
8787-8888-oxrls auto-detects workspaces from:
8989-9090-- `package.json` workspaces (array or object format)
9191-- `pnpm-workspace.yaml`
9292-- No config = single-package mode (root is the only package)
9393-9494-## Requirements
9595-9696-- Rust 2021 edition
9797-- Node.js project with `package.json`
9898-- `npm` for publishing
-305
packages/oxrls/docs/usage.md
···11-# Usage
22-33-## Commands
44-55-### `oxrls init`
66-77-```bash
88-oxrls init [OPTIONS]
99-```
1010-1111-**Options:**
1212-1313-| Option | Description |
1414-| --------------------- | -------------------------------------------- |
1515-| `--force` | Overwrite existing config |
1616-| `--release-dir <DIR>` | Custom release directory (default: `.oxrls`) |
1717-| `--non-interactive` | Skip the config wizard and use defaults |
1818-1919-**Interactive mode** (default): walks you through all config options step by step:
2020-2121-1. Release directory
2222-2. Changelog preferences (per-package, global, or none)
2323-3. Base branch
2424-4. Internal dependency update strategy
2525-5. Default npm access
2626-6. Linked package groups (monorepo only)
2727-7. Fixed package groups (monorepo only)
2828-2929-**Non-interactive mode** (`--non-interactive`): creates config with defaults, same as before.
3030-3131----
3232-3333-### `oxrls new`
3434-3535-```bash
3636-oxrls new [OPTIONS]
3737-```
3838-3939-**Interactive mode** (no flags): select packages, choose one bump type for all, enter summary + optional details.
4040-4141-**Non-interactive mode:**
4242-4343-```bash
4444-oxrls new --package @scope/core:patch --summary "Fix bug"
4545-oxrls new \
4646- --package @scope/core:patch \
4747- --package @scope/react:minor \
4848- --summary "Improve editor behavior"
4949-```
5050-5151-**Options:**
5252-5353-| Option | Description |
5454-| ---------------------------- | -------------------------------- |
5555-| `-p`, `--package <PKG:TYPE>` | Package + bump type (repeatable) |
5656-| `--summary <TEXT>` | Summary of the change |
5757-| `--details <TEXT>` | Optional body text |
5858-5959-**Generated file:**
6060-6161-```markdown
6262----
6363-'@scope/core': patch
6464-'@scope/react': minor
6565----
6666-6767-Improve editor behavior.
6868-```
6969-7070-Files use random adjective-noun names like `calm-blue-fox.md`.
7171-7272----
7373-7474-### `oxrls status`
7575-7676-```bash
7777-oxrls status
7878-```
7979-8080-Shows pending release files, calculated version bumps, and pre-release status.
8181-8282----
8383-8484-### `oxrls bump`
8585-8686-```bash
8787-oxrls bump [--dry-run] [--archive]
8888-```
8989-9090-Consumes all pending release files and applies version bumps:
9191-9292-1. Read and validate all release files
9393-2. Merge bump types (major > minor > patch)
9494-3. Apply fixed/linked group constraints
9595-4. Compute new versions (with pre-release tags if configured)
9696-5. Update `package.json` versions
9797-6. Update internal dependency ranges
9898-7. Generate or update `CHANGELOG.md` files
9999-8. Save release plan for `oxrls release`
100100-9. Consume release files
101101-102102-**Safety**: read everything → validate → compute plan → write files. If anything fails, nothing is written.
103103-104104----
105105-106106-### `oxrls release`
107107-108108-```bash
109109-oxrls release [--dry-run] [--tag <TAG>]
110110-```
111111-112112-Publishes all packages from the last successful `oxrls bump` to npm.
113113-114114-Reads `.oxrls/releaseplan.txt` (a plain text list of package names, one per line, alphabetically sorted).
115115-116116-**Behavior:**
117117-118118-- **Private packages** (`"private": true`) are skipped
119119-- **Version check**: verifies `package.json` version matches the expected version
120120-- **Exists check**: runs `npm view <pkg>@<version> version` first — skips if already published
121121-- **Dist-tag**: `--tag` override → pre-release tag from version → `"latest"`
122122-- **Access**: reads `publishConfig.access` from `package.json` → falls back to `.oxrls/config.json` config
123123-- **Registry**: reads `publishConfig.registry` from `package.json` if set
124124-- After success, the manifest file is removed
125125-126126-```bash
127127-oxrls release --dry-run # preview
128128-oxrls release # publish everything
129129-oxrls release --tag next # override dist-tag for all packages
130130-```
131131-132132----
133133-134134-### `oxrls pre`
135135-136136-```bash
137137-oxrls pre [SUBCOMMAND]
138138-```
139139-140140-**Interactive mode** (no subcommand): select packages from a list, then enter a tag name (defaults to `beta`).
141141-142142-**Subcommands:**
143143-144144-```bash
145145-# Enter pre-release mode
146146-oxrls pre enter beta --package @scope/pkg-c
147147-oxrls pre enter beta --package @scope/pkg-c --package @scope/pkg-d
148148-oxrls pre enter beta --package "@scope/pre-*"
149149-oxrls pre enter rc --package @scope/pkg-c --force # migrate tag
150150-151151-# Exit pre-release mode
152152-oxrls pre exit --package @scope/pkg-c
153153-oxrls pre exit --package "@scope/pre-*"
154154-155155-# Show status
156156-oxrls pre status
157157-```
158158-159159-Package names support:
160160-161161-- Exact names: `@scope/pkg-c`
162162-- Partial names: `pkg-c` resolves to `@scope/pkg-c` by suffix matching
163163-- Globs: `"@scope/pre-*"`
164164-- Negation: `"!@scope/special"` (in config)
165165-166166----
167167-168168-## Release file format
169169-170170-```markdown
171171----
172172-'@scope/pkg-a': patch
173173-'@scope/pkg-b': minor
174174----
175175-176176-Summary of changes.
177177-```
178178-179179-- Frontmatter is required (delimited by `---`)
180180-- Bump types: `patch`, `minor`, `major`
181181-- Body must not be empty
182182-- Unknown packages produce a clear error
183183-184184----
185185-186186-## Version bump rules
187187-188188-| Current | Bump | Result |
189189-| ------- | ----- | ------ |
190190-| 1.2.3 | patch | 1.2.4 |
191191-| 1.2.3 | minor | 1.3.0 |
192192-| 1.2.3 | major | 2.0.0 |
193193-| 0.2.3 | major | 1.0.0 |
194194-| 0.2.3 | minor | 0.3.0 |
195195-| 0.2.3 | patch | 0.2.4 |
196196-197197-Multiple bumps for same package: **major > minor > patch**.
198198-199199----
200200-201201-## Fixed packages
202202-203203-All packages in a fixed group share the same version:
204204-205205-```json
206206-{ "fixed": [["@scope/core", "@scope/utils"]] }
207207-```
208208-209209-If `@scope/core` gets a bump, both packages get the same new version (highest old version + max bump type).
210210-211211----
212212-213213-## Linked packages
214214-215215-All packages in a linked group share the same bump type:
216216-217217-```json
218218-{ "linked": [["@scope/hooks", "@scope/utils"]] }
219219-```
220220-221221-If one gets `minor`, all get `minor`. Each keeps its own version number.
222222-223223----
224224-225225-## Internal dependency updates
226226-227227-oxrls updates dependency ranges in `dependencies`, `devDependencies`, `peerDependencies`, and `optionalDependencies`:
228228-229229-| Original | Updated |
230230-| ------------------ | ------------------ |
231231-| `^1.2.3` | `^1.2.4` |
232232-| `~1.2.3` | `~1.2.4` |
233233-| `1.2.3` | `1.2.4` |
234234-| `workspace:*` | `workspace:*` |
235235-| `workspace:^` | `workspace:^` |
236236-| `workspace:~` | `workspace:~` |
237237-| `workspace:^1.2.3` | `workspace:^1.2.4` |
238238-239239----
240240-241241-## Changelog format
242242-243243-### Per-package (default)
244244-245245-```markdown
246246-# Changelog
247247-248248-## 1.2.4
249249-250250-### Patch Changes
251251-252252-- Fixed editor selection behavior.
253253-```
254254-255255-### Global (opt-in via `generateGlobalChangelog`)
256256-257257-```markdown
258258-# Changelog
259259-260260-## 2026-05-22
261261-262262-### Minor Changes
263263-264264-- **@scope/react** (v1.1.0): Add new feature.
265265-266266-### Patch Changes
267267-268268-- **@scope/core** (v1.2.4): Fix transaction mapping bug.
269269-- **@scope/utils** (v1.2.4): Updated with @scope/core.
270270-```
271271-272272----
273273-274274-## Pre-release mode
275275-276276-Controlled via config or CLI:
277277-278278-```bash
279279-oxrls pre enter beta --package "@scope/experimental-*"
280280-oxrls pre # interactive
281281-```
282282-283283-Version examples:
284284-285285-| Bump | Without pre | With pre (beta) |
286286-| ----- | ----------- | --------------- |
287287-| patch | `1.2.4` | `1.2.4-beta.1` |
288288-| minor | `1.3.0` | `1.3.0-beta.1` |
289289-| major | `2.0.0` | `2.0.0-beta.1` |
290290-291291-Pre-release tag is used as the npm dist-tag during `oxrls release`:
292292-293293-```bash
294294-oxrls release # publishes with --tag beta
295295-oxrls release --tag next # overrides to --tag next
296296-```
297297-298298----
299299-300300-## Exit codes
301301-302302-| Code | Meaning |
303303-| ---- | ------- |
304304-| 0 | Success |
305305-| 1 | Error |