Compatibility

Run MarginCI with Node.js 24.21.0 on macOS (Apple silicon) or Ubuntu 24.04 (x64). Use the exact configurations below. Install MarginCI separately from the application as described in Getting started.

Release validation configurations

Use Node.js 24.21.0 and a toolchain covered by your delivered package’s acceptance record:

Environment OS and architecture Node.js npm pnpm application
Hosted GitHub Actions Ubuntu 24.04 x64 24.21.0 11.6.2 12.3.4
Hosted GitHub Actions macOS 26 arm64 24.21.0 11.6.2 12.3.4
Local machine macOS arm64, Darwin 27.0.0 24.21.0 11.7.0 12.3.4

Check that the acceptance record matches your archive’s SHA-256 and platform. Results from another archive or an emulated environment do not establish support for your delivery.

Check node --version and npm --version before installation. Node and actions/setup-node supply a bundled npm version, which may differ from the versions above. Other npm versions are not qualified by those results.

For supported API calls and live-testing limits, see provider testing. Configure and verify your repository’s CI policies as described in GitHub Actions.

Node.js 24.21.0 is required by the package and enforced before workload execution. Other Node.js versions are rejected, including other Node 24 patches. Other Linux distributions and architectures are unsupported. Windows is unsupported.

Repository and dependencies

Component Requirement
Git Application repository with a baseline commit available locally
npm One root package; package-lock.json v2/v3 with integrity-pinned HTTPS registry dependencies
pnpm Exact repository pin already on PATH; tested pin 12.3.4, lockfile v9 and one root importer
JavaScript Direct Node.js entry point or a resolved npm/pnpm script
TypeScript Local .ts/.mts/.cts, ESM or CommonJS, supported self-contained tsconfig; relative .js-to-.ts and extensionless imports
Network calls Global fetch and tested node:http/node:https paths; only the listed provider endpoints

MarginCI installs each revision’s dependencies separately from its frozen lockfile, with lifecycle scripts disabled. Dependencies that require install-time build scripts are unsupported. npm and pnpm installation timeouts are 120 and 300 seconds respectively. pnpm must already be available at the repository’s exact pin; MarginCI does not download or switch package managers. Other pnpm pins can be attempted but are unverified.

Bun, Yarn, workspaces, local/file/link/git dependencies and npm v1 locks are unsupported. Source symlinks, submodules, Git export transformations, external loaders, NODE_PATH and existing NODE_OPTIONS are rejected. If the CLI itself was installed through pnpm, invoke node ./node_modules/marginci/dist/cli.js: pnpm’s bin shim sets NODE_PATH. The separate npm installation in the quickstart avoids this issue.

TypeScript is transpiled inside the operation’s process without writing build files. Run typechecking separately. tsx, external tsconfig inheritance, project references, aliases, plugins and TypeScript dependencies are unsupported. Committed built JavaScript is an alternative.

Lockfile metadata

Every registry entry needs resolved (an HTTPS registry identity) and integrity. MarginCI identifies the first incomplete dependency path and missing fields without printing registry URLs or values.

A normal npm install --package-lock-only --ignore-scripts refresh may leave metadata incomplete. Review dependency identity through your normal workflow, regenerate a complete integrity-pinned lock, review the dependency graph and commit it. MarginCI does not fill in metadata, substitute dependencies or rewrite the graph.

Process and state requirements

MarginCI starts a separate Node.js process for each attempt. The operation must perform its paid calls in that process, consume the required responses and await completion before exiting. A retry starts a new process. Arbitrary child processes, worker threads, queues, browser/CDP traffic and remote background work are unsupported. Firecrawl batch scraping is supported only through the completion tracking described in the provider guide.

HTTP/2, WebSockets, native/custom networking, webhooks and unlisted provider endpoints are unsupported. MarginCI cannot measure paid work hidden behind another service.

Reset local state between test cases and arrange comparable external state. Files changed inside a revision’s snapshot persist between its cases. MarginCI isolates source and dependencies for measurement; it is not a sandbox for untrusted code. See Security and data handling.

Committed JavaScript for incompatible imports

Successful doctor checks establish repository/configuration prerequisites; they do not establish that every application import can execute. For example, a TypeScript application importing JSON without Node’s required import attributes can pass doctor and then fail with ERR_IMPORT_ATTRIBUTE_MISSING. MarginCI’s synchronous TypeScript loader does not repair application import semantics.

If direct execution is incompatible, use the supported committed-JavaScript approach. Run the application’s normal build outside measurement, preserving its normal bundling and module settings and required assets (for example, a tokenizer’s WASM file). Include the full build and its required assets; a partial bundle with externalized packages may still fail. Keep the wrapper calling the real application through its existing provider route.

Commit the generated JavaScript and assets with the source in each measured Git revision. Each baseline and candidate must own its respective build; never overlay the candidate build onto the baseline. In the normal review/CI workflow, rebuild with the application’s locked dependencies and check that generated output matches source, for example git diff --exit-code -- path/to/built-engine.js path/to/required-assets/. Ensure required output is tracked, not ignored. Run application tests and typechecking separately. Keep application implementation/build output outside comparison_files; only the frozen wrapper, success helpers and workload belong there. The measured command executes the committed build without build orchestration or loader changes.