Skip to content

[browser][coreCLR] Skeleton for JavaScript host - #119683

Merged
pavelsavara merged 27 commits into
dotnet:mainfrom
pavelsavara:wasm_singlefilehost
Sep 23, 2025
Merged

[browser][coreCLR] Skeleton for JavaScript host#119683
pavelsavara merged 27 commits into
dotnet:mainfrom
pavelsavara:wasm_singlefilehost

Conversation

@pavelsavara

@pavelsavarapavelsavara commented Sep 13, 2025

Copy link
Copy Markdown
Member

Skeleton for JavaScript host

The goal on this PR is to establish directory structure and naming.

All new *.js files are

  • hand written skeleton and PoC for now.
  • It will be replaced by TypeScript sources in better quality in next PRs.
  • later most of them would be generated into artifacts\obj
    • like artifacts\obj\native\<RID>\System.Native.Browser\ next to libSystem.Native.Browser.a

Functionality

As compared to current WASM corerun, this could run in a browser as well as in NodeJS.
In NodeJS it expects all managed assemblies in the current folder and name of main assembly as first argument.
In browser, it loads assets as defined in dotnet.boot.js, which you can edit before you host it with dotnet-serve
The assemblies are loaded asynchronously and put into memory via external_assembly_probe callback.
All of this would be further integrated with existing Mono WASM SDK later.

New files

  • src\native\corehost\browserhost\
    • this is targeting NodeJS for now
    • libBrowserHost.js - implements external_assembly_probe callback
    • browserhost.cpp - creates coreCLR instance
      • statically linked
      • no path probing or host policy
      • passing TRUSTED_PLATFORM_ASSEMBLIES as env var for the PoC, to be improved.
    • sample files
      • At the moment clumsy and to be simplified.
      • index.html - target web page
      • main.mjs - this is demo of the NodeJS usage.
      • dotnet.boot.js - list of assets to download. This going to be generated by MSBuild of the WASM SDK later. It's 100% compatible with Mono/Blazor
    • loader
      • ES6 JavaScript module representing public JS API and a loader/host
      • it will produce dotnet.js file in the final product.
      • the module downloads other JS modules, DLLs and other assets.
      • needs to be small so that it would start the download cascade quickly
  • src\native\libs\Common\JavaScript
    • shared type definitions and small helpers connecting our JavaScript modules
  • src\native\libs\System.Native.Browser\
    • Emscripten library with native functions for runtime PAL and ICalls
    • libSystem.Native.Browser.js - JS part of the library
    • libSystem.Native.Browser.extpost.js - ES6 exports helpers
    • CMakeLists.txt, entrypoints.c - native part of the library. C exports for P/Invoke.
  • src\native\libs\System.Runtime.InteropServices.JavaScript.Native\
    • Emscripten library with native functions for JS interop
    • libSystem.Runtime.InteropServices.JavaScript.Native.js - JS part of the library
    • CMakeLists.txt, entrypoints.c - native part of the library. C exports for P/Invoke.
    • dotnet.runtime.js
      • ES6 JavaScript module with the JS interop marshallers
      • it will produce dotnet.runtime.js file in the final product.
  • src\native\
    • root of the JavaScript build
    • package.json, package-lock.json, .npmrc - npm package definition and dependencies
    • .eslintrc.cjs, .eslintrc.cjs - JS code style
    • rollup.config.js - JS bundler and build script for TypeScript
    • tsconfig.json - typescript configuration

Q & A

  • Q: does this support C code trimming
  • A: not yet, until we generate list of P/Invoke dependencies from IL trimmed assemblies
  • Q: does this support JS code trimming and symbol minifications
  • A: It would (to some degree) once we bring TS. Protecting symbols from Emscripten is complex topic.
  • Q: there are similar files in src\mono\browser\runtime, are we going to reuse them ?
  • A: we are going to reuse best ideas, but keep Mono code as is in place
  • Q: could we produce runtime without JavaScript interop assembly ?
  • A: Tentative yes. I'm working on it. The challenge is that async C# Main() needs to yield to browser event loop and marshal Task/Promise. Synchronous main is not very useful in JS.

Fixes#119685
Contributes to #113067

image

@pavelsavarapavelsavara added this to the 11.0.0 milestone Sep 13, 2025
@pavelsavarapavelsavara self-assigned this Sep 13, 2025
@pavelsavarapavelsavara added arch-wasm WebAssembly architecture area-Host os-browser Browser variant of arch-wasm labels Sep 13, 2025
Comment threadsrc/native/libs/System.Globalization.Native/CMakeLists.txt Outdated
@pavelsavara

