Skip to content

feat: allow extending hyperlight-js-runtime with custom native modules#49

Open
simongdavies wants to merge 2 commits intohyperlight-dev:mainfrom
simongdavies:extend-runtime-with-native-modules
Open

feat: allow extending hyperlight-js-runtime with custom native modules#49
simongdavies wants to merge 2 commits intohyperlight-dev:mainfrom
simongdavies:extend-runtime-with-native-modules

Conversation

@simongdavies
Copy link
Contributor

@simongdavies simongdavies commented Mar 12, 2026

Resolves #48

Add a registration-based system for extending the JS runtime with custom native (Rust-implemented) modules that run inside the Hyperlight guest VM. Also allows extending the available global JS Objects

Key changes:

  • hyperlight-js-runtime/Cargo.toml: Add [lib] target so the runtime can be used as a library dependency by extender crates.

  • modules/mod.rs: Add global CUSTOM_MODULES registry with register_native_module() and builtin_module_names(). NativeModuleLoader checks custom registry first, falls back to built-in modules. Panics if custom module name conflicts with a built-in.

  • native_modules! macro: Generates init_native_modules() (#[no_mangle]) that registers custom modules. Called automatically via spin::Once on first NativeModuleLoader access — no explicit init needed.

  • guest/mod.rs: Move hyperlight guest entry point (hyperlight_main, guest_dispatch_function, Host impl, stubs) from main/hyperlight.rs into the lib behind cfg(hyperlight). Extender binaries get all guest infrastructure for free by depending on the lib.

  • hyperlight-js/build.rs: Add HYPERLIGHT_JS_RUNTIME_PATH env var override to embed custom runtime binaries instead of the default.

  • host.rs: Restore original Host trait only (no FsHost extraction).

  • New custom_globals! macro in modules/mod.rs (same #[no_mangle] + extern

  • setup_custom_globals() bridge called in JsRuntime::new() after
    built-in globals

  • Default empty custom_globals! {} in base runtime main.rs

Testing:

  • 19 unit/integration tests in hyperlight-js-runtime (loader, registry, macro, override prevention, E2E with native CLI fixture binary)
  • Test fixture with globalThis.CUSTOM_GLOBAL_TEST = 42
  • 3 Hyperlight VM integration tests in hyperlight-js (#[ignore], run via just test-native-modules)
  • Extended runtime fixture crate with shared native_math module
  • just test-native-modules recipe for full hyperlight pipeline

Docs:

  • docs/extending-runtime.md with quick start, host-side usage, native testing, API reference, and architecture diagram

@simongdavies simongdavies added the kind/enhancement New feature or improvement label Mar 12, 2026
@simongdavies simongdavies force-pushed the extend-runtime-with-native-modules branch 8 times, most recently from acaa72b to d721317 Compare March 14, 2026 08:56
Resolves hyperlight-dev#48

Add a registration-based system for extending the JS runtime with custom
native (Rust-implemented) modules that run inside the Hyperlight guest VM.

Key changes:

- hyperlight-js-runtime/Cargo.toml: Add [lib] target so the runtime can
  be used as a library dependency by extender crates.

- modules/mod.rs: Add global CUSTOM_MODULES registry with
  register_native_module() and builtin_module_names(). NativeModuleLoader
  checks custom registry first, falls back to built-in modules. Panics
  if custom module name conflicts with a built-in.

- native_modules! macro: Generates init_native_modules() (#[no_mangle])
  that registers custom modules. Called automatically via spin::Once on
  first NativeModuleLoader access — no explicit init needed.

- guest/mod.rs: Move hyperlight guest entry point (hyperlight_main,
  guest_dispatch_function, Host impl, stubs) from main/hyperlight.rs
  into the lib behind cfg(hyperlight). Extender binaries get all guest
  infrastructure for free by depending on the lib.

- hyperlight-js/build.rs: Add HYPERLIGHT_JS_RUNTIME_PATH env var override
  to embed custom runtime binaries instead of the default.

- host.rs: Restore original Host trait only (no FsHost extraction).

Testing:
- 13 unit/integration tests in hyperlight-js-runtime (loader, registry,
  macro, override prevention, E2E with native CLI fixture binary)
- 3 Hyperlight VM integration tests in hyperlight-js (#[ignore], run via
  just test-native-modules)
- Extended runtime fixture crate with shared native_math module
- just test-native-modules recipe for full hyperlight pipeline

Docs:
- docs/extending-runtime.md with quick start, host-side usage, native
  testing, API reference, and architecture diagram
@simongdavies simongdavies force-pushed the extend-runtime-with-native-modules branch from d721317 to 3e43831 Compare March 14, 2026 10:12
Add custom_globals! macro alongside native_modules! to allow extender
crates to register global JS objects (TextEncoder, TextDecoder,
polyfills, constants) without modifying hyperlight-js-runtime.

- New custom_globals! macro in modules/mod.rs (same #[no_mangle] + extern
- setup_custom_globals() bridge called in JsRuntime::new() after
  built-in globals
- Default empty custom_globals! {} in base runtime main.rs
- Test fixture with globalThis.CUSTOM_GLOBAL_TEST = 42
- 6 new tests: unit e2e + full pipeline (standalone, coexist with
  builtins, combined with native modules)
- Documentation in docs/extending-runtime.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/enhancement New feature or improvement

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow extending hyperlight-js-runtime with custom native modules

1 participant