# Edge.js: one process holding both the CLR and V8

> Edge.js is a native addon that lets Node.js call .NET and .NET call Node.js inside a single process, handling marshaling between the CLR and V8 heaps and reconciling the single-threaded JavaScript runtime with the multithreaded CLR. It is a maintained fork of Tomasz Janczuk's original library with support for current Node.js and .NET Core releases.

**agracio/edge-js** — Run .NET and Node.js code in-process on Windows, MacOS, and Linux

- Repository: https://github.com/agracio/edge-js
- Stars: 838 · Forks: 98
- Language: C++
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/agracio-edge-js

## What in-process actually buys you

Edge.js allows Node.js and .NET code to run in one process on Windows, macOS and Linux. You can call .NET functions from Node.js and Node.js functions from .NET.

The interesting part is the list of problems that in-process solves, because they are the reasons this kind of library exists at all. Edge.js takes care of marshaling data between the CLR and V8. It reconciles the threading models of the single-threaded V8 and the multithreaded CLR. And it ensures the correct lifetime of objects on the V8 and CLR heaps. Each of those is a problem you would otherwise solve with a process boundary and a serialisation format, which is exactly the cost Edge.js is designed to avoid.

The CLR side can be pre-compiled or given as source, and the documentation names C#, F#, Python through IronPython, and PowerShell as the source languages it can compile at runtime. Edge can also be extended to support other CLR languages or DSLs.

The library is a fork. The README states plainly that it is based on the original edge library by Tomasz Janczuk and that all credit for the original work goes to him. The fork's own updates section lists support for new Node.js versions, support for .NET Core 3.1 through 9.x on Windows, Linux and macOS, and a set of specific fixes carried over from pull requests, including an AccessViolationException when running Node.js code from C# and a StackOverflowException that occurs when the underlying C# code throws a complex exception.

## The use cases the README lists

The stated list of things the mechanism supports is worth reading as a decision guide, because several of these only make sense if the two runtimes share a process.

Scripting Node.js from a .NET application on Windows using .NET Framework is one, and scripting C# from a Node.js application on Windows, macOS and Linux using .NET Framework or .NET Core is the mirror image. Using CLR multithreading from Node.js for CPU intensive work is the case where the threading reconciliation pays off directly, since JavaScript's single thread cannot use extra cores on its own. Writing native extensions to Node.js in C# rather than in C or C++ is another, and so is integrating existing .NET components into Node.js applications and accessing MS SQL from Node.js using ADO.NET.

The scripting cases extend beyond C#: F#, PowerShell and IronPython can all be scripted from Node.js. That is a debugging and automation convenience more than an architectural one, and it is a good demonstration that the CLR hosting path is generic.

The sample directory reflects the same spread. There are hello samples for a lambda, a function and a file, arithmetic and class samples, a marshalling sample in each direction, sync and instance samples, a listener sample, a worker sample that matches the CPU bound use case, a SQL sample in both a .csx and a .js flavour, an X509 store sample, a SOAP sample, event log, registry read and registry write samples, zip and unzip samples and an image conversion sample. The .csx extension on some of them is the marker for the inline C# script path.

## A native addon with a per-platform binary policy

Edge.js ships as an npm package named edge-js, with a NuGet package named EdgeJs, and the package manifest is where the practical constraints live. The version is 26.1.0, the license is MIT, the entry point is./lib/edge.js with TypeScript definitions in edge-js.d.ts, and the engine requirements are npm 8.0.0 or newer and Node 16.0.0 or newer. The runtime dependencies are minimal: the edge-cs package, aliased to the @agracio scope, and nan, the native addon shim. The install script is node tools/install.js and the test script is node tools/test.js, so the native build happens as part of installation rather than being a separate manual step.

The Node.js support policy is spelled out in three parts. Windows supports the four latest LTS or candidate LTS releases, meaning the even-numbered versions, plus up to one Current odd-numbered release, which is dropped when superseded by a new LTS candidate. macOS ships pre-compiled binaries for the same releases as Windows, and when you use a version that is not pre-compiled the binaries are compiled during npm install using node-gyp. Linux always compiles from source during npm install.

The precompiled Windows table covers Node 20.x and 22.x on x86, x64 and arm64, while 24.x and 26.x are available on x64 and arm64 only, with x86 marked as unsupported. macOS ships precompiled binaries for 20.x, 22.x, 24.x and 26.x on x64 and arm64, and the Linux row covers 16.x through 26.x on x64 and arm64, with other architectures noted as possibly working but untested.

That last point is the one to check first if you deploy on Linux arm64, which is now common on cloud hardware and on Apple silicon.

## CLR flavour decides what you can script

There are two matrices here and they answer different questions. The first asks which CLR you can script from Node.js, and the answer is broadly yes everywhere, with the caveat that the .NET Framework column is Windows only and the Mono column has a footnote on Linux.

The second matrix asks the opposite direction, scripting Node.js from the CLR, and here the answer is narrow: Windows with .NET Framework is supported, while Mono and CoreCLR are marked unsupported on every platform. That is the asymmetry to notice. A .NET application that wants to call into Node.js is limited to the .NET Framework on Windows, while a Node.js application can call .NET broadly.

The reason is in the architecture rather than in a policy decision. The CLR hosting path is what Edge.js implements, so running CLR code inside Node.js is the direct case. Hosting V8 inside the CLR is the harder direction, and the original design supported it only where the .NET Framework provided the hosting APIs.

Mono is called out separately. The README states that Mono is no longer actively supported, that existing code will remain in Edge.js, and that the focus will be on .NET Core. The footnotes explain that there is no flag to force Edge.js to run in a Mono environment on Windows, so it would only happen on a Windows machine without .NET Framework present, and that on Linux there is a known bug that throws an exception when executing C# code under certain conditions, with a workaround involving setting the LD_PRELOAD environment variable before running Edge.js with Mono.

## Packaging, Electron and the maintenance posture

The repository is a Visual Studio solution with a C++ source tree, a binding.gyp file for node-gyp, a Dockerfile, and separate directories for performance work, samples, stress tests and tools. The Docker image is Ubuntu 24.04 with build-essential, python3, git and libglib2.0-dev, and it installs Node.js, the.NET SDK and node-gyp like this:

```bash
RUN curl -sL https://deb.nodesource.com/setup_22.x | sudo -E bash -
RUN sudo apt -q -y install dotnet-sdk-9.0
RUN npm i -g node-gyp
```

The Node.js line comes from the NodeSource setup script for the 22.x release, the SDK from the dotnet backports PPA.

Electron is handled by a separate repository, electron-edge-js, and the README recommends it for Electron applications and, importantly, for VS Code extensions, because VS Code runs on an Electron shell.

The packaging surfaces are the npm package edge-js and the NuGet package EdgeJs, and the quick start sample lives in a separate repository, edge-js-quick-start, which shows a sample app working with.NET Core using inline code and compiled C# libraries.

The maintenance picture is mixed but favourable. The last push was on 2026-10-20, days before this article, and the npm version tracks the Node major it supports, sitting at 26.1.0 for Node 26. The repository has no GitHub releases, so the npm and NuGet packages are the release artefacts rather than tags in the repository.

The one Windows-specific prerequisite is the Visual C++ Redistributable, which the README lists as a requirement for Windows.

## Where Edge.js is the wrong choice

The first thing to weigh is whether in-process is what you actually need. A process boundary with HTTP or gRPC between a Node.js service and a.NET service costs you serialisation and a network hop, and buys you isolation, independent deployment and independent failure. If the two sides do not need to share objects or share threads, that trade is usually worth taking, and Edge.js exists for the cases where it is not.

The second limitation is the platform matrix. Scripting Node.js from.NET is limited to.NET Framework on Windows, so a cross-platform.NET application that wanted to embed JavaScript cannot use this path. Mono support is explicitly parked. Linux always compiles from source during npm install, and architectures beyond x64 and arm64 are only marked as possibly working. If your deployment has to run everywhere, that is a constraint you inherit.

The third is the nature of the thing itself. Edge.js is a native addon that hosts two runtimes in one process, which means the failure modes are the union of both runtimes' failure modes: a garbage collection problem in either heap, a stack overflow across the boundary, a threading deadlock. The fixes listed in the updates section, an AccessViolationException and a StackOverflowException from complex C# exceptions, are exactly the sort of defect that comes from that union.

There is also a modern alternative for some of these cases that does not need a native addon at all. Node.js has its own worker threads for CPU bound work, and.NET has supported calling JavaScript engines directly for years. Neither gives you the same in-process object sharing, but both are considerably easier to reason about than hosting V8 inside the CLR.

What Edge.js still gives you is the thing it was built for: a.NET library called from Node.js with no serialisation, or C# compiled at runtime from a string, in one process, on three operating systems.

## Conclusion

Edge.js fits a team that genuinely needs both runtimes in one address space, for example a Node.js service that must reuse existing.NET components, or a.NET application that wants to script parts of itself in JavaScript without a second process and a serialisation boundary. It does not fit a project that would be better served by an HTTP or gRPC boundary between two services, Before adopting it, confirm your Node.js version is in the precompiled table for your platform, check whether your runtime is CoreCLR rather than Mono, since Mono is no longer actively supported, and be aware that the prebuilt binaries cover only the versions listed, with everything else compiled from source during npm install.

## FAQ

### What does Edge.js do and what problem does it solve?

It lets Node.js call .NET functions and .NET call Node.js functions inside one process on Windows, macOS and Linux. It handles data marshaling between the CLR and V8, reconciles the single-threaded V8 runtime with the multithreaded CLR, and manages object lifetimes on both heaps.

### Which Node.js versions have prebuilt Edge.js binaries?

On Windows, Node 20.x and 22.x have x86, x64 and arm64 builds, while 24.x and 26.x have x64 and arm64 only. macOS ships precompiled x64 and arm64 builds for 20.x, 22.x, 24.x and 26.x. Linux always compiles during npm install using node-gyp, and other Linux architectures may work but are untested.

### Can I still use Mono with Edge.js?

Mono is no longer actively supported. Existing code stays in Edge.js but the focus has moved to .NET Core. There is no flag to force Edge.js to run in a Mono environment on Windows, and on Linux there is a known bug when executing C# code under certain conditions, worked around by setting the LD_PRELOAD environment variable.

### How do I install Edge.js?

It is published as the npm package edge-js and the NuGet package EdgeJs. The package requires npm 8.0.0 or newer and Node 16.0.0 or newer, and the install script runs node tools/install.js, which builds the native module when no prebuilt binary matches your platform. On Windows you also need the Visual C++ Redistributable.

### Does Edge.js work with Electron and VS Code extensions?

Yes, through the separate electron-edge-js package, which the README recommends for Electron applications and for VS Code extensions because VS Code runs on an Electron shell.

## Sources

- [agracio/edge-js on GitHub](https://github.com/agracio/edge-js)
- [Issues](https://github.com/agracio/edge-js/issues)
- [License: MIT](https://github.com/agracio/edge-js/blob/master/LICENSE)
- [README](https://github.com/agracio/edge-js/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/agracio-edge-js
