sebastienros/jint

Javascript Interpreter for .NET

C#

4,735

2,999 commits

updated Oct 12, 2026

See the code

README

Build NuGet Feedz

Jint

Jint is a modern ECMAScript interpreter for .NET. It runs JavaScript directly in your process without native dependencies, bytecode generation, or a separate runtime.

Jint targets .NET Framework 4.7.2, .NET Standard 2.0/2.1, .NET 8, and .NET 10. Start with the documentation or install the core package:

dotnet add package Jint

Quick start

The examples below assume using Jint;.

Evaluate JavaScript

var engine = new Engine();
var result = engine.Evaluate("40 + 2").AsNumber();

Expose .NET and call JavaScript

var engine = new Engine()
    .SetValue("log", new Action<string>(Console.WriteLine))
    .Execute("""
        function greet(name) {
            const message = `Hello, ${name}!`;
            log(message);
            return message;
        }
        """);

var greeting = engine.Invoke("greet", "Ada").AsString();

Prepare code that runs repeatedly

var script = Engine.PrepareScript(
    "items.reduce((sum, value) => sum + value, 0)",
    source: "sum.js",
    strict: true);

var engine = new Engine();
engine.SetValue("items", new[] { 1, 2, 3 });

var total = engine.Evaluate(in script).AsNumber();

Prepared<Script> and Prepared<Module> are thread-safe and may be shared across engines. JavaScript objects are not: a JsValue that contains an object belongs to the engine and realm that created it.

Features

  • Modern ECMAScript, modules, promises, async functions, generators, Intl, and Temporal
  • Direct projection of .NET values, delegates, objects, collections, and types
  • Synchronous and asynchronous module loaders
  • Execution constraints, hardened untrusted-code defaults, and security diagnostics
  • Profiling, statement coverage, debugging, and Chrome DevTools Protocol integration
  • Opt-in Web APIs and Node-compatible modules
  • A headless browser, command-line tool, and MCP server

Browser and Node APIs are not installed by default. Hosts explicitly grant the capabilities each script needs.

Used by

Projects using Jint include RavenDB, EventStoreDB, Orchard Core, Elsa Workflows, Docfx, and JavaScript Engine Switcher.

Additional packages

Jint is the core package used throughout this README. Add another package only when the application needs an optional debugging or browser surface.

PackagePurpose
Jint.DevToolsChrome DevTools Protocol server for debugging and profiling an engine
Jint.BrowserHeadless HTML, DOM, navigation, networking, storage, and content extraction
Jint.Browser.Tooljint-browser command-line tool
Jint.Browser.McpModel Context Protocol server for browser automation

See Additional packages for dependencies, target frameworks, and common combinations.

Branches and releases

Jint 5 is under development on main and has not been released. This branch includes breaking changes; development packages are available from the preview feed.

The 4.x branch is the maintenance lane for Jint 4.16. Changes there preserve compatibility and focus on non-breaking correctness and conformance fixes. The 3.x branch receives only security and severe-correctness maintenance.

Pull requests target main unless they are explicit backports. See Branches and Releases for the complete policy and Migrating to Jint 5 when upgrading from Jint 4.

Standards conformance

These percentages describe the pinned test corpora in this repository, not the entire web platform.

SurfaceResultMeasured scope
ECMAScript and ECMA-40299.9% (102,585 / 102,692)Generated test262 cases from annexB, built-ins, intl402, language, and staging; 107 cases are skipped
WinterTC Minimum Common API79.5% (62 / 78)59 members present and 3 correctly absent for Jint's global shape; the remaining 16 are WebAssembly, which Jint declines by design
Jint runtime Web APIs92.9% (38,649 / 41,581)Assertions in the vendored .any.js WPT corpus across 44 suite directories
Jint.Browser84.0% (9,691 / 11,541)Tests in the gated in-process browser WPT corpus

The test262 result uses commit 419d3e0. Read the detailed scope and exclusions for ECMAScript, Web APIs, and Jint.Browser.

  • Enable strict mode when compatible with the scripts you run.
  • Prepare and cache scripts or modules that execute repeatedly.
  • Give each engine to only one operation at a time; await async operations before reusing or disposing it.
  • Expose narrow, purpose-built host capabilities instead of broad CLR access.
  • Use a fresh engine across trust domains. Global snapshots help trusted reuse, but they are not an isolation boundary.
  • Measure with your own scripts and host objects. Interpreter performance depends heavily on call frequency and script-to-host traffic.

