{"id":49308034,"url":"https://github.com/akeit0/okojo","last_synced_at":"2026-04-26T10:31:02.667Z","repository":{"id":351000850,"uuid":"1206847526","full_name":"akeit0/okojo","owner":"akeit0","description":"Okojo is an experimental low allocation managed JavaScript engine for .NET","archived":false,"fork":false,"pushed_at":"2026-04-20T10:29:00.000Z","size":2567,"stargazers_count":121,"open_issues_count":4,"forks_count":4,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-20T12:18:49.294Z","etag":null,"topics":["csharp","dotnet","interpreter","javascript"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/akeit0.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-04-10T10:05:03.000Z","updated_at":"2026-04-18T04:05:00.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/akeit0/okojo","commit_stats":null,"previous_names":["akeit0/okojo"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/akeit0/okojo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akeit0%2Fokojo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akeit0%2Fokojo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akeit0%2Fokojo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akeit0%2Fokojo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/akeit0","download_url":"https://codeload.github.com/akeit0/okojo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/akeit0%2Fokojo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32294591,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-26T09:34:17.070Z","status":"ssl_error","status_checked_at":"2026-04-26T09:34:00.993Z","response_time":129,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["csharp","dotnet","interpreter","javascript"],"created_at":"2026-04-26T10:31:01.934Z","updated_at":"2026-04-26T10:31:02.656Z","avatar_url":"https://github.com/akeit0.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Okojo\n\u003cimg src=\"./docs/okojo_logo.svg\" width=\"20%\"\u003e\n\n\n\"Okojo\" means \"ermine\" or \"stoat\" in Japanese.\n\nOkojo is an experimental low allocation managed JavaScript engine for .NET, aimed at **correctness first**, strong observability/tooling, and practical host integration for modern ECMAScript workloads.\n\nThis repository contains the core engine, host/runtime layers, minimum web-platform api support, WebAssembly integration, code-generation helpers, examples, Test262 infrastructure, and internal sandboxes used to drive compatibility work.\n\n\n## What Okojo is trying to be\n\nThe current direction is:\n\n- a correct, observable JavaScript engine for .NET\n- a clean embedding surface for host applications\n- a base for browser-compatibility and Node-compatibility work\n- a package set that can be consumed in layers instead of one monolithic runtime\n\nThe project is still **prerelease**. Public APIs and package boundaries are being refined, but the repo is already organized around the package wave expected to ship first.\n\n## Current status\n- core language and runtime correctness are the top priority\n- non-legacy, non-staging Test262 baseline coverage is currently passing in the working baseline\n- deprecated and legacy corners are intentionally not a priority unless explicitly re-approved\n- Except for intentional legacy, direct-eval, and the skipping of with statements, the baseline passes **100%** of test262. [See Test262 Section](#test262-progress-and-compatibility-tracking)\n- Unlike jint, its RegExp implementation is ECMAScript 262 compliant, although its performance is not very good.\n- runtime support is currently **.NET 10+**\n- core runtime packages are intended to stay **NativeAOT-friendly by default**\n- browser-facing and Node-facing integration work is active, but not every `src/` project is part of the first public wave\n\n## Performance\n\nAlthough it is not as fast as other implementations that are famous for being more than just an interpreter, it is more than **3** times faster than [jint](https://github.com/sebastienros/jint). \n\nIt is expected to become about **1.5** times faster through performance tuning.\nI'd like to emphasize the **low allocation**.\n\n[for-loop-sum.js](benchmarks/Okojo.Benchmarks/scripts/for-loop-sum.js)\n[many-object.js](benchmarks/Okojo.Benchmarks/scripts/many-object.js)\n[pure-function-call.js](benchmarks/Okojo.Benchmarks/scripts/pure-function-call.js)\n![img](./docs/benchmark.png)\nhttps://chartbenchmark.net/\n\n| Method | Scenario           | Mean       | Error     | StdDev   | Ratio | Gen0     | Allocated | Alloc Ratio |\n|------- |------------------- |-----------:|----------:|---------:|------:|---------:|----------:|------------:|\n| Jint   | for-loop-sum       | 1,503.6 us | 245.87 us | 13.48 us |  1.00 | 142.5781 | 2236280 B |       1.000 |\n| Okojo  | for-loop-sum       |   471.0 us |  37.55 us |  2.06 us |  0.31 |        - |      88 B |       0.000 |\n|        |                    |            |           |          |       |          |           |             |\n| Jint   | many-object        | 1,506.1 us |  68.16 us |  3.74 us |  1.00 | 109.3750 | 1743560 B |        1.00 |\n| Okojo  | many-object        |   452.2 us |  14.31 us |  0.78 us |  0.30 |  27.3438 |  432000 B |        0.25 |\n|        |                    |            |           |          |       |          |           |             |\n| Jint   | pure-function-call | 1,620.5 us | 293.68 us | 16.10 us |  1.00 | 162.1094 | 2561672 B |       1.000 |\n| Okojo  | pure-function-call |   464.0 us |  19.73 us |  1.08 us |  0.29 |        - |     280 B |       0.000 |\n\nBenchmark project:\n\n```powershell\ndotnet run --project benchmarks/Okojo.Benchmarks/Okojo.Benchmarks.csproj -c Release\n```\n\nThe benchmark suite uses BenchmarkDotNet and includes compile, promise, async, property-path, global-binding, and Jint comparison scenarios under `benchmarks/Okojo.Benchmarks`.\n\n\n## Public package wave\n\nThese are the `src/` packages currently marked `IsPackable=true` and intended as the public package wave.\n\n| Package | NuGet | Role |\n| --- | --- | --- |\n| `Okojo` | [nuget.org/packages/Okojo](https://www.nuget.org/packages/Okojo) | Core engine, runtime, modules, compiler, embedding API |\n| `Okojo.Hosting` | [nuget.org/packages/Okojo.Hosting](https://www.nuget.org/packages/Okojo.Hosting) | Host queues, schedulers, workers, and runtime helpers |\n| `Okojo.Diagnostics` | [nuget.org/packages/Okojo.Diagnostics](https://www.nuget.org/packages/Okojo.Diagnostics) | Formatting, inspection, and disassembly helpers |\n| `Okojo.Reflection` | [nuget.org/packages/Okojo.Reflection](https://www.nuget.org/packages/Okojo.Reflection) | Reflection-based CLR interop extensions |\n| `Okojo.WebPlatform` | [nuget.org/packages/Okojo.WebPlatform](https://www.nuget.org/packages/Okojo.WebPlatform) | `fetch`, timers, workers, and web host APIs |\n| `Okojo.WebAssembly` | [nuget.org/packages/Okojo.WebAssembly](https://www.nuget.org/packages/Okojo.WebAssembly) | Backend-agnostic WebAssembly integration |\n| `Okojo.WebAssembly.Wasmtime` | [nuget.org/packages/Okojo.WebAssembly.Wasmtime](https://www.nuget.org/packages/Okojo.WebAssembly.Wasmtime) | Wasmtime backend for `Okojo.WebAssembly` |\n| `Okojo.Annotations` | [nuget.org/packages/Okojo.Annotations](https://www.nuget.org/packages/Okojo.Annotations) | Attributes for Okojo globals and object export generation |\n| `Okojo.SourceGenerator` | [nuget.org/packages/Okojo.SourceGenerator](https://www.nuget.org/packages/Okojo.SourceGenerator) | Roslyn source generator for Okojo export glue |\n| `Okojo.DocGenerator.Annotations` | [nuget.org/packages/Okojo.DocGenerator.Annotations](https://www.nuget.org/packages/Okojo.DocGenerator.Annotations) | Attributes for declaration-file generation control |\n| `Okojo.DocGenerator.Cli` | [nuget.org/packages/Okojo.DocGenerator.Cli](https://www.nuget.org/packages/Okojo.DocGenerator.Cli) | dotnet tool that emits TypeScript declaration files |\n\nNot part of the current public package wave:\n\n- `Okojo.Browser`\n- `Okojo.Node`\n- `Okojo.Node.Cli`\n- `Okojo.Repl`\n- debug server packages\n- compiler experimental projects\n\n## Quick start\n\n```csharp\nusing Okojo;\n\nusing var runtime = JsRuntime.CreateBuilder().Build();\n\nvar realm = runtime.MainRealm;\nvar result = realm.Eval(\"1 + 2\");\n\nConsole.WriteLine(result.NumberValue); // 3\n```\n\nUseful entry points:\n\n- `JsRuntime.CreateBuilder()`\n- `JsRuntime.Create(...)`\n- `JsRuntime.MainRealm`\n- `JsRuntime.CreateRealm()`\n- `JsRealm.Eval(...)`\n- `JsRealm.Execute(...)`\n- `JsRealm.Import(...)`\n- `JsRealm.LoadModule(...)`\n\n## Platform support and AOT\n\nToday, the runtime and host packages are supported on **.NET 10 and later**.\n\nThe core runtime packages are intended to remain **AOT-compatible by default**. In this repo, projects under `src/` default to `IsAotCompatible=true`, and the packages that are pure runtime/hosting surfaces are kept on that path unless they explicitly opt out.\n\nThe main exception is `Okojo.Reflection`, which is intentionally split out so that reflection-backed CLR interop stays opt-in instead of becoming part of the default runtime surface.\n\nThe build-time helper packages such as `Okojo.Annotations`, `Okojo.SourceGenerator`, and `Okojo.DocGenerator.Annotations` are separate from the runtime support story and can be used from projects that feed Okojo-based generation or declaration workflows.\n\n## Core surface: `JsRuntime`, `JsRealm`, and `JsValue`\n\nThe main embedding shape is:\n\n1. build a runtime\n2. use a realm to evaluate scripts or modules\n3. exchange values through `JsValue`\n\n`JsValue` is the core public value type. It is a compact value container used for primitives, strings, objects, symbols, bigints, and host interop.\n\n```csharp\nusing Okojo;\n\nusing var runtime = JsRuntime.Create();\nvar realm = runtime.MainRealm;\n\nJsValue answer = 42;\nJsValue label = \"okojo\";\nJsValue computed = realm.Eval(\"({ total: 21 + 21, ok: true, label: 'okojo' })\");\n\nConsole.WriteLine(answer.Int32Value);      // 42\nConsole.WriteLine(label.AsString());       // okojo\nConsole.WriteLine(computed.IsObject);      // True\nConsole.WriteLine(realm.Eval(\"21 + 21\").NumberValue); // 42\n```\n\nSome commonly useful `JsValue` members:\n\n- `IsNumber`, `IsString`, `IsObject`, `IsBool`, `IsNull`, `IsUndefined`\n- `Int32Value`, `Float64Value`, `NumberValue`\n- `AsString()`, `TryGetString(...)`\n- `AsObject()`, `TryGetObject(...)`\n- implicit conversions from `int`, `double`, `bool`, and `string`\n## Execution duration Constraints\nYou can set execution duration in instructions level.\n```cs\nusing var rt = JsRuntime.CreateBuilder()\n    .UseAgent(agent =\u003e\n    {\n        agent.SetExecutionTimeout(TimeSpan.FromSeconds(2));\n        agent.SetMaxInstructions(100_000);\n        agent.SetCheckInterval(1000);\n    })\n    .Build();\nvar realm = rt.MainRealm;\n// var agent = realm.Agent.SetCheckInterval(10000);\nrealm.Evaluate(\"while(true){}\");\n```\n\n```\nUnhandled exception. Okojo.Runtime.JsRuntimeException: Execution limit exceeded\n```\n## Installing host globals\n\nYou can install globals directly from the runtime builder without defining a full host object model.\n\n```csharp\nusing Okojo;\n\nusing var runtime = JsRuntime.CreateBuilder()\n    .UseGlobals(globals =\u003e globals\n        .Value(\"answer\", JsValue.FromInt32(42))\n        .Function(\"sum\", 2, static (in info) =\u003e\n        {\n            var left = info.GetArgumentOrDefault(0, JsValue.FromInt32(0)).Int32Value;\n            var right = info.GetArgumentOrDefault(1, JsValue.FromInt32(0)).Int32Value;\n            return JsValue.FromInt32(left + right);\n        }))\n    .Build();\n\nvar result = runtime.MainRealm.Eval(\"answer + sum(5, 7)\");\nConsole.WriteLine(result.Int32Value); // 54\n```\n\nThat builder style is the preferred public composition path.\n\n## Reflection-backed CLR access\n\nIf you want CLR namespace and type access from JavaScript, add `Okojo.Reflection` explicitly and opt into reflection-backed interop:\n\n```csharp\nusing Okojo;\nusing Okojo.Reflection;\n\nusing var runtime = JsRuntime.CreateBuilder()\n    .AllowClrAccess(typeof(Console).Assembly, typeof(Enumerable).Assembly)\n    .Build();\n```\n\nFrom JavaScript, CLR access shows up through helper globals:\n\n- `clr` - root CLR namespace object\n- `$using(...)` - import CLR namespaces or types into a smaller resolver object\n- `$place(type, value?)` - create a placeholder object for `ref` and `out` style arguments\n- `$null(type)` - create a typed CLR null value\n- `$cast(type, value)` - force CLR-side conversion\n\nMinimal JavaScript-side examples:\n\n```js\nclr.System.Console.WriteLine(\"hello from CLR\");\n\nconst sys = $using(clr.System);\nsys.Console.WriteLine(sys.String.Concat(\"oko\", \"jo\"));\n\nconst result = $place(clr.System.Int32);\nconst ok = clr.System.Int32.TryParse(\"42\", result);\nclr.System.Console.WriteLine(result.value);\n```\n\nThat last pattern is the basic `ref` / `out` shape: pass a `$place(...)` object to the CLR call, then read the updated `.value` after invocation.\n\nThat split is deliberate:\n\n- `Okojo` keeps the default embedding surface simpler and more AOT-friendly\n- `Okojo.Reflection` is the opt-in package for reflection-based host interop\n\nUseful references:\n\n- `src/Okojo.Reflection/README.md`\n- `src/Okojo.Reflection/ClrAccessExtensions.cs`\n- `sandbox/OkojoRepl`\n```\ndotnet run --project .\\sandbox\\OkojoRepl\\OkojoRepl.csproj \n```\n## Modules\n\nOkojo supports ECMAScript modules through the runtime loader surface.\n\n```csharp\nusing Okojo;\n\nvar loader = new InMemoryModuleLoader(new Dictionary\u003cstring, string\u003e\n{\n    [\"/mods/main.js\"] = \"export const value = 1 + 2;\"\n});\n\nusing var runtime = JsRuntime.CreateBuilder()\n    .UseModuleSourceLoader(loader)\n    .Build();\n\nJsValue ns = runtime.MainRealm.Import(\"/mods/main.js\");\nConsole.WriteLine(ns);\n```\n\nThere are runnable module-focused examples under:\n\n- `examples/OkojoModuleSample`\n- `examples/OkojoModuleSampleRunner`\n- `sandbox/OkojoProbeSandbox`\n\n## Hosting and web APIs\n\n`Okojo.Hosting` and `Okojo.WebPlatform` are intended for hosts that need event loops, timers, workers, fetch, and queue control.\n\nThe host sandbox examples show both browser-like and server-like queue wiring:\n\n```csharp\nvar runtime = JsRuntime.CreateBuilder()\n    .UseTimeProvider(timeProvider)\n    .UseLowLevelHost(host =\u003e host.UseTaskScheduler(eventLoop))\n    .UseWebDelayScheduler(eventLoop)\n    .UseWebTimerQueue(WebTaskQueueKeys.Timers)\n    .UseAnimationFrameQueue(WebTaskQueueKeys.Rendering)\n    .UseFetchCompletionQueue(WebTaskQueueKeys.Network)\n    .UseModuleSourceLoader(moduleLoader)\n    .UseBrowserGlobals(fetch =\u003e fetch.HttpClient = httpClient)\n    .Build();\n```\n\nIf you want a smaller default set for timers, delays, and related runtime globals, the examples also use:\n\n```csharp\nvar runtime = JsRuntime.CreateBuilder()\n    .UseWebRuntimeGlobals()\n    .Build();\n```\n\nUseful references:\n\n- `examples/OkojoHostEventLoopSandbox`\n- `examples/OkojoGameLoopSandbox`\n- `src/vscode-debug/extension`\n- `tests/Okojo.Tests/AgentJobQueueTests.cs`\n- `tests/Okojo.Tests/AsyncAwaitTests.cs`\n\n## WebAssembly and Wasmtime\n\n`Okojo.WebAssembly` provides the backend-agnostic WebAssembly integration surface. `Okojo.WebAssembly.Wasmtime` provides a packaged Wasmtime backend.\n\nThe Wasmtime-backed setup looks like this:\n\n```csharp\nusing Okojo.WebAssembly.Wasmtime;\n\nusing var runtime = NodeRuntime.CreateBuilder()\n    .UseWebAssembly(wasm =\u003e wasm\n        .UseBackend(static () =\u003e new WasmtimeBackend())\n        .InstallGlobals())\n    .Build();\n```\n\nUseful references:\n\n- `sandbox/OkojoInkProbe`\n- `src/Okojo.WebAssembly`\n- `src/Okojo.WebAssembly.Wasmtime`\n\n## Node-like execution and InkProbe\n\n`Okojo.Node` and `Okojo.Node.Cli` are not in the current public package wave yet, but they are already useful as integration and bring-up surfaces.\n\nThe `okojonode` CLI supports script execution, eval, printing, and debugger-oriented entry points:\n\n```text\nokojonode \u003cscript\u003e [arguments]\nokojonode inspect \u003cscript\u003e [arguments]\nokojonode -e \u003ccode\u003e\nokojonode -p \u003ccode\u003e\n```\n\nOne practical way to exercise the current Node-like stack is to run the InkProbe app through the CLI:\n\n```powershell\ndotnet run -c Release --project src/Okojo.Node.Cli/Okojo.Node.Cli.csproj sandbox/OkojoInkProbe/app/main.mjs\n```\n\nInkProbe itself is the focused sandbox for the same stack and is useful when you want a reduced Wasmtime-enabled repro with optional debugger logging:\n\n```powershell\ndotnet run --project sandbox/OkojoInkProbe/OkojoInkProbe.csproj -c Release -- --debugger\n```\n\nUseful references:\n\n- `sandbox/OkojoInkProbe`\n- `src/Okojo.Node.Cli/NodeCliApplication.cs`\n- `docs/OKOJO_NODE_INK_DEBUG_WORKFLOW.md`\n\n## Source generation with `Okojo.Annotations` and `Okojo.SourceGenerator`\n\n`Okojo.Annotations` and `Okojo.SourceGenerator` are for strongly-typed host APIs that should become JavaScript globals or generated object bindings.\n\nExample shape:\n\n```csharp\nusing Okojo.Annotations;\nusing Okojo.DocGenerator.Annotations;\n\n[GenerateJsGlobals]\n[DocDeclaration(\"globals\")]\ninternal sealed partial class SketchGlobals\n{\n    [JsGlobalProperty(\"width\")]\n    public int Width =\u003e 320;\n\n    [JsGlobalProperty(\"strokeWidth\", Writable = true)]\n    public int StrokeWidth { get; set; } = 2;\n\n    [JsGlobalFunction(\"background\")]\n    private void Background(byte r, byte g, byte b) { }\n\n    [JsGlobalFunction(\"sumNumbers\")]\n    private int SumNumbers(ReadOnlySpan\u003cint\u003e values) =\u003e values.ToArray().Sum();\n}\n```\n\nThen install the generated globals:\n\n```csharp\nvar globals = new SketchGlobals();\n\nusing var runtime = JsRuntime.CreateBuilder()\n    .UseGlobals(globals.InstallGeneratedGlobals)\n    .Build();\n```\n\nReal references:\n\n- `examples/OkojoArtSandbox/SketchRuntime.cs`\n- `tests/Okojo.Tests/GeneratedGlobalInstallerTests.cs`\n\n## Generated object bindings and doc annotations\n\n`GenerateJsObjectAttribute` is for object-style bindings. `DocDeclarationAttribute` and `DocIgnoreAttribute` control declaration output.\n\n```csharp\nusing Okojo;\nusing Okojo.Annotations;\nusing Okojo.DocGenerator.Annotations;\n\n[GenerateJsObject]\n[DocDeclaration(\"Foo/Bar\", \"Docs.Shapes\")]\npublic partial class GeneratedHostBindingSample\n{\n    public float X { get; set; }\n\n    public static int SumNumbers(ReadOnlySpan\u003cint\u003e values)\n    {\n        var sum = 0;\n        foreach (var value in values)\n            sum += value;\n        return sum;\n    }\n\n    [DocIgnore]\n    public string Echo(string value) =\u003e $\"echo:{value}\";\n\n    public static string DescribeJsValues(ReadOnlySpan\u003cJsValue\u003e values)\n    {\n        if (values.Length == 0)\n            return string.Empty;\n        return string.Join(\"|\", values.ToArray());\n    }\n}\n```\n\nReal references:\n\n- `examples/OkojoArtSandbox/GeneratedObjectSample.cs`\n- `tests/Okojo.Tests/HostInteropTests.cs`\n\n## Declaration generation with `Okojo.DocGenerator.Cli`\n\n`Okojo.DocGenerator.Cli` is a dotnet tool that walks a project, finds `[GenerateJsGlobals]` and `[GenerateJsObject]` types, and emits TypeScript declaration files.\n\nIt also carries XML documentation comments into the generated declarations, including `summary` text and `param` descriptions, so the emitted `.d.ts` can preserve useful TSDoc-style API help.\n\n```powershell\ndotnet tool install --global Okojo.DocGenerator.Cli\nokojo-docgen --project ./src/MyProject/MyProject.csproj --out ./artifacts/types/globals.d.ts\n```\n\nPer-type output:\n\n```powershell\nokojo-docgen --project ./src/MyProject/MyProject.csproj --out ./artifacts/types --per-type\n```\n\nReal run against `examples/OkojoArtSandbox/OkojoArtSandbox.csproj`:\n\n```powershell\ndotnet run --project ./src/Okojo.DocGenerator.Cli/Okojo.DocGenerator.Cli.csproj -c Release -- --project ./examples/OkojoArtSandbox/OkojoArtSandbox.csproj --out ./artifacts/docgen-readme --per-type\n```\n\nGenerated files:\n\n- `artifacts/docgen-readme/globals.d.ts`\n- `artifacts/docgen-readme/objects/GeneratedObjectSample.d.ts`\n\nExcerpt from the generated `globals.d.ts`:\n\n```ts\n/**\n * Requests a sketch canvas size in pixels.\n * @param width Requested canvas width.\n * @param height Requested canvas height.\n */\ndeclare function createCanvas(width?: number, height?: number): void;\n\ndeclare function background(color: string): void;\ndeclare function background(gray: number): void;\ndeclare function background(gray: number, alpha: number): void;\ndeclare function background(r: number, g: number, b: number): void;\ndeclare function background(r: number, g: number, b: number, a: number): void;\n\ndeclare const width: number;\ndeclare const height: number;\ndeclare const frameCount: number;\n```\n\nThat comment block comes from the C# XML doc comment on `createCanvas`:\n\n```csharp\n/// \u003csummary\u003eRequests a sketch canvas size in pixels.\u003c/summary\u003e\n/// \u003cparam name=\"width\"\u003eRequested canvas width.\u003c/param\u003e\n/// \u003cparam name=\"height\"\u003eRequested canvas height.\u003c/param\u003e\n[JsGlobalFunction(\"createCanvas\")]\nprivate void CreateCanvas(int width = 960, int height = 720) { }\n```\n\nExcerpt from the generated object declaration:\n\n```ts\ndeclare namespace OkojoArtSandbox {\n    class GeneratedObjectSample {\n        Name: string;\n        Age: number;\n        DoSomething(): boolean;\n    }\n}\n```\n\nThe tool entry point lives in `src/Okojo.DocGenerator.Cli/Program.cs`.\n\n## VS Code debugger\n\nThere is also an in-repo VS Code debugger scaffold under `src/vscode-debug/extension`.\n\nCurrent capabilities include:\n\n- debugger contribution and configuration provider\n- inline adapter that launches `src/Okojo.DebugServer`\n- paused stack, locals, and source inspection from debug-server checkpoints\n- source breakpoints by `sourcePath:line`\n- `stopOnEntry` support\n\nQuick local run:\n\n```powershell\ncd src/vscode-debug/extension\nnpm install\nnpm run compile\n```\n\nThen open `src/vscode-debug/extension` in VS Code, press `F5`, and use the sample workspace under `samples/okojo-debugger-workspace`.\n\n## Useful examples and sandboxes\n\nIf you want concrete code before reading internals, start here:\n\n| Path | What it shows |\n| --- | --- |\n| `examples/OkojoModuleSample` | ES module import/export behavior with a runnable sample |\n| `examples/OkojoModuleSampleRunner` | Installing a small host `console` and evaluating a module entry point |\n| `examples/OkojoHostEventLoopSandbox` | Browser-like queue wiring for timers, animation frames, and fetch |\n| `examples/OkojoGameLoopSandbox` | Frame-budgeted execution, module loading, and manual event-loop pumping |\n| `examples/OkojoArtSandbox` | Generated globals and objects driving an interactive sketch host |\n| `benchmarks/Okojo.Benchmarks` | BenchmarkDotNet suite for runtime, object-path, promise, compile, and Jint-comparison scenarios |\n| `sandbox/OkojoRuntimeDebugSandbox` | Runtime debugger checkpoints, breakpoints, module vs script execution |\n| `sandbox/OkojoProbeSandbox` | Small probes for script/module execution and namespace inspection |\n| `sandbox/OkojoInkProbe` | Node-like host with Wasmtime-enabled WebAssembly support |\n| `src/Okojo.Node.Cli` | Node-like CLI entry point for scripts, eval, print, inspect, and InkProbe launching |\n| `src/vscode-debug/extension` | VS Code debugger adapter scaffold and sample workspace integration |\n\n## `src/` project map\n\n`src/` contains both the public package wave and repo-internal projects used for host integration, tooling, experiments, and debugging. Being under `src/` does **not** mean a project is intended for near-term NuGet publication.\n\n| Project | Role | Publication status |\n| --- | --- | --- |\n| `Okojo` | Core engine, runtime, compiler, modules, embedding API | Public package wave |\n| `Okojo.Hosting` | Host queues, scheduling, worker helpers | Public package wave |\n| `Okojo.Diagnostics` | Formatting, inspection, disassembly helpers | Public package wave |\n| `Okojo.Reflection` | Reflection-backed CLR interop extensions | Public package wave |\n| `Okojo.WebPlatform` | Host-installed web APIs such as fetch, timers, workers | Public package wave |\n| `Okojo.WebAssembly` | Backend-agnostic WebAssembly integration surface | Public package wave |\n| `Okojo.WebAssembly.Wasmtime` | Wasmtime backend for `Okojo.WebAssembly` | Public package wave |\n| `Okojo.Annotations` | Shared annotations for source generation and tooling | Public package wave |\n| `Okojo.SourceGenerator` | Roslyn source generator used by Okojo export patterns | Public package wave |\n| `Okojo.DocGenerator.Annotations` | Doc generation annotation types | Public package wave |\n| `Okojo.DocGenerator.Cli` | Documentation generator dotnet tool | Public package wave |\n| `Okojo.Browser` | Browser-oriented host and integration surface | Not in current NuGet wave |\n| `Okojo.Node` | Node-compatibility host and runtime layer | Not in current NuGet wave |\n| `Okojo.Node.Cli` | Dotnet tool for the Node-like CLI host | Packable tool, intentionally outside the current public workflow |\n| `Okojo.Repl` | Interactive shell and console-facing runtime host | Internal and dev-focused for now |\n| `Okojo.DebugServer` | Debug transport and server host | Internal diagnostics infrastructure |\n| `Okojo.DebugServer.Core` | Shared debug server core types | Internal diagnostics infrastructure |\n| `vscode-debug/extension` | VS Code debugger adapter and launch configuration support | Internal tooling |\n| `Okojo.Compiler.Experimental` | Experimental compiler work | Experimental and internal |\n\nPackage/versioning/publishing strategy for the packable projects is documented in [docs/OKOJO_PACKABLE_PACKAGE_WORKFLOW.md](docs/OKOJO_PACKABLE_PACKAGE_WORKFLOW.md).\n\n## Requirements\n\n- .NET 10 SDK\n\n## Development\n\nFast local validation loop:\n\n```powershell\ndotnet test tests/Okojo.Tests/Okojo.Tests.csproj\n```\n\nFocused Test262 example:\n\n```powershell\ndotnet run --project ./tools/Test262Runner/ -c Release --filter test262/test/language\n```\n\n## Test262 progress and compatibility tracking{#test262}\n\nThis repo tracks compatibility progress in checked-in artifacts so work can be prioritized by **passed**, **failed**, and **classified skip** status rather than a single aggregate number.\n[TEST262_PROGRESS_INCREMENTAL.md](TEST262_PROGRESS_INCREMENTAL.md)\nImportant files:\n\n| File | Purpose |\n| --- | --- |\n| [`TEST262_PROGRESS_INCREMENTAL.md`](TEST262_PROGRESS_INCREMENTAL.md) | Human-readable progress snapshot grouped by category and folder, including passed, failed, and split skip classes |\n| `TEST262_PROGRESS_INCREMENTAL.json` | Machine-readable version of the same incremental progress data (gitignored)|\n| [`docs/TEST262_SKIP_TAXONOMY.md`](docs/TEST262_SKIP_TAXONOMY.md) | Skip classification policy and grouped skip inventory |\n| `tools/Test262Runner` | Runner and progress generation logic |\n\n### How to read `TEST262_PROGRESS_INCREMENTAL.md`\n\nThe main columns are:\n\n- **Passed** - tests currently passing\n- **Failed** - tests currently failing\n- **Skip Std** - baseline ECMAScript coverage intentionally skipped for now\n- **Skip Legacy** - deprecated legacy coverage intentionally not prioritized\n- **Skip Annex B** - Annex B coverage tracked separately from other legacy behavior\n- **Skip Proposal** - proposal and staging work not part of the baseline target\n- **Skip Finished** - finished proposals that are still intentionally outside the current carried baseline\n- **Skip Other** - intentional exceptions or non-standard buckets that do not fit the above\n- **Baseline Passed %** - completion percentage after excluding non-baseline skip classes from the denominator\n\nThat last column is usually the best single number to use for practical baseline progress discussions.\n\n## Key docs\n\n- [`OKOJO_BROWSER_COMPATIBILITY_PLAN.md`](OKOJO_BROWSER_COMPATIBILITY_PLAN.md) - top-level compatibility direction\n- [`docs/TEST262_SKIP_TAXONOMY.md`](docs/TEST262_SKIP_TAXONOMY.md) - skip taxonomy and inventory\n- [`docs/OKOJO_PACKABLE_PACKAGE_WORKFLOW.md`](docs/OKOJO_PACKABLE_PACKAGE_WORKFLOW.md) - packable package versioning and publishing strategy\n\n## Licensing\n\nSee [LICENSE](LICENSE) and [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakeit0%2Fokojo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fakeit0%2Fokojo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fakeit0%2Fokojo/lists"}