I'm trying to transpile a WASM file to JavaScript. wasm2js can't handle BigInt imports to WASM from JavaScript. jco transpile expects a WebAssembly Component. wasm-tools doesn't convert the core WASM module into a component due to env import from JavaScript.
Is there a WASM to JavaScript transpiler that supports BigInt imports from JavaScript?
i do not know. may i ask the very ignorant question, why compile wasm to js? where is there js but no wasm
also if i may ask, what toolchain are you using that uses bigint imports? i would like to prepare a proposal à la js string builtins for bigints at some point, and i would like to collect users :)
(i realize that neither of these questions bring you closer to answering your own question; apologies :sweat_smile: )
I'm trying to port code originally written in Zig to JavaScript.
Currently the WASM looks like this. There are a couple other places in the code that uses BigInt.
const { instance } = await WebAssembly.instantiate(wasmBytes, {
env: {
get_time_ns: () => BigInt(Math.round(performance.now() * 1_000_000)),
console_log: (ptr, len) => {
const bytes = new Uint8Array(inst.exports.memory.buffer, ptr, len);
console.log("[wasm]", new TextDecoder().decode(bytes));
},
random_fill: (ptr, len) => {
crypto.getRandomValues(
new Uint8Array(inst.exports.memory.buffer, ptr, len),
);
},
},
});
Why do you need to have plain js as output rather than wasm + js glue? Do you want to run it on some old js engine that doesn't support wasm yet or something?
bjorn3 said:
Why do you need to have plain js as output rather than wasm + js glue? Do you want to run it on some old js engine that doesn't support wasm yet or something?
Because I'm trying to port QUIC, TLS, and WebTransport server implementation to JavaScript proper.
These each of these
use Node.js Addons for C++ and Rust source code execution.
This is a JavaScript implementation of QUIC/HTTP3 doesn't work as expected; doesn't send messages back to client
This _does_ work as expected using WebAssembly
The target is not just the browser, it's the JavaScript programming language at large. AFAIK nobody has created a QUIC/HTTP/3/WebTransport implementation in only JavaScript that works as expected.
I figured it out
const env = {
// 1. Move the variable inside the object
tempRet0: 0,
// 2. Use method shorthand to allow 'this' access
setTempRet0(val) {
this.tempRet0 = val | 0;
},
getTempRet0() {
return this.tempRet0 | 0;
},
get_time_ns() {
const nowNs = BigInt(Math.round(performance.now() * 1e6));
const low = Number(nowNs & 0xFFFFFFFFn) | 0;
// Update the internal state
this.tempRet0 = Number(nowNs >> 32n) | 0;
return low;
},
console_log(ptr, len) {
const bytes = new Uint8Array(mem.buffer, ptr, len);
const msg = decoder.decode(bytes);
console.log(msg);
},
random_fill(ptr, len) {
const bytes = new Uint8Array(mem.buffer, ptr, len);
crypto.getRandomValues(bytes);
},
};
const retasmFunc = asmFunc({
env,
});
const mem = retasmFunc.memory;
function bigIntToi32(bigInt) {
const bId = BigInt(bigInt);
const low = Number(bId & 0xFFFFFFFFn) | 0;
const high = Number(bId >> 32n) | 0;
return {
low,
high,
};
}
const instance = {
exports: {
...retasmFunc,
qz_wt_accept_session: (sessionId) => {
const {
low,
high,
} = bigIntToi32(sessionId);
return retasmFunc.qz_wt_accept_session(low, high);
},
qz_wt_read_stream: (streamId, outPtr, outLen) => {
const {
low,
high,
} = bigIntToi32(streamId);
return retasmFunc.qz_wt_read_stream(low, high, outPtr, outLen);
},
qz_wt_send_stream: (streamId, dataPtr, len) => {
const {
low,
high,
} = bigIntToi32(streamId);
return retasmFunc.qz_wt_send_stream(low, high, dataPtr, len);
},
qz_wt_close_stream: (streamId) => {
const {
low,
high,
} = bigIntToi32(streamId);
return retasmFunc.qz_wt_close_stream(low, high);
},
qz_wt_send_datagram: (sessionId, dataPtr, len) => {
const {
low,
high,
} = bigIntToi32(sessionId);
return retasmFunc.qz_wt_send_datagram(low, high, dataPtr, len);
},
qz_wt_close_session: (sessionId, errorCode, reasonPtr, reasonLen) => {
const {
low,
high,
} = bigIntToi32(sessionId);
return retasmFunc.qz_wt_close_session(
low,
high,
errorCode,
reasonPtr,
reasonLen,
);
},
},
};
Last updated: Apr 13 2026 at 00:25 UTC