Skip to content

cli: Decouple Node.js from the Anchor CLI#4388

Open
plind-junior wants to merge 4 commits into
otter-sec:masterfrom
plind-junior:fix/decouple-nodejs-cli
Open

cli: Decouple Node.js from the Anchor CLI#4388
plind-junior wants to merge 4 commits into
otter-sec:masterfrom
plind-junior:fix/decouple-nodejs-cli

Conversation

@plind-junior
Copy link
Copy Markdown

@plind-junior plind-junior commented Apr 6, 2026

Summary

Addresses #4279 — Remove Node.js as a hard dependency from the Anchor CLI default workflow.

Audit Results

The CLI currently depends on Node.js in 9 integration points:

Area File Purpose
npm config cli/src/lib.rs:1120-1132 Get default license for package.json during anchor init
npx program-metadata cli/src/metadata.rs:43-54 IDL write/fetch/close via @solana-program/program-metadata
npx skills cli/src/lib.rs:1506-1518 Install Solana dev skills (--install-agent-skills)
node shell cli/src/lib.rs:4568-4572 anchor shell — interactive JS REPL
node deploy cli/src/lib.rs:4298-4303 Execute deploy.js/deploy.ts scripts
node version check cli/src/lib.rs:4883-4893 DNS option for Node >=16.4
Package manager install cli/src/lib.rs:1533-1549 npm/yarn/pnpm install during anchor init
Test runners cli/src/rust_template.rs:662-690 Jest/Mocha test script generation
package.json generation cli/src/rust_template.rs:400-485 JS/TS project scaffolding

Implementation Plan

Phase 1 — Remove unnecessary Node.js calls

  • Replace npm config get init-license with a hardcoded default ("ISC") — no reason to shell out to npm for a license string
  • Gate Node version check / DNS option — only needed when running JS tests, skip for Rust test workflows

Phase 2 — Gate JS features behind runtime checks

  • anchor init: Skip package.json, node_modules, and JS test scaffolding when Rust test framework is selected
  • anchor shell: Check for Node.js at invocation time, clear error if missing
  • Deploy scripts: Same — check at invocation, clear error if missing

Phase 3 — Out of scope (depends on other issues)

Test plan

  • anchor init with Rust test framework creates a working project without Node.js installed
  • anchor init with JS/TS test framework still works as before
  • anchor test with Rust tests works without Node.js
  • anchor shell prints a clear error when Node.js is not installed
  • Existing JS/TS workflows remain unbroken

Relates to #4278 (LiteSVM) and #4288 (IDL Generation)

@vercel
Copy link
Copy Markdown

vercel Bot commented Apr 6, 2026

@plind-dm is attempting to deploy a commit to the Solana Foundation Team on Vercel.

A member of the Team first needs to authorize it.

The `get_npm_init_license()` function shells out to `npm config get
init-license` during `anchor init` just to retrieve a license string
for the generated package.json. This creates an unnecessary hard
dependency on npm being installed even when the user may not need it.

Replace with a hardcoded "ISC" default, which is what npm itself
defaults to. This removes one Node.js touchpoint from the init path.

Partial fix for solana-foundation#4279
`get_node_dns_option()` calls `node --version` to determine DNS
options for every test run, including `cargo test` and `cargo test-sbf`
where Node.js is not involved at all. This causes Rust-only workflows
to fail if Node.js is not installed.

Detect whether the test script is Rust-based (starts with "cargo test")
and skip the Node.js version check and NODE_OPTIONS setup entirely
in that case.

Partial fix for solana-foundation#4279
When using Rust-based test templates (litesvm, mollusk, rust), there
is no need to generate package.json, tsconfig.json, .prettierignore,
deploy scripts, or run npm/yarn install. These are only relevant for
JS/TS test workflows (mocha, jest).

Add `TestTemplate::is_rust_based()` helper and use it to conditionally
skip all Node.js-related scaffolding during project initialization.
This allows `anchor init` with default settings (litesvm) to succeed
without Node.js installed.

Partial fix for solana-foundation#4279
`anchor shell` and `anchor migrate` both require Node.js but would
previously fail with an opaque spawn error if node was not installed.

Add an `ensure_node_installed()` check that runs `node --version` and
returns a clear error message pointing to nodejs.org when Node.js is
not found. Call it at the start of both commands so users get actionable
feedback instead of a raw OS error.

Partial fix for otter-sec#4279
@plind-junior plind-junior force-pushed the fix/decouple-nodejs-cli branch from aa7f2ac to 3289878 Compare April 6, 2026 16:50
@plind-junior plind-junior marked this pull request as ready for review April 6, 2026 17:00
@plind-junior plind-junior reopened this Apr 10, 2026
@plind-junior
Copy link
Copy Markdown
Author

@jamie-osec If this feature is already merged, do not close this one but just change it to draft status.
I will close it myself

@jamie-osec
Copy link
Copy Markdown
Collaborator

You can change it to draft status yourself if you wish but we will close any redundant PRs

@plind-junior
Copy link
Copy Markdown
Author

plind-junior commented Apr 13, 2026

@jamie-osec I don't have the authority to mark it as a draft. Feel free to close it if it's redundant.

@jamie-osec
Copy link
Copy Markdown
Collaborator

jamie-osec commented Apr 13, 2026

image

PR authors should always be able to change status with this button

@jamie-osec jamie-osec marked this pull request as draft April 13, 2026 10:17
@jamie-osec
Copy link
Copy Markdown
Collaborator

Is this ready for review or not?

@plind-junior plind-junior marked this pull request as ready for review April 23, 2026 19:48
@plind-junior
Copy link
Copy Markdown
Author

It's fully ready for review

@plind-junior plind-junior force-pushed the fix/decouple-nodejs-cli branch from 3e3ed94 to 3289878 Compare April 23, 2026 20:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants