Skip to content

Conversation

@patinthehat
Copy link
Member

@patinthehat patinthehat commented Jan 31, 2026

This pull request introduces a new major release (v3.0.0) of node-ray, focusing on a full transition to ESM-only modules, raising the minimum Node.js version to 20.19, and updating the project's dependencies and tooling. It also updates documentation and configuration files to reflect these changes, and removes all CommonJS-specific code and exports. The ESLint and Prettier configurations are modernized, and project metadata is updated accordingly.

Major breaking changes and ESM transition:

  • Dropped all CommonJS (require) support; package is now ESM-only. All CJS build outputs and export conditions have been removed from package.json, and documentation has been updated to instruct users to use ESM imports only. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]
  • Minimum supported Node.js version is now 20.19, as reflected in documentation and the engines field in package.json. [1] [2] [3] [4] [5]

Tooling and configuration updates:

  • Replaced legacy ESLint configuration (.eslintrc.cjs, .eslintignore) with a new flat config (eslint.config.js), and updated .npmignore accordingly. [1] [2] [3] [4]
  • Updated Prettier configuration to ESM (prettier.config.js), and renamed biome.json to biome.jsonc with updated schema and rules. [1] [2] [3] [4] [5] [6]

Dependency and script upgrades:

  • Upgraded all major development dependencies: ESLint 9, TypeScript ESLint 8, Prettier 3.8, Vite 7, Vitest 4, and TypeScript 5.9. Updated related scripts and lint-staged configuration. [1] [2] F37e4f28L37R37, [3]

Documentation and metadata:

  • Updated README.md, CHANGELOG.md, and docs to clarify ESM-only usage, Node.js requirements, and removed all CommonJS examples. [1] [2] [3] [4] [5] [6] [7] [8]
  • Updated copyright and version metadata in LICENSE and package.json. [1] [2]

These changes are breaking for users relying on CommonJS or older Node.js versions. All new usage must be ESM-based.

Summary by CodeRabbit

  • Breaking Changes

    • ESM-only support now required; Node.js >=20.19 is minimum.
  • New Features

    • Browser standalone CDN variants added.
    • Release bumped to v3.0.0 with upgrade notes.
  • Documentation

    • All examples converted to ES module imports; Requirements section added.
  • Chores

    • Updated tooling/config publishing rules, linting setup, dependencies, and license year.

✏️ Tip: You can customize this high-level summary in your review settings.

@snyk-io
Copy link

snyk-io bot commented Jan 31, 2026

Snyk checks have passed. No issues have been found so far.

Status Scanner Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@coderabbitai
Copy link

coderabbitai bot commented Jan 31, 2026

Warning

Rate limit exceeded

@patinthehat has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 20 minutes and 53 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

Walkthrough

This PR migrates the project to ESM (removes CommonJS exports), introduces a new flat ESLint config, updates tooling and devDependencies, bumps version to 3.0.0, adjusts build scripts, updates docs to require Node >=20.19 and ESM usage, and updates packaging metadata.

Changes

Cohort / File(s) Summary
ESLint config & ignores
/.eslintignore, /.eslintrc.cjs, /eslint.config.js
Removed legacy .eslintrc.cjs and deleted ignore patterns; added new flat eslint.config.js with TypeScript parser, @typescript-eslint plugin, rule overrides, and updated ignore globs.
Package manifest & publishing
/package.json, /.npmignore
Bumped version to 3.0.0, removed CommonJS require exports from the exports map, updated scripts and lint-staged, upgraded devDependencies, raised node engine to >=20.19, and adjusted npmignore entries (add/remove listed config files).
Build & bundling
/scripts/build.js, prettier.config.js
Standardized build outputs to ES modules (removed .cjs build variants); converted prettier.config.js to ESM export default.
Documentation
/README.md, /docs/available-environments.md, /docs/usage.md
Added Node.js >=20.19 and ESM-only requirement; replaced CommonJS examples with ESM imports; clarified ray.config.js as ESM; expanded browser standalone CDN guidance.
Tooling config
/biome.jsonc, /.github/workflows/run-tests.yml
Updated biome schema and reorganized lint/security/style rules; CI matrix node versions bumped to 22 and 24.
Changelog & license
/CHANGELOG.md, /LICENSE
Added v3.0.0 changelog entry with breaking changes; updated copyright year and organization.
Source lint notes
src/PayloadFactory.ts
Removed an ESLint suppression comment (@typescript-eslint/ban-types) — no functional code changes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 I hopped through exports, swapped require for import,
ESM fields shining bright in every file and report.
Configs refreshed, lint rules set anew,
Version three we celebrate — a carrot cake for the crew! 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Upgrade deps 2026 1' is vague and generic, failing to convey the major breaking changes (ESM-only transition, v3.0.0 release, Node.js minimum version bump) that represent the primary intent of this substantial PR. Revise the title to clearly reflect the main breaking change, such as 'Drop CommonJS support and upgrade to v3.0.0 ESM-only release' or 'Migrate to ESM-only and upgrade major dependencies for v3.0.0'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch upgrade-deps-2026-1

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@what-the-diff
Copy link

what-the-diff bot commented Jan 31, 2026

PR Summary

  • Removal of Legacy ESLint Configuration Files - The old ESLint configuration files have been deleted, signaling a shift towards a newer way of managing JavaScript linting rules.
  • Implementation of New ESLint Configuration File - A new ESLint configuration file using modern JavaScript module structure (ES modules) has been introduced, matching the overall transition of the project from traditional CommonJS modules.
  • Package Details and Dependency Updates - The version of the package has been upgraded to 3.0.0 and dependencies have been updated to the latest versions. The project has moved towards a complete ES module structure, as indicated by the absence of any CommonJS paths in the "exports" section.
  • Changelog Modifications - The changelog now includes an entry for the new version, cataloging significant updates like transition to ES modules, along with an enhancement in minimum Node.js version requirement.
  • Prettier Configuration File Rename - Aligning with the overall transition to ES modules, the Prettier configuration file has been renamed while keeping the functionality intact.
  • Reframed Biome Configuration - The biome configuration file has been tweaked, both in terms of the schema and the way the properties are organized.
  • Dependency-related Script Changes - Modifications have been made to scripts related to Prettier and ESLint to ensure they continue working smoothly with the updated project structure.
  • Documentation Updates - The project documentation now states clearly that the project works exclusively with ES modules and requires Node.js version 20.19 or higher.
  • Removal of CommonJS Build Configurations - All build configurations related to CommonJS have been removed from the build setup, aligning the process with the shift to pure ES modules.
  • Minor Code Refactoring/Cleanup - Some additional changes have been made to source code, like removal of comments and modification of formatting in PayloadFactory.ts.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
scripts/build.js (1)

123-123: ⚠️ Potential issue | 🟡 Minor

Build target is inconsistent with Node.js version requirement.

The build target is set to node18, but the PR states Node.js >= 20.19 is required for v3.0.0. Consider updating the target to node20 to align with the minimum supported version and enable newer Node.js features in the build output.

🔧 Proposed fix
-                target: config.target === 'browser' ? 'chrome70' : 'node18',
+                target: config.target === 'browser' ? 'chrome70' : 'node20',
🤖 Fix all issues with AI agents
In @.npmignore:
- Line 14: Remove the obsolete ignore entries from .npmignore: delete the lines
containing ".eslintrc.js" and "biome.json" (these were left over after moving to
eslint.config.js and renaming biome.json to biome.jsonc) so the .npmignore only
contains current, relevant ignore patterns; verify no other stale config
filenames remain in the file.

In `@docs/available-environments.md`:
- Around line 5-8: The top-level heading "Requirements:" is currently H1 and
should be H2 to satisfy markdownlint; update the markdown heading for the
"Requirements:" section from a single '#' to '##' (i.e., change the heading
level for the "Requirements:" line), then verify the heading hierarchy in
docs/available-environments.md so markdownlint no longer flags H1→H2 issues.

In `@eslint.config.js`:
- Line 50: Remove the deprecated rule entry '@typescript-eslint/no-var-requires'
from the ESLint configuration (in eslint.config.js) because typescript-eslint v8
removed that rule; locate the object or rules block where
'@typescript-eslint/no-var-requires': 'off' is defined and delete that key/value
pair so the config no longer references the nonexistent rule.

In `@package.json`:
- Around line 46-48: Update the package.json scripts "fmt", "lint", and
"lint:fix" to remove the explicit "./node_modules/.bin/" prefixes and replace
single quotes around glob patterns with double quotes for cross-platform
compatibility; specifically edit the "fmt" script (symbol "fmt") to call
prettier directly and use double-quoted globs, and update "lint" and "lint:fix"
(symbols "lint" and "lint:fix") to call eslint without the path prefix and use
double-quoted patterns so Windows cmd.exe and npm-installed binaries work
correctly.
- Around line 59-67: The lint-staged entries currently call binaries with
explicit paths like "./node_modules/.bin/prettier --write" and
"./node_modules/.bin/eslint --fix"; update the lint-staged config to use bare
command names instead (e.g., "prettier --write" and "eslint --fix") so
lint-staged resolves local binaries automatically and improves cross-platform
compatibility—apply this change to the arrays that target all files,
"*.{json,css,scss,gql}", and "*.{yaml,yml}" to replace any
"./node_modules/.bin/..." invocations with the corresponding "prettier" or
"eslint" commands.

In `@README.md`:
- Around line 52-57: Remove the trailing space at the end of the blockquote
line(s) that reference permafrost-dev/react-ray and permafrost-dev/vue-ray (the
lines beginning with ">" in the README blockquote) so the blockquote does not
have trailing whitespace; edit the two blockquote lines to end immediately after
the URL text with no extra space.

@@ -12,19 +12,19 @@
/coverage
.editorconfig
.eslintrc.js
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick | 🔵 Trivial

Consider removing obsolete ignore entries.

Since .eslintrc.cjs was removed in favor of eslint.config.js and biome.json was renamed to biome.jsonc, the ignore entries for .eslintrc.js (line 14) and biome.json (line 28) are now obsolete. While harmless, removing them would keep the file tidy.

Also applies to: 28-28

🤖 Prompt for AI Agents
In @.npmignore at line 14, Remove the obsolete ignore entries from .npmignore:
delete the lines containing ".eslintrc.js" and "biome.json" (these were left
over after moving to eslint.config.js and renaming biome.json to biome.jsonc) so
the .npmignore only contains current, relevant ignore patterns; verify no other
stale config filenames remain in the file.

Comment on lines +5 to +8
Requirements:
- Node.js >= 20.19
- ESM-only (CommonJS `require` is not supported)

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix heading level to satisfy markdownlint (H1 → H2).

📝 Suggested diff
-Requirements:
-- Node.js >= 20.19
-- ESM-only (CommonJS `require` is not supported)
+## Requirements
+- Node.js >= 20.19
+- ESM-only (CommonJS `require` is not supported)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Requirements:
- Node.js >= 20.19
- ESM-only (CommonJS `require` is not supported)
## Requirements
- Node.js >= 20.19
- ESM-only (CommonJS `require` is not supported)
🧰 Tools
🪛 markdownlint-cli2 (0.20.0)

[warning] 7-7: Heading levels should only increment by one level at a time
Expected: h2; Actual: h3

(MD001, heading-increment)

🤖 Prompt for AI Agents
In `@docs/available-environments.md` around lines 5 - 8, The top-level heading
"Requirements:" is currently H1 and should be H2 to satisfy markdownlint; update
the markdown heading for the "Requirements:" section from a single '#' to '##'
(i.e., change the heading level for the "Requirements:" line), then verify the
heading hierarchy in docs/available-environments.md so markdownlint no longer
flags H1→H2 issues.

'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-explicit-any': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-var-requires': 'off',
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

typescript-eslint v8 breaking changes no-var-requires removal

💡 Result:

In typescript-eslint v8 (released July 31, 2024), @typescript-eslint/no-var-requires was deprecated and removed from the preset configs (e.g. plugin:@typescript-eslint/recommended``), in favor of @typescript-eslint/no-require-imports. If you had `no-var-requires` enabled manually, the v8 migration is to remove it and enable `no-require-imports` instead. [1]

What changed (practically)

  • no-var-requires only banned assignments like const x = require('x'), while allowing import x = require('x') and require('x') calls. [2]
  • no-require-imports bans invoking require() (including const x = require('x') and import x = require('x') by default). It’s enabled by plugin:@typescript-eslint/recommended``. [3]

Migration snippet

// before (v7/v8 but now deprecated)
rules: {
  '@typescript-eslint/no-var-requires': 'error',
}

// after (v8+)
rules: {
  '@typescript-eslint/no-require-imports': 'error',
}

If you still rely on import x = require('x'), use:

rules: {
  '@typescript-eslint/no-require-imports': ['error', { allowAsImport: true }],
}

[3]

Sources: typescript-eslint v8 announcement (breaking changes + config diffs) [1], no-var-requires rule docs [2], no-require-imports rule docs [3].


🏁 Script executed:

# Check eslint.config.js file
cat -n eslint.config.js | head -60

Repository: permafrost-dev/node-ray

Length of output: 2202


🏁 Script executed:

# Check package.json for typescript-eslint version
cat package.json | grep -A 5 -B 5 "typescript-eslint"

Repository: permafrost-dev/node-ray

Length of output: 482


Remove deprecated TypeScript ESLint rule.

The @typescript-eslint/no-var-requires rule was removed in typescript-eslint v8. Since your project is already on v8.54.0, this configuration has no effect and should be removed.

Proposed fix
             '@typescript-eslint/explicit-module-boundary-types': 'off',
-            '@typescript-eslint/no-var-requires': 'off',
             '@typescript-eslint/no-empty-function': 'off',
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
'@typescript-eslint/no-var-requires': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-empty-function': 'off',
🤖 Prompt for AI Agents
In `@eslint.config.js` at line 50, Remove the deprecated rule entry
'@typescript-eslint/no-var-requires' from the ESLint configuration (in
eslint.config.js) because typescript-eslint v8 removed that rule; locate the
object or rules block where '@typescript-eslint/no-var-requires': 'off' is
defined and delete that key/value pair so the config no longer references the
nonexistent rule.

Comment on lines +46 to +48
"fmt": "./node_modules/.bin/prettier --write 'src/**/*.{js,ts,json}' 'tests/**/*.{js,ts,json}' './*.js'",
"lint": "./node_modules/.bin/eslint src tests scripts",
"lint:fix": "./node_modules/.bin/eslint src tests scripts --fix",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

cat package.json

Repository: permafrost-dev/node-ray

Length of output: 3379


🌐 Web query:

npm script PATH injection node_modules .bin Windows shell compatibility

💡 Result:

What “PATH injection” means for npm run

When you run an npm script, npm prepends your project’s node_modules/.bin to the PATH for that script process. This is why you can write webpack (not ./node_modules/.bin/webpack) in package.json scripts. This PATH modification is explicit npm behavior. [1][2]

Security/behavior implication: any executable name you invoke in an npm script is resolved against node_modules/.bin first, so a dependency (or compromised dependency) can effectively “shadow” a system command with the same name (by providing a bin/shim in .bin). That’s often desired for tooling, but it’s also the core of the “PATH injection” concern. [1][2]

Why Windows behaves differently (shell compatibility)

npm runs scripts in a platform-dependent shell:

  • POSIX: typically /bin/sh
  • Windows: cmd.exe by default [1]

So scripts that rely on POSIX shell features (e.g., VAR=1 cmd, $(...), single-quote rules, export, etc.) often break on Windows unless you adapt them.

You can change the shell npm uses via the script-shell config (e.g., PowerShell on Windows) if you need different shell semantics. [1]

Practical ways to make scripts cross-platform

  • Avoid shell-specific syntax in package.json scripts when possible; prefer Node-based CLIs and flags.
  • Use cross-env for portable environment variable setting in scripts. [3]
  • If you’re spawning processes from Node and need Windows reliability (PATHEXT, shebangs, .cmd shims in node_modules/.bin, quoting), use cross-spawn rather than raw child_process.spawn in many cases. [4]

Sources

[1] npm Docs: npm run-script (PATH includes node_modules/.bin; default shell; script-shell) (docs.npmjs.com)
[2] npm Docs: “scripts” (executables exported to PATH) (docs.npmjs.com)
[3] cross-env (portable env vars; notes about shell usage) (npmjs.com)
[4] cross-spawn (Windows spawning + .bin shim/quoting/shebang issues) (npmjs.com)

Citations:


Remove explicit node_modules/.bin paths and fix quoting for cross-platform compatibility.

npm automatically injects node_modules/.bin into the script's PATH, so explicit paths are unnecessary. Additionally, single quotes do not prevent glob expansion in Windows cmd.exe; use double quotes instead to ensure glob patterns are passed correctly to prettier and eslint.

🔧 Suggested diff
-        "fmt": "./node_modules/.bin/prettier --write 'src/**/*.{js,ts,json}' 'tests/**/*.{js,ts,json}' './*.js'",
-        "lint": "./node_modules/.bin/eslint src tests scripts",
-        "lint:fix": "./node_modules/.bin/eslint src tests scripts --fix",
+        "fmt": "prettier --write \"src/**/*.{js,ts,json}\" \"tests/**/*.{js,ts,json}\" \"*.js\"",
+        "lint": "eslint src tests scripts",
+        "lint:fix": "eslint src tests scripts --fix",
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"fmt": "./node_modules/.bin/prettier --write 'src/**/*.{js,ts,json}' 'tests/**/*.{js,ts,json}' './*.js'",
"lint": "./node_modules/.bin/eslint src tests scripts",
"lint:fix": "./node_modules/.bin/eslint src tests scripts --fix",
"fmt": "prettier --write \"src/**/*.{js,ts,json}\" \"tests/**/*.{js,ts,json}\" \"*.js\"",
"lint": "eslint src tests scripts",
"lint:fix": "eslint src tests scripts --fix",
🤖 Prompt for AI Agents
In `@package.json` around lines 46 - 48, Update the package.json scripts "fmt",
"lint", and "lint:fix" to remove the explicit "./node_modules/.bin/" prefixes
and replace single quotes around glob patterns with double quotes for
cross-platform compatibility; specifically edit the "fmt" script (symbol "fmt")
to call prettier directly and use double-quoted globs, and update "lint" and
"lint:fix" (symbols "lint" and "lint:fix") to call eslint without the path
prefix and use double-quoted patterns so Windows cmd.exe and npm-installed
binaries work correctly.

Comment on lines +59 to 67
"./node_modules/.bin/prettier --write",
"./node_modules/.bin/eslint --fix"
],
"*.{json,css,scss,gql}": [
"./node_modules/.bin/prettier --config prettier.config.cjs --write"
"./node_modules/.bin/prettier --write"
],
"*.{yaml,yml}": [
"./node_modules/.bin/prettier --config prettier.config.cjs --tab-width 2 --write"
"./node_modules/.bin/prettier --write"
]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, check if the package.json exists and contains the mentioned paths
if [ -f "package.json" ]; then
  echo "=== Checking package.json for lint-staged configuration ==="
  sed -n '50,75p' package.json
else
  echo "package.json not found at root"
fi

Repository: permafrost-dev/node-ray

Length of output: 1194


🌐 Web query:

lint-staged PATH environment variable Windows compatibility documentation