Copy link
Copy Markdown
MemberAuthor

Together with #119591

image

Comment thread.github/policies/resourceManagement.yml
Comment threadsrc/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.props Outdated
Comment threadsrc/native/corehost/browser/dotnet.boot.js Outdated
@pavelsavara
pavelsavara marked this pull request as ready for review September 18, 2025 22:35
CopilotAI review requested due to automatic review settings September 18, 2025 22:35

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull Request Overview

Establishes the initial skeleton, layout, and build hooks for a JavaScript-based host for CoreCLR targeting browsers and NodeJS, plus supporting JS/TS library scaffolding.

  • Introduces placeholder JS libraries for System.JavaScript and System.Runtime.InteropServices.JavaScript and wires them into the Emscripten build.
  • Adds a simple browser/NodeJS host (C++ + JS glue) and pipeline/build file updates to include the new components.
  • Provides initial TypeScript config, linting setup, and documentation placeholders for the upcoming TS-based implementation.

Reviewed Changes

Copilot reviewed 42 out of 48 changed files in this pull request and generated 12 comments.

Show a summary per file
FileDescription
src/native/libs/tsconfig.jsonAdds TypeScript compiler configuration for JS/TS libraries.
src/native/libs/rollup.config.jsPlaceholder rollup config; currently throws not-implemented (build stub).
src/native/libs/package.jsonAdds npm metadata and devDependencies for rollup/TS/eslint build tooling.
src/native/libs/System.Runtime.InteropServices.JavaScript/libSystem.Runtime.InteropServices.JavaScript.jsDummy JS interop library for Emscripten; exports interop entrypoints and initialization hooks.
src/native/libs/System.Runtime.InteropServices.JavaScript/entrypoints.cC entrypoints mapping to JS implementations for P/Invoke resolution.
src/native/libs/System.Runtime.InteropServices.JavaScript/ReadMe.mdDocumentation stub for the interop library.
src/native/libs/System.Runtime.InteropServices.JavaScript/CMakeLists.txtCMake target for the native static library (conditional on GEN_PINVOKE).
src/native/libs/System.JavaScript/libSystem.JavaScript.jsDummy PAL library functions (e.g., random bytes) and Emscripten integration.
src/native/libs/System.JavaScript/libSystem.JavaScript.extpost.jsPost-JS module to expose initialize entrypoint and create the Emscripten runtime.
src/native/libs/System.JavaScript/entrypoints.cC entrypoints mapping to JS PAL functions for P/Invoke resolution.
src/native/libs/System.JavaScript/ReadMe.mdDocumentation stub for the System.JavaScript PAL library.
src/native/libs/System.JavaScript/CMakeLists.txtCMake target for System.JavaScript static lib and temporary JS asset installation.
src/native/libs/System.JavaScript.Runtime/dotnet.runtime.jsMinimal placeholder runtime JS module to satisfy build.
src/native/libs/System.JavaScript.Runtime/ReadMe.mdDocumentation stub for the runtime module.
src/native/libs/System.JavaScript.Loader/dotnet.jsLoader/host ES module orchestrating runtime/wasm and assembly loading for browser/NodeJS.
src/native/libs/System.JavaScript.Loader/ReadMe.mdDocumentation stub for the loader module.
src/native/libs/Common/JavaScript/types/index.tsBarrel for shared type definitions.
src/native/libs/Common/JavaScript/types/emscripten.tsType definitions for Emscripten Module and pointers.
src/native/libs/Common/JavaScript/common/index.tsPlaceholder for shared helpers.
src/native/libs/Common/JavaScript/ReadMe.mdDocumentation for shared types/helpers.
src/native/libs/CMakeLists.txtIncludes new JS libs for browser target builds.
src/native/libs/.eslintrc.cjsESLint configuration for TS/JS.
src/native/libs/.eslintignoreIgnore generated and JS files for linting.
src/native/corehost/browser/native.rcWindows resource file for host.
src/native/corehost/browser/main.mjsSimple NodeJS/browser host entrypoint (demo).
src/native/corehost/browser/libBrowserHost.jsEmscripten library exposing browser host callbacks and initializing DOTNET/interop.
src/native/corehost/browser/index.htmlMinimal HTML for browser demo.
src/native/corehost/browser/dotnet.boot.jsDemo asset manifest for browser boot.
src/native/corehost/browser/configure.cmakeConfigure checks and generated config header.
src/native/corehost/browser/config.h.inGenerated config header template.
src/native/corehost/browser/browserhost.cppCoreCLR bootstrapper using host runtime contract for JS/browser scenario.
src/native/corehost/browser/CMakeLists.txtCMake target for browserhost, linking JS libraries and setting emscripten flags.
src/installer/pkg/sfx/Microsoft.NETCore.App/Directory.Build.propsAdds new native libs to platform manifest.
src/coreclr/vm/wasm/helpers.cppRemoves temporary stub now provided by JS PAL.
src/coreclr/vm/CMakeLists.txtAdds include paths for new JS libs on browser builds.
src/coreclr/hosts/corewasmrun/CMakeLists.txtLinks System.JavaScript lib into corewasmrun.
src/coreclr/hosts/corerun/libCorerun.pre.jsPre-run script to copy Node env vars into Emscripten ENV.
src/coreclr/hosts/corerun/corerun.jsRemoves old pre-js; replaced by libCorerun.pre.js.
src/coreclr/hosts/corerun/CMakeLists.txtWires new pre-js and System.JavaScript lib when targeting browser.
src/coreclr/CMakeLists.txtAdds browserhost build and dependency for browser target.
eng/pipelines/common/evaluate-default-paths.ymlEnsures CI path filters include new JS/browser-host folders.
docs/workflow/building/coreclr/wasm.mdAdds VS Code NodeJS launch config for browserhost demo.

Comment threadsrc/native/libs/System.JavaScript/libSystem.JavaScript.js Outdated
Comment threadsrc/native/libs/System.JavaScript.Loader/dotnet.js Outdated
Comment threadsrc/native/libs/System.JavaScript.Loader/dotnet.js Outdated
Comment threadsrc/native/libs/System.JavaScript.Loader/dotnet.js Outdated
Comment threadsrc/native/corehost/browser/main.mjs Outdated
Comment threadsrc/native/libs/System.Runtime.InteropServices.JavaScript/ReadMe.md Outdated
Comment threadsrc/native/libs/System.JavaScript/ReadMe.md Outdated
Comment threadsrc/native/libs/System.JavaScript.Runtime/ReadMe.md Outdated
Comment threadsrc/native/libs/rollup.config.js Outdated
@pavelsavara

Copy link
Copy Markdown
MemberAuthor

This is ready for initial feedback.
The feedback I'm seeking is directory structure and naming.
The PR also has new summary in top description.

I'm also working on much nicer TypeScript version, but it needs more of my work.

Comment threadsrc/native/libs/System.Native.Browser/ReadMe.md Outdated
Comment threadsrc/native/libs/System.Native.Browser/ReadMe.md Outdated
Comment threadsrc/native/libs/System.Native.Browser/ReadMe.md Outdated
Comment threadsrc/native/libs/System.Native.Browser/ReadMe.md Outdated
Comment threadsrc/native/libs/System.JavaScript.Loader/ReadMe.md Outdated
Comment threadsrc/native/corehost/browserhost/browserhost.cpp Outdated
Comment threadsrc/native/corehost/browserhost/browserhost.cpp
Comment threadsrc/native/corehost/browserhost/browserhost.cpp
Comment threadsrc/native/corehost/browserhost/libBrowserHost.js
Comment threadsrc/native/corehost/browserhost/libBrowserHost.js
Comment threadsrc/native/corehost/browserhost/libBrowserHost.js Outdated
Comment threadsrc/native/corehost/browserhost/libBrowserHost.js Outdated
Comment threadsrc/native/corehost/browserhost/libBrowserHost.js Outdated
Comment threadsrc/native/corehost/browserhost/libBrowserHost.js
Comment threadsrc/native/corehost/browserhost/libBrowserHost.js
Comment threadsrc/native/corehost/browserhost/sample/dotnet.boot.js Outdated
Comment threadsrc/native/rollup.stub.js
@kg

kg commented Sep 22, 2025

Copy link
Copy Markdown
Contributor

The parts I understand look pretty good.

Comment threaddocs/workflow/building/coreclr/wasm.md Outdated
@pavelsavara
pavelsavara merged commit f375b41 into dotnet:mainSep 23, 2025
165 of 167 checks passed
@pavelsavara
pavelsavara deleted the wasm_singlefilehost branch September 23, 2025 16:51
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Oct 24, 2025
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-Hostos-browserBrowser variant of arch-wasm

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[browser] reinvent internal JS interfaces between modules

8 participants

@pavelsavara@jkotas@kg@radekdoulik@maraf@janvorli@SingleAccretion