Migrate this repository from Nx orchestration to Isox. Inspect the repository before editing, preserve its working build/test/lint behavior, and implement and verify the migration. Follow repository instructions and preserve unrelated changes. Do not commit, publish, or deploy unless separately requested. Isox’s Nx integration supports Nx 23 only and exists solely for initial migration and evaluation. Once the user decides to keep using Isox, complete the migration to native Isox commands and underlying tools, including replacing Nx executors and config helpers. Retaining the adapter is an intermediate step, not a completed migration. Use the active roadmap to distinguish implemented Isox behavior from planned prerequisite scheduling, remote caching, and isolation features. Use the affected and CI guide to replace Nx affected commands and nx-extend matrix actions with native Isox selection and weighted plans.
1. Inspect the existing behavior
Identify the package manager, lockfile, runtime versions, workspace layout, projects, scripts, CI jobs, and installed Nx/plugin versions. Record a baseline of the relevant checks and any existing failures. Before using the temporary Nx adapter, confirm that the installed Nx runtime is 23.x and retained plugins are compatible with it. Other Nx versions are unsupported; migrate their commands directly to native tools or Isox executors. Inventory each project’s effective targets, including inferred targets, project and package configuration, and workspace defaults. Use the installed Nx CLI’s inspection commands where available; inspect its help for version-specific syntax. Do not assume that copyingproject.json captures all behavior: Nx also
derives project configuration from plugins and nx.json defaults. See
Nx’s project configuration reference.
For every command used locally or in CI, record its actual tool invocation,
options, working directory, environment requirements, configuration variants,
outputs, prerequisites, and failure behavior. Find Nx imports in tool configs,
custom executors, scripts, and application code as well as CLI invocations.
2. Use Isox’s project definition
For gradual migration, Isox can read existing Nx-schemaproject.json files
directly. A recognized Nx $schema preserves targets and triggers in-memory
conversion of implicitDependencies to dependencies. Options and custom
metadata survive; $schema becomes a file URL to the bundled Isox schema in the
converted workspace cache. Source files stay unchanged. Recognized schemas
include local nx/schemas/project-schema.json and legacy
@nrwl/workspace/schemas/project-schema.json paths, the project-configuration
identifier on nx.dev, and the official schema on raw.githubusercontent.com.
No schema is downloaded during discovery.
Migration is selected by $schema, not by field names alone. Files with no
schema or another schema are treated as Isox definitions with optional extra
metadata. A file defining both implicitDependencies and dependencies must be
resolved before automatic conversion. This does not resolve
inferred targets, target defaults, or targets using only shell-command shorthand;
targets without an executor are skipped in memory and in the workspace cache.
Commands still need explicit executor references and effective options.
Use this conversion to test existing executor-based projects before rewriting
their source files. For the final explicit Isox format, follow the steps below.
Install @isox-sh/cli as a workspace development dependency using the repository’s
package manager. The package provides the isox binary; use npx isox,
pnpm exec isox, or yarn isox for a local installation.
Keep the filename project.json. Run isox init at the workspace root to create
isox.json containing the installed CLI’s version from its package.json, for
example { "version": "0.0.1" }. When the root contains an nx.json file, init
also adds "nx": { "executors": ["@nx"] }. Init refuses to overwrite an existing file;
preserve and inspect any existing marker. Isox finds the nearest marker by walking
upward from the current directory. For existing markers, configure nx.executors
explicitly for any retained Nx executor scopes or packages.
Create or convert a project.json in each project’s directory. Isox defines the
following fields and allows additional project and command properties for custom
executors and tools. Additional properties are preserved in the workspace cache
and executor context without giving them built-in scheduling behavior:
@example/cli. Adapt the schema path, scripts, package names,
and commands to the repository. Verify that each referenced script actually
exists. The schema ships with @isox-sh/core; use the installed schema as the
source of truth if migrating against a different Isox version.
- Names must be unique and contain no whitespace or colons. An omitted name
defaults to the containing directory’s name. The project root is derived from
the location of
project.json; do not add arootfield. - Keep
targets. A command requiresexecutorand accepts optionaloptionsplus additional metadata. Executors usepackage:executorreferences; options must be objects. - Convert manual dependencies to explicit Isox project names in
dependencies. Resolve any Nx patterns and exclusions before converting them. Isox also infers relationships from source imports, TypeScript aliases, and local package references. Preserve relationships that cannot be inferred as explicit entries. These edges propagate affected changes and select dependency projects fordependsOn: ["^build"]. Project edges alone do not schedule tasks. - Preserve applicable string
tags. Neither tags nor dependencies enforce module boundaries or schedule commands. - Keep extra fields such as
sourceRoot,projectType, or custom metadata when consumers need them. The Nx adapter passes explicit project metadata through. MigrateimplicitDependenciestodependenciesfor Isox’s own model, and replace Nx$schemareferences with the Isox schema. - Preserve
configurationsas a map of names to option objects and optionaldefaultConfigurationas a name. Isox merges the selected configuration over baseoptionsat the top level; nested objects and arrays are replaced. Use--prodforproduction, or--config=<name>(--configurationand-care aliases). An explicit name takes precedence over--prod, then the command’s default is used. Missing configurations fail. Selecting a configuration does not change the cached target definition. - Configure task prerequisites using the supported
dependsOnsyntax. Verify target names, configurations, and forwarded options. Continuous prerequisites are unsupported. Nx-schema migration removescache,inputs, andnamedInputsin memory; it retains output metadata for the adapter. Do not copy Nx input expressions into native cache declarations. For deterministic native targets, explicitly configurecache: true,inputsand disposable output directories using local task caching. Move compatible workspace target defaults toisox.json.targetDefaults; use object entries by target/executor and migrate Nx-specific input/output semantics.
3. Choose an execution path per command
Use native tools or native Isox executors as the final execution path. Retaining an Nx 23-compatible executor through the adapter is supported only during initial migration; verify it and record the work needed to replace it.Native shell commands
Use@isox-sh/core:run-command to invoke the repository’s underlying tools or
scripts. Its options are:
command: one nonempty shell command string.cwd: optional working directory, relative to the workspace root or absolute.
.env loading, Nx token interpolation, command array,
or parallel execution. Unknown CLI flags override executor options; they are not
appended to the shell command. Configuration selection flags are handled by Isox
itself. Preserve required environment and
tool flags explicitly. Do not translate nx:run-commands by copying its entire
options object.
Preserve dependency build order using the existing package manager or explicit
ordered scripts. For example, pnpm’s --filter package... can include package
dependencies when those relationships exist in package manifests. Isox’s own
dependencies list does not establish pnpm dependencies. Avoid recursion: an
Isox build command that invokes pnpm build must not invoke a script that calls
the same Isox build command again.
Native TypeScript builds
Usejs:tsc from @isox-sh/js for native TypeScript 7 builds. Keep output and
compiler settings in tsconfig; translate Nx outputPath to compilerOptions.outDir
relative to the tsconfig directory (or use an absolute path). Nx’s outputPath is
workspace-relative: for packages/web/tsconfig.build.json, dist/web becomes
../../dist/web so the output location is preserved. Also translate
rootDir to the matching compiler option. Remove executor options such as
Nx main and transformers; unknown native options fail rather than being ignored.
noEmitOnError is always enabled. Emitting configs require a safe workspace-local
output directory. This executor does not schedule dependency builds.
Native asset patterns require a workspace-relative input, a glob, optional
output-relative output, and optional ignore. For uncached targets, cleanup
removes only stale owned, unchanged files and preserves unrelated output. Targets
with cache: true replace declared output directories as a whole, including with
--skip-cache or clean: false; keep source files and manually maintained assets
outside those directories. Define generatePackageJson: true
explicitly when a distributable manifest is required; it defaults to false. A
source package.json is optional, but must include name/version when present.
Without one, generation uses the Isox project name and workspace version (or
0.0.0). Preserve source metadata rather than copying Nx package-generation
options verbatim. generateExportsField and
output-relative additionalEntryPoints can add exports. Existing exports are
validated and preserved. Runtime dependencies are inferred from source imports
and resolved against project, workspace, and local package versions. Computed
module names require explicit dependency metadata. Lockfile generation is not
supported.
For watch mode, run isox build <project> --watch, or add an Isox configuration
containing watch: true and select it with --config=watch. The CLI forwards
--watch as the executor’s watch: true option.
Rebuilds refresh tsconfig, assets, and package metadata; recoverable errors keep
the stream alive. Signal/cancellation closes the watcher and compiler children.
See the JS executor contract for exact defaults,
workspace version handling, cleanup restrictions, and watch sampling limits.
Temporarily retained Nx 23 executors
Install@isox-sh/nx in the workspace to retain Nx executors during migration.
When nx.json exists, isox init adds the adapter to package.json as a dev
dependency matching the CLI version, preserving any existing version. Run the
workspace’s package manager to install dependencies and update the lockfile.
Executor packages matching a scope or package name in isox.json’s nx.executors
array use the Nx adapter. Init includes @nx in that array when the root contains
nx.json, enabling references
such as:
executors manifest, with builders as a fallback. It
maps Isox commands/dependencies to Nx targets/implicitDependencies and supplies
basic root, project, target, verbosity, and project-configuration context. It
passes an optional JSON nx.json through as nxJsonConfiguration without
applying defaults. projectGraph supplies all discovered project nodes and
declared dependency edges. Applications map to app nodes and libraries to lib.
When no project type is explicit, the adapter uses inferred metadata and falls
back to lib. Dependencies must name projects explicitly; missing names cause an error.
When Nx is installed alongside the executor, its graph builder runs in an isolated
process with the daemon disabled, supplying inferred project/import dependencies,
npm externalNodes, and a refreshed Nx file dependency map. This is required for
webpack’s generated package manifests and pruned lockfiles, including helper
dependencies such as tslib. Keep the workspace’s installed Nx runtime and
lockfile while retaining these executors. Nx’s own workspace data cache is
updated separately from .isox, even when Isox’s project cache is reused.
Graph failures stop execution. Without Nx installed, the adapter can only supply
the explicit Isox graph, with no npm nodes.
taskGraph describes only the selected command; the outer Isox runner schedules
dependsOn prerequisites separately. The adapter graph has empty dependency lists and no
computed outputs or output caching. Use projectGraph for project dependency
traversal; a plugin requiring Nx’s full task pipeline needs further migration.
Explicit
extra project and command properties override inferred metadata, including
sourceRoot when present. See the
Nx context reference
when assessing a plugin’s context requirements.
The runner merges the command’s selected configuration before invoking the
adapter and supplies configurationName in the Nx context. Task IDs include the
configuration and task targets carry it as configuration. The graph’s target
options remain the base definition. The adapter does not run Nx orchestration,
infer tasks, import Nx workspace target defaults, validate executor schemas, or apply
schema defaults. Copy required defaults into each command’s options or named
configurations. If a plugin depends on unavailable context or reads
Nx project files itself, replace it with the underlying tool or report the
specific missing capability. Do not claim compatibility from the package name
alone. For nx:*, @nrwl/*, or third-party Nx plugins, add the corresponding
package or scope (for example nx, @nrwl, or @nx-extend/gcp) to nx.executors.
An absent or empty array selects no Nx packages, including @nx/*.
Do not rename a package reference unless the corresponding package is installed
and its behavior has been checked.
During initial migration, keep dependencies and configuration still required by
retained plugins, including Nx 23 peer dependencies and config helpers. Once the
user adopts Isox, replace these integrations and remove the dependencies after
verifying the native replacements.
Custom native executors
Rewrite custom executors to use the exported IsoxExecutor<Options> type.
They receive (options, context) with this native context:
Read merged configuration values from the executor’s
options argument.
context.command retains the base command definition, including its unmerged
options and named configurations; the project and workspace records also
remain unchanged by configuration selection.
Replace Nx context accesses explicitly. Native context has no targetName,
targets, projectsConfigurations, or isVerbose. Use the native project and
command records. Replace imports of Nx execution helpers with actual Isox/tool
behavior rather than keeping an accidental dependency on Nx scheduling.
An executor returns { success: boolean }, a promise of that result, or an async
iterable of such results. Ordinary failed results, empty iterables, missing
results, and exceptions fail the command. Watch executors can yield
{ success, continuous: true }; failed continuous results are recoverable while
the stream continues. Honor context.signal and close resources on cancellation.
Export a CommonJS callable
function or a callable default export. Declare "executors": "./executors.json" in the
package manifest. The command manifest has this shape:
src/executors/<name>/<name>.executor.ts. Native executors
use executors manifests. Nx packages also use executors (or legacy builders)
manifests; nx.executors selects which packages receive the Nx context. Ensure the executor package’s package.json
can be resolved from the workspace root, including under pnpm’s dependency
isolation. Build local executor packages before invoking their compiled files.
4. Update entry points and dependencies
Install@isox-sh/cli through the repository’s package manager and update its existing
lockfile. Core is a CLI dependency; built-in commands use the CLI’s copy when
core cannot be resolved from the workspace. Install @isox-sh/core directly only
for API/type imports, editor schema paths, or an intentional workspace override.
Do not invent an unpublished version
or mix package managers. For a local Isox checkout, bootstrap its compiled CLI
using pnpm bootstrap first. Add executor packages where resolution from
the workspace root works.
Change scripts, documentation, editor tasks, and CI from nx run project:build
to isox build project (or isox run project:build). The syntax is
isox <command> <project>, where the command is an entry under targets.
init, add, run, reset, affected, plan, and run-many are reserved;
use isox run project:reset for
a project command named reset.
Replace nx affected and nx run-many workflows with isox affected and
isox run-many. Use isox plan and the native GitHub Actions to distribute exact
project lists across weighted workers. Follow the affected and CI guide
for Git selection, tags, named configurations, and pre/post stages. Declare
dependsOn so each worker expands required tasks, including unselected projects.
Without explicit prerequisites, stages with cached outputs only order selected
projects by dependency. Workers do not coordinate dependency order or deduplicate
tasks across matrix jobs. For versioning and publishing, assess the native
semver:version and semver:github executors against the existing
release workflow. Preserve required build ordering and coverage; do not silently
skip checks. Report unresolved needs for remote caching, generators beyond the
available project initializers and add hooks, release features beyond the native
plugin, module-boundary rules, watch orchestration, or artifact transfer.
Remove unused Nx scripts, configuration, and dependencies only after checking
remaining imports, retained adapters, and working commands. Do not leave a shell
wrapper around nx run as the final claimed replacement for Nx orchestration.
When no Nx executors remain, remove the entries from nx.executors in
isox.json. If a workflow still requires Nx, label it as an explicit migration
gap and describe its native replacement plan.
5. Validate and report
Add.isox/ to version-control ignores. Isox stores discovered project
configuration in .isox/workspace.json; this is not a task-output cache.
Run isox reset after project-definition, target-default, or ignore-rule changes before using
single-project commands. Affected, planning and run-many commands rewrite fresh
definitions on every invocation. Dependency analysis is separate: affected
selection requests the full graph, cacheable targets request their inputs’ dependency
closure, and the TypeScript executor requests its
dependency closure for alias remapping. Selecting all projects or running an
explicit list does not itself request analysis.
Only those dependency requests check or create .isox/discovery.json. Entries
are reused after configuration, source-metadata and resolution checks. The
per-project sources SHA fingerprints paths, identity, size and timestamps, not
source contents or imports. Any included source edit can invalidate an entry;
the project is reanalyzed as a whole, including test files, while unchanged
projects can reuse their entries. Import edits do not require reset. Neither
cache skips compilation or replaces build-specific package dependency generation.
TypeScript resolution can record ancestor node_modules existence checks outside
the workspace. These are lookup probes, not recursive project discovery. See
cache behavior for scope and invalidation.
isox reset removes the entire .isox directory when an explicit cleanup is
needed. Never edit the cache to substitute for a project-file migration. Check
.gitignore and .isoxignore if migrated projects are not discovered.
Run the migrated build, test, and lint commands needed to match the baseline.
Check at least one invocation from a nested directory, prerequisite build order,
output locations, and failure exit codes. Verify retained Nx executors against
their installed versions; tests of the adapter alone cannot establish plugin
compatibility. Put any new tests inside the package they belong to, and follow
the repository’s code style.
Summarize changed files, the Nx-to-Isox command mapping, checks run and results,
temporarily retained Nx dependencies and their replacement plans, and any
remaining behavior gaps.
Do not report completion for workflows that have not been migrated or verified.