💡 Result:

  • How lint-staged finds commands: it can run any executable that’s installed locally/globally via npm or available on your $PATH. It resolves locally installed binaries (from node_modules/.bin) via its spawn helper (documented as nano-spawn in the repo README, and as execa on npm). [1][2]

  • Environment-variable expansion (important on Windows too): task strings do not expand environment variables like a normal shell would (e.g., %FOO% / $FOO). If you need that behavior, the docs recommend using cross-env. [1]

  • Windows-specific constraint you may hit: Windows has a relatively small maximum command-line length (documented in lint-staged as 8192 characters), so lint-staged may need to split long file lists; the maxArgLength option exists for this. [1]

  • If you’re debugging “command not found” on Windows: it usually means the Git hook process (often via Husky / a GUI Git client) is running with a different PATH than your interactive terminal. In that case, you typically need to ensure the hook sets/augments PATH before running lint-staged (this is commonly reported with GUI Git integrations). [3]

Sources:
[1] lint-staged README (GitHub)
[2] lint-staged package docs (npm)
[3] Community report on hooks/GUI environments losing PATH (Zenn article)


🌐 Web query:

lint-staged bin paths node_modules .bin usage best practices

💡 Result:

Best practices for lint-staged + node_modules/.bin (bin paths)

  • Don’t hardcode ./node_modules/.bin/... in lint-staged commands. Configure tasks using the bare executable name (e.g. eslint, prettier). lint-staged will resolve locally installed binaries for you, and it explicitly discourages relying on globally installed tools. [1]
    Example:

    {
      "*.js": ["eslint --fix", "prettier --write"]
    }
  • Prefer package-manager execution contexts over “manual PATH” tweaks.

    • npm run automatically adds node_modules/.bin to PATH for scripts, so eslint, prettier, etc. work without prefixes. [2]
    • With pnpm, use pnpm exec <cmd> (or pnpm <cmd> when not conflicting) which also adds node_modules/.bin to PATH. [3]
  • Avoid referencing node_modules directly in day-to-day usage. Use an npm/pnpm script (or the package manager’s exec) instead of calling ./node_modules/.bin/<tool> directly—this is a common maintainability guideline for teams and CI. [2] [4]

Practical rule of thumb

  • Inside lint-staged config: use bare commands (eslint, prettier, stylelint, etc.). [1]
  • Inside package.json scripts / CI: use npm run <script> / pnpm run <script> (or pnpm exec <tool> for ad-hoc runs). [2] [3]

Sources: lint-staged docs [1], npm docs [2], pnpm docs [3], general JS tooling guidance [4].

[1] (github.com)
[2] (docs.npmjs.com)
[3] (pnpm.io)
[4] (julie.io)

Citations:


Use bare command names in lint-staged instead of hard-coded bin paths.