See performance and advanced hosting for engine lifetime, pooling, projection, and caching guidance.

Benchmarks

The repository's current default-job BenchmarkDotNet comparison uses each engine's recommended cached execution path:

  • Jint is the fastest managed engine on 10 of 12 scripts and the fastest interpreter on all 12.
  • Jint has the lowest managed allocation on 10 of 12 scripts.
  • Script-to-host interop is 3.4x to 11.2x faster than the measured ClearScript lanes.
  • The startup-shaped minimal script runs in about 1.1 us with a prepared Jint script, compared with about 380 us for the compiled V8 lane.

Native V8 remains faster on long, compute-heavy loops. Managed allocation figures also cannot include V8's native heap. Read the engine comparison and methodology before comparing engines; absolute numbers from different benchmark sessions are not comparable.

Running untrusted code

Jint is an in-process interpreter, not an operating-system security boundary. Start with the hardened profile, keep the host surface small, and add a process-level boundary for hostile input.

var limits = UntrustedCodeLimits.Default with
{
    TimeoutInterval = TimeSpan.FromSeconds(1),
    MaxStatements = 50_000,
    MemoryLimit = 16_000_000
};

var options = new Options().ForUntrustedCode(limits);
using var engine = new Engine(options);

using (limits.BeginOperation(engine, cancellationToken))
{
    var value = engine.Evaluate(source);
    return engine.ConvertResult(value, limits.ResultLimits);
}

The profile disables broad CLR and reflection access, module loading, string compilation, projected CLR writes, live CLR-array views, registered extension methods, and blocking Atomics.wait. It also applies finite parsing, execution, memory, recursion, regular-expression, promise, and result limits.

Constraints are cooperative and cannot preempt arbitrary host callbacks. Use an external deadline, restrict module and network loaders on every hop, and run hostile code in a least-privileged disposable process or container.

Read Running untrusted code and the threat model before deploying a script service.

Documentation and support

Jint is licensed under the BSD 2-Clause License.

sebastienros/jint

Javascript Interpreter for .NET

C#

4,735

2,999 commits

updated Oct 12, 2026

See the code

README

Build NuGet Feedz

Jint

Jint is a modern ECMAScript interpreter for .NET. It runs JavaScript directly in your process without native dependencies, bytecode generation, or a separate runtime.

Jint targets .NET Framework 4.7.2, .NET Standard 2.0/2.1, .NET 8, and .NET 10. Start with the documentation or install the core package:

dotnet add package Jint

Quick start

The examples below assume using Jint;.

Evaluate JavaScript

var engine = new Engine();
var result = engine.Evaluate("40 + 2").AsNumber();

Expose .NET and call JavaScript

var engine = new Engine()
    .SetValue("log", new Action<string>(Console.WriteLine))
    .Execute("""
        function greet(name) {
            const message = `Hello, ${name}!`;
            log(message);
            return message;
        }
        """);

var greeting = engine.Invoke("greet", "Ada").AsString();

Prepare code that runs repeatedly

var script = Engine.PrepareScript(
    "items.reduce((sum, value) => sum + value, 0)",
    source: "sum.js",
    strict: true);

var engine = new Engine();
engine.SetValue("items", new[] { 1, 2, 3 });

var total = engine.Evaluate(in script).AsNumber();

Prepared<Script> and Prepared<Module> are thread-safe and may be shared across engines. JavaScript objects are not: a JsValue that contains an object belongs to the engine and realm that created it.

Features

  • Modern ECMAScript, modules, promises, async functions, generators, Intl, and Temporal
  • Direct projection of .NET values, delegates, objects, collections, and types
  • Synchronous and asynchronous module loaders
  • Execution constraints, hardened untrusted-code defaults, and security diagnostics
  • Profiling, statement coverage, debugging, and Chrome DevTools Protocol integration
  • Opt-in Web APIs and Node-compatible modules
  • A headless browser, command-line tool, and MCP server

Browser and Node APIs are not installed by default. Hosts explicitly grant the capabilities each script needs.

Used by

Projects using Jint include RavenDB, EventStoreDB, Orchard Core, Elsa Workflows, Docfx, and JavaScript Engine Switcher.

Additional packages

Jint is the core package used throughout this README. Add another package only when the application needs an optional debugging or browser surface.

PackagePurpose
Jint.DevToolsChrome DevTools Protocol server for debugging and profiling an engine
Jint.BrowserHeadless HTML, DOM, navigation, networking, storage, and content extraction
Jint.Browser.Tooljint-browser command-line tool
Jint.Browser.McpModel Context Protocol server for browser automation

See Additional packages for dependencies, target frameworks, and common combinations.

Branches and releases

Jint 5 is under development on main and has not been released. This branch includes breaking changes; development packages are available from the preview feed.

The 4.x branch is the maintenance lane for Jint 4.16. Changes there preserve compatibility and focus on non-breaking correctness and conformance fixes. The 3.x branch receives only security and severe-correctness maintenance.

Pull requests target main unless they are explicit backports. See Branches and Releases for the complete policy and Migrating to Jint 5 when upgrading from Jint 4.

Standards conformance

These percentages describe the pinned test corpora in this repository, not the entire web platform.

SurfaceResultMeasured scope
ECMAScript and ECMA-40299.9% (102,585 / 102,692)Generated test262 cases from annexB, built-ins, intl402, language, and staging; 107 cases are skipped
WinterTC Minimum Common API79.5% (62 / 78)59 members present and 3 correctly absent for Jint's global shape; the remaining 16 are WebAssembly, which Jint declines by design
Jint runtime Web APIs92.9% (38,649 / 41,581)Assertions in the vendored .any.js WPT corpus across 44 suite directories
Jint.Browser84.0% (9,691 / 11,541)Tests in the gated in-process browser WPT corpus

The test262 result uses commit 419d3e0. Read the detailed scope and exclusions for ECMAScript, Web APIs, and Jint.Browser.

  • Enable strict mode when compatible with the scripts you run.
  • Prepare and cache scripts or modules that execute repeatedly.
  • Give each engine to only one operation at a time; await async operations before reusing or disposing it.
  • Expose narrow, purpose-built host capabilities instead of broad CLR access.
  • Use a fresh engine across trust domains. Global snapshots help trusted reuse, but they are not an isolation boundary.
  • Measure with your own scripts and host objects. Interpreter performance depends heavily on call frequency and script-to-host traffic.

See performance and advanced hosting for engine lifetime, pooling, projection, and caching guidance.

Benchmarks

The repository's current default-job BenchmarkDotNet comparison uses each engine's recommended cached execution path:

  • Jint is the fastest managed engine on 10 of 12 scripts and the fastest interpreter on all 12.
  • Jint has the lowest managed allocation on 10 of 12 scripts.
  • Script-to-host interop is 3.4x to 11.2x faster than the measured ClearScript lanes.
  • The startup-shaped minimal script runs in about 1.1 us with a prepared Jint script, compared with about 380 us for the compiled V8 lane.

Native V8 remains faster on long, compute-heavy loops. Managed allocation figures also cannot include V8's native heap. Read the engine comparison and methodology before comparing engines; absolute numbers from different benchmark sessions are not comparable.

Running untrusted code

Jint is an in-process interpreter, not an operating-system security boundary. Start with the hardened profile, keep the host surface small, and add a process-level boundary for hostile input.

var limits = UntrustedCodeLimits.Default with
{
    TimeoutInterval = TimeSpan.FromSeconds(1),
    MaxStatements = 50_000,
    MemoryLimit = 16_000_000
};

var options = new Options().ForUntrustedCode(limits);
using var engine = new Engine(options);

using (limits.BeginOperation(engine, cancellationToken))
{
    var value = engine.Evaluate(source);
    return engine.ConvertResult(value, limits.ResultLimits);
}

The profile disables broad CLR and reflection access, module loading, string compilation, projected CLR writes, live CLR-array views, registered extension methods, and blocking Atomics.wait. It also applies finite parsing, execution, memory, recursion, regular-expression, promise, and result limits.

Constraints are cooperative and cannot preempt arbitrary host callbacks. Use an external deadline, restrict module and network loaders on every hop, and run hostile code in a least-privileged disposable process or container.

Read Running untrusted code and the threat model before deploying a script service.

Documentation and support

Jint is licensed under the BSD 2-Clause License.

Project health

Overall

5.4/10

Maintained

10/10

Code review

0/10
OpenSSF Scorecard

NuGet

Latest release

4.17.0 · Oct 7, 2026

Releases this year

30

Significant stargazers

(top 24 of 27)

Luke Warlow

164 followers · starred Jul 2023

Wang Ao

235 followers · starred Oct 2022

Jeswin

74 followers · starred Mar 2021

Oleksii Holub

2,959 followers · starred Feb 2020