Skip to content

Commit cd6829d

Browse files
committed
Update Docs
Signed-off-by: Simon Davies <simongdavies@users.noreply.github.com>
1 parent 0085e42 commit cd6829d

File tree

1 file changed

+103
-6
lines changed

1 file changed

+103
-6
lines changed

docs/extending-runtime.md

Lines changed: 103 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,20 +74,30 @@ libc stubs) — no copying files or build scripts needed.
7474

7575
### 3. Build and embed in hyperlight-js
7676

77-
Set `HYPERLIGHT_CFLAGS` before building. The hyperlight target has no libc —
78-
QuickJS needs the stub headers from `hyperlight-js-runtime/include/` and
79-
`-D__wasi__=1` to disable pthreads.
77+
The hyperlight target has no libc, so QuickJS needs stub headers from
78+
`hyperlight-js-runtime/include/` and `-D__wasi__=1` to disable pthreads.
79+
Set `HYPERLIGHT_CFLAGS` before building — the one-liner below uses
80+
`cargo metadata` to resolve the include path from your dependency tree:
8081

8182
```bash
83+
# Resolve CFLAGS from hyperlight-js-runtime's include/ directory
8284
export HYPERLIGHT_CFLAGS=$(node -e "
8385
var m=JSON.parse(require('child_process').execSync(
8486
'cargo metadata --format-version 1 --manifest-path my-custom-runtime/Cargo.toml',
85-
{encoding:'utf8',stdio:['pipe','pipe','pipe']}));
87+
{encoding:'utf8',stdio:['pipe','pipe','pipe'],maxBuffer:20*1024*1024}));
8688
var p=m.packages.find(function(p){return p.name==='hyperlight-js-runtime'});
87-
console.log('-I'+require('path').join(require('path').dirname(p.manifest_path),'include')+' -D__wasi__=1');
89+
if(p)console.log('-I'+require('path').join(
90+
require('path').dirname(p.manifest_path),'include')+' -D__wasi__=1');
8891
")
8992

90-
cargo hyperlight build --manifest-path my-custom-runtime/Cargo.toml
93+
# Build the custom runtime for the hyperlight target
94+
cargo hyperlight build --manifest-path my-custom-runtime/Cargo.toml --release
95+
96+
# Tell hyperlight-js to embed the custom runtime (not the default one)
97+
export HYPERLIGHT_JS_RUNTIME_PATH=my-custom-runtime/target/x86_64-hyperlight-none/release/my-custom-runtime
98+
99+
# Rebuild hyperlight-js so the embedded runtime is updated
100+
cargo build -p hyperlight-js --release
91101
```
92102

93103
### 4. Use from the host
@@ -178,6 +188,93 @@ for a working example with end-to-end tests.
178188
Run `just test-native-modules` to build the fixture for the Hyperlight
179189
target and run the full integration tests.
180190

191+
## Using js-host-api from a Downstream Node.js Project
192+
193+
If your downstream project depends on `@hyperlight/js-host-api` (the
194+
Node.js NAPI addon) and uses a custom runtime, you **cannot** use a
195+
published version of the addon — the published binary has the default
196+
runtime baked in via `include_bytes!()`. You need to build the NAPI
197+
addon from source with your custom runtime embedded.
198+
199+
### Why not just `npm install`?
200+
201+
The `js-host-api` NAPI addon links against the `hyperlight-js` Rust crate,
202+
which embeds the runtime binary at compile time. A published npm package
203+
would contain a `.node` binary with the **default** runtime — your custom
204+
native modules wouldn't be present.
205+
206+
### The pattern: reuse Cargo's git checkout
207+
208+
Your custom runtime crate already has a Cargo dependency on
209+
`hyperlight-js-runtime`, which causes Cargo to clone the full
210+
`hyperlight-js` workspace into `~/.cargo/git/checkouts/`. The
211+
`js-host-api` NAPI source is included in that checkout — no separate
212+
git clone needed.
213+
214+
#### 1. Discover the checkout path
215+
216+
Use `cargo metadata` to find where Cargo placed the hyperlight-js
217+
workspace:
218+
219+
```bash
220+
HYPERLIGHT_DIR=$(node -e "
221+
var m=JSON.parse(require('child_process').execSync(
222+
'cargo metadata --format-version 1 --manifest-path my-custom-runtime/Cargo.toml',
223+
{encoding:'utf8',stdio:['pipe','pipe','pipe'],maxBuffer:20*1024*1024}));
224+
var p=m.packages.find(function(p){return p.name==='hyperlight-js-runtime'});
225+
if(p)console.log(require('path').resolve(
226+
require('path').dirname(p.manifest_path),'..','..'));
227+
")
228+
echo "$HYPERLIGHT_DIR"
229+
# e.g. /home/you/.cargo/git/checkouts/hyperlight-js-abc123/def456
230+
```
231+
232+
#### 2. Build the NAPI addon with your custom runtime
233+
234+
```bash
235+
# Set HYPERLIGHT_CFLAGS for the guest build
236+
export HYPERLIGHT_CFLAGS=$(node -e "
237+
var m=JSON.parse(require('child_process').execSync(
238+
'cargo metadata --format-version 1 --manifest-path my-custom-runtime/Cargo.toml',
239+
{encoding:'utf8',stdio:['pipe','pipe','pipe'],maxBuffer:20*1024*1024}));
240+
var p=m.packages.find(function(p){return p.name==='hyperlight-js-runtime'});
241+
if(p)console.log('-I'+require('path').join(
242+
require('path').dirname(p.manifest_path),'include')+' -D__wasi__=1');
243+
")
244+
245+
# Build your custom runtime for the hyperlight target
246+
cargo hyperlight build --manifest-path my-custom-runtime/Cargo.toml --release
247+
248+
# Point hyperlight-js at your custom runtime binary
249+
export HYPERLIGHT_JS_RUNTIME_PATH=my-custom-runtime/target/x86_64-hyperlight-none/release/my-custom-runtime
250+
251+
# Clean stale builds so build.rs re-embeds the runtime
252+
cd "${HYPERLIGHT_DIR}/src/hyperlight-js" && cargo clean -p hyperlight-js
253+
254+
# Build the NAPI addon from the Cargo checkout
255+
cd "${HYPERLIGHT_DIR}" && just build release
256+
```
257+
258+
#### 3. Symlink for npm dependency resolution
259+
260+
Create a symlink so npm can resolve the addon via a stable path:
261+
262+
```bash
263+
mkdir -p deps
264+
ln -sfn "${HYPERLIGHT_DIR}/src/js-host-api" deps/js-host-api
265+
```
266+
267+
In your package.json, point to js-host-api via the symlink:
268+
269+
```json
270+
{
271+
"dependencies": {
272+
"@hyperlight/js-host-api": "file:deps/js-host-api"
273+
}
274+
}
275+
```
276+
Make sure to add `deps` to your `.gitignore` since it's a symlink to a local Cargo checkout.
277+
181278
## API Reference
182279

183280
### `native_modules!`

0 commit comments

Comments
 (0)