lint-staged automatically resolves locally installed binaries—explicitly using ./node_modules/.bin/* is unnecessary and discouraged. The recommended approach is to use bare command names like eslint and prettier, which also improves cross-platform compatibility.

🔧 Suggested diff
-            "./node_modules/.bin/prettier --write",
-            "./node_modules/.bin/eslint --fix"
+            "prettier --write",
+            "eslint --fix"
@@
-            "./node_modules/.bin/prettier --write"
+            "prettier --write"
@@
-            "./node_modules/.bin/prettier --write"
+            "prettier --write"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"./node_modules/.bin/prettier --write",
"./node_modules/.bin/eslint --fix"
],
"*.{json,css,scss,gql}": [
"./node_modules/.bin/prettier --config prettier.config.cjs --write"
"./node_modules/.bin/prettier --write"
],
"*.{yaml,yml}": [
"./node_modules/.bin/prettier --config prettier.config.cjs --tab-width 2 --write"
"./node_modules/.bin/prettier --write"
]
"prettier --write",
"eslint --fix"
],
"*.{json,css,scss,gql}": [
"prettier --write"
],
"*.{yaml,yml}": [
"prettier --write"
]
🤖 Prompt for AI Agents
In `@package.json` around lines 59 - 67, The lint-staged entries currently call
binaries with explicit paths like "./node_modules/.bin/prettier --write" and
"./node_modules/.bin/eslint --fix"; update the lint-staged config to use bare
command names instead (e.g., "prettier --write" and "eslint --fix") so
lint-staged resolves local binaries automatically and improves cross-platform
compatibility—apply this change to the arrays that target all files,
"*.{json,css,scss,gql}", and "*.{yaml,yml}" to replace any
"./node_modules/.bin/..." invocations with the corresponding "prettier" or
"eslint" commands.

Comment on lines +52 to 57
`node-ray` offers several options to allow you to use it in either NodeJS, Web-based TypeScript or JavaScript projects, and browser environments.

>If you're using NextJs/React, take a look at [permafrost-dev/react-ray](https://github.com/permafrost-dev/react-ray).
>
>If you're using Vue, check out [permafrost-dev/vue-ray](https://github.com/permafrost-dev/vue-ray).
> If you're using NextJs/React, take a look at [permafrost-dev/react-ray](https://github.com/permafrost-dev/react-ray).
>
> If you're using Vue, check out [permafrost-dev/vue-ray](https://github.com/permafrost-dev/vue-ray).

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Remove trailing space in the blockquote to satisfy markdownlint.

📝 Suggested diff
-> 
+>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
`node-ray` offers several options to allow you to use it in either NodeJS, Web-based TypeScript or JavaScript projects, and browser environments.
>If you're using NextJs/React, take a look at [permafrost-dev/react-ray](https://github.com/permafrost-dev/react-ray).
>
>If you're using Vue, check out [permafrost-dev/vue-ray](https://github.com/permafrost-dev/vue-ray).
> If you're using NextJs/React, take a look at [permafrost-dev/react-ray](https://github.com/permafrost-dev/react-ray).
>
> If you're using Vue, check out [permafrost-dev/vue-ray](https://github.com/permafrost-dev/vue-ray).
`node-ray` offers several options to allow you to use it in either NodeJS, Web-based TypeScript or JavaScript projects, and browser environments.
> If you're using NextJs/React, take a look at [permafrost-dev/react-ray](https://github.com/permafrost-dev/react-ray).
>
> If you're using Vue, check out [permafrost-dev/vue-ray](https://github.com/permafrost-dev/vue-ray).
🧰 Tools
🪛 markdownlint-cli2 (0.20.0)

[warning] 55-55: Trailing spaces
Expected: 0 or 2; Actual: 1

(MD009, no-trailing-spaces)

🤖 Prompt for AI Agents
In `@README.md` around lines 52 - 57, Remove the trailing space at the end of the
blockquote line(s) that reference permafrost-dev/react-ray and
permafrost-dev/vue-ray (the lines beginning with ">" in the README blockquote)
so the blockquote does not have trailing whitespace; edit the two blockquote
lines to end immediately after the URL text with no extra space.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/run-tests.yml (1)

13-32: ⚠️ Potential issue | 🔴 Critical

Matrix variable node-version is defined but never used.

The workflow defines a node-version matrix with values [22, 24], but no step actually sets up Node.js using this variable. All steps use Bun directly, so the tests run under Bun's bundled Node version rather than the specified matrix versions. This means CI is not actually validating compatibility with Node 22 and 24 as intended.

Additionally, the minimum supported Node.js version (20.19 per the PR objectives) is not included in the test matrix.

🔧 Proposed fix: Add setup-node step and include minimum version
     strategy:
       fail-fast: true
       matrix:
-        node-version: [22, 24]
+        node-version: [20, 22, 24]

     steps:
     - name: Checkout repository
       uses: actions/checkout@v4
       with:
         fetch-depth: 1

+    - name: Setup Node.js
+      uses: actions/setup-node@v4
+      with:
+        node-version: ${{ matrix.node-version }}
+
     - uses: oven-sh/setup-bun@v2
       with:
         bun-version: latest

Alternatively, if Bun is intentionally used as the sole runtime and Node.js version testing is not required, remove the unused matrix to avoid confusion:

♻️ Alternative: Remove unused matrix
   tests:
-
     runs-on: ubuntu-latest
-    strategy:
-      fail-fast: true
-      matrix:
-        node-version: [22, 24]

     steps:

@patinthehat patinthehat merged commit c6cbf7c into main Jan 31, 2026
4 of 7 checks passed
@patinthehat patinthehat deleted the upgrade-deps-2026-1 branch January 31, 2026 07:23
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