Skip to content

[Bug] tree-sitter@0.25.0 fails to build with Node.js 24 - C++20 required but not set #7

@nicolas-despres

Description

@nicolas-despres

Description

The native module compilation fails when installing dependencies with Node.js 24.x. The tree-sitter@0.25.0 package fails to build because Node.js 24 requires C++20 (as per the v8 headers), but the tree-sitter binding.gyp configuration doesn't specify this standard, causing the build to default to an older C++ version.

Steps to Reproduce

  1. Use Node.js 24.x (e.g., node --version shows v24.14.0)
  2. Run pnpm install in the AgentScript monorepo
  3. Observe the native module compilation failure during tree-sitter installation

Expected Behavior

The tree-sitter native module should compile successfully and pnpm install should complete without errors.

Actual Behavior

The compilation fails with C++20-specific errors:

/Users/.../include/node/v8config.h:13:2: error: "C++20 or later required."
   13 | #error "C++20 or later required."

Additional compilation errors include:

  • error: unknown type name 'concept'
  • error: use of undeclared identifier 'requires'
  • error: no member named 'ranges' in namespace 'std'
  • error: no type named 'contiguous_iterator_tag' in namespace 'std'

Environment

  • Node.js version: v24.14.0
  • pnpm version: 10.28.0
  • OS: macOS 26.4.1 (Darwin 25.4.0)
  • Package & version: tree-sitter@0.25.0 (transitive dependency)
  • Browser (if applicable): N/A

Additional details:

  • Architecture: arm64 (Apple Silicon)
  • Compiler: Apple clang version 21.0.0
  • node-gyp version: 11.5.0

Minimal Reproduction

This issue occurs during standard installation:

# With Node.js 24.x active
pnpm install

The error appears specifically when tree-sitter@0.25.0 attempts to compile its native bindings.

Additional Context

Full error log
gyp info using node-gyp@11.5.0
gyp info using node@24.14.0 | darwin | arm64
  CXX(target) Release/obj.target/tree_sitter_runtime_binding/src/binding.o
In file included from ../src/binding.cc:3:
In file included from ../src/./language.h:7:
In file included from .../include/node/node_object_wrap.h:25:
In file included from .../include/node/v8.h:23:
In file included from .../include/node/cppgc/common.h:8:
.../include/node/v8config.h:13:2: error: "C++20 or later required."
   13 | #error "C++20 or later required."
      |  ^
In file included from ../src/binding.cc:3:
In file included from ../src/./language.h:7:
In file included from .../include/node/node_object_wrap.h:25:
In file included from .../include/node/v8.h:24:
In file included from .../include/node/v8-array-buffer.h:12:
In file included from .../include/node/v8-local-handle.h:13:
In file included from .../include/node/v8-handle-base.h:8:
.../include/node/v8-internal.h:1256:37: error: a non-type template parameter cannot have type 'ExternalPointerTagRange'
 1256 |   template <ExternalPointerTagRange tag_range>
      |                                     ^
In file included from ../src/binding.cc:3:
In file included from ../src/./language.h:7:
In file included from .../include/node/node_object_wrap.h:25:
In file included from .../include/node/v8.h:24:
In file included from .../include/node/v8-array-buffer.h:12:
.../include/node/v8-local-handle.h:280:5: error: unknown type name 'requires'
  280 |     requires std::is_base_of_v<T, S>
      |     ^
.../include/node/v8-local-handle.h:645:5: error: unknown type name 'requires'
  645 |     requires std::is_base_of_v<T, S>
      |     ^
In file included from ../src/binding.cc:3:
In file included from ../src/./language.h:7:
In file included from .../include/node/node_object_wrap.h:25:
In file included from .../include/node/v8.h:24:
In file included from .../include/node/v8-array-buffer.h:13:
.../include/node/v8-memory-span.h:45:28: error: no member named 'ranges' in namespace 'std'
   45 | inline constexpr bool std::ranges::enable_view<v8::MemorySpan<T>> = true;
      |                       ~~~~~^
.../include/node/v8-memory-span.h:47:28: error: no member named 'ranges' in namespace 'std'
   47 | inline constexpr bool std::ranges::enable_borrowed_range<v8::MemorySpan<T>> =
      |                       ~~~~~^
.../include/node/v8-memory-span.h:168:35: error: no type named 'contiguous_iterator_tag' in namespace 'std'
  168 |     using iterator_concept = std::contiguous_iterator_tag;
      |                              ~~~~~^
In file included from ../src/binding.cc:3:
In file included from ../src/./language.h:7:
In file included from .../include/node/node_object_wrap.h:25:
In file included from .../include/node/v8.h:24:
In file included from .../include/node/v8-array-buffer.h:14:
In file included from .../include/node/v8-object.h:10:
In file included from .../include/node/v8-maybe.h:11:
In file included from .../include/node/cppgc/internal/conditional-stack-allocated.h:10:
.../include/node/cppgc/macros.h:51:1: error: unknown type name 'concept'
   51 | concept IsStackAllocatedType =
      | ^
.../include/node/cppgc/macros.h:52:5: error: use of undeclared identifier 'requires'
   52 |     requires { typename T::IsStackAllocatedTypeMarker; };
      |     ^~~~~~~~
fatal error: too many errors emitted, stopping now [-ferror-limit=]
20 errors generated.
make: *** [Release/obj.target/tree_sitter_runtime_binding/src/binding.o] Error 1
gyp ERR! build error 
gyp ERR! stack Error: `make` failed with exit code: 2
gyp ERR! System Darwin 25.4.0
gyp ERR! command "/opt/homebrew/Cellar/node@24/24.14.0_1/bin/node" "/path/to/node-gyp/bin/node-gyp.js" "rebuild"
gyp ERR! cwd /path/to/tree-sitter
gyp ERR! node -v v24.14.0
gyp ERR! node-gyp -v v11.5.0
gyp ERR! not ok

Steps to Reproduce

  1. Use Node.js 24.x (e.g., nvm install 24)
  2. Install tree-sitter: npm install tree-sitter@0.25.0
  3. Observe compilation failure

Workaround

Setting CXXFLAGS manually works:

CXXFLAGS="-std=c++20" npm install tree-sitter

Or for pnpm:

CXXFLAGS="-std=c++20" pnpm install

Proposed Solution

Update binding.gyp to explicitly set C++20 when building for Node.js 24+. Example:

{
  "targets": [{
    "target_name": "tree_sitter_runtime_binding",
    "cflags_cc": ["-std=c++20"],
    "xcode_settings": {
      "CLANG_CXX_LANGUAGE_STANDARD": "c++20",
      "MACOSX_DEPLOYMENT_TARGET": "11.0"
    },
    "msvs_settings": {
      "VCCLCompilerTool": {
        "AdditionalOptions": ["/std:c++20"]
      }
    },
    # ... rest of config
  }]
}

Alternatively, detect Node.js version and conditionally set the standard:

# In binding.gyp (using gyp conditions)
'conditions': [
  ['node_version_major >= 24', {
    'cflags_cc': ['-std=c++20'],
    'xcode_settings': {
      'CLANG_CXX_LANGUAGE_STANDARD': 'c++20',
    }
  }]
]

Additional Context

  • Node.js 24 was released with v8 headers that require C++20
  • Other native modules (e.g., better-sqlite3, sqlite3) have already updated their build configs for Node.js 24 compatibility
  • This affects any project using Node.js 24+ with tree-sitter
  • The issue impacts both direct installations and transitive dependencies

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions