Skip to content

TypeScript Core#8861

Open
chharvey wants to merge 4 commits into
WebAssembly:mainfrom
chharvey:feat/ts-core
Open

TypeScript Core#8861
chharvey wants to merge 4 commits into
WebAssembly:mainfrom
chharvey:feat/ts-core

Conversation

@chharvey

@chharvey chharvey commented Jun 19, 2026

Copy link
Copy Markdown
Contributor

The first of several PRs in an attempt to break up #8826 into smaller parts. This PR sets up core typescript functionality and ports over only the top-level types, constants, and enums of the JS API.

Changes:

  • adds root-level ts/ folder with README.md, package.json, tsconfig.json, and other project files
  • updates root-level CMakeLists.txt, exporting needed variables & methods (like HEAP8) from Emscripten into the JS build
  • ts/src/-pre.ts imports the Emscripten-built Binaryen function, calls and awaits it, and exports that as an internal object called BinaryenObj (AssemblyScript calls this object binaryen and exports that publicly).
  • ts/src/**: the typescript library sits on top of the Emscripten artifact. it accesses the WASM bindings on BinaryenObj imported from -pre.ts.
  • entrypoint ts/src/binaryen.ts for users, exporting all the parts of the public-facing API. Users use a namespace import instead of a default import:
    import * as binaryen from "binaryen.ts";
    
    (this better aligns with the ES Modules standard since it’s no longer a proper object).
    users will still use the same API (binaryen.ExpressionRef, binaryen.i32, binaryen.Module, etc.)
  • starting some Node.JS tests at ts/tests/. hopefully this will take some of the weight off the python tests

Non-Changes:

  • original binaryen.js-post.js file has not been touched; the tentative plan is to complete the TS migration before phasing out the JS code (unless decided otherwise by repo maintainers)
  • python tests also haven’t been touched for now, but maybe a future PR will work on migrating them to Node.JS

API Deprecations (see ts/src/-deprecations.ts for full list; will evolve with more PRs):

  • enum names have been singularized (e.g. binaryen.Featuresbinaryen.Feature)
  • deprecations are still accessible as their old symbols (users can still use binaryen.Features, but there is a doc-comment @deprecated warning for intellisense support)

Get started:

brew install node # includes npm
cd ts/
npm ci          # downloads dependencies
npm run make    # rebuilds out-of-tree into ../build/ and copies the built js to ./build/
npm run check   # runs the python tests
npm run compile # compiles typescript to ./dist/
npm run test    # runs the node tests

See ts/package.json, ts/README.md, and ts/docs/API-Overview.md (in this PR) for details.

@chharvey chharvey requested a review from a team as a code owner June 19, 2026 02:09
@chharvey chharvey requested review from tlively and removed request for a team June 19, 2026 02:09
Comment thread ts/package.json
"packageManager": {
"name": "npm"
}
}

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.

Very strange choice. How about simply "version": ">= 20"?

@chharvey chharvey Jun 21, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Node.JS has this unusual convention that odd-numbered versions are not stable and become unsupported after 6 months. Only even-numbered versions receive continued long-term support (bugfixes & security updates) after ‘current’ development, which is why i put "^20 || ^22 || ^24 || ^26".

Luckily this is about to change starting in v27 (planned April 2027) where:

Starting with Node.js 27, the release cycle will be annual and every major version will move to LTS status after its six-month Current phase (and six additional months of Alpha phase).

@MaxGraey MaxGraey Jun 21, 2026

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.

Setting a minimum version is pretty standard practice. You do it once and then forget about it. In your case, though, you'll need to update the list every time a new major node.js version comes out! And why does it matter whether the version is stable or not stable? It doesn't suddenly break anything.

In addition, there are users who rarely update, while others use only the latest version of node (which may not be included in that list).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fair enough, and agreed, it'd be better to set it once and only update once a version reaches end-of-life. I'll set the minimum to >= 22

Comment thread CMakeLists.txt
target_link_libraries(binaryen_js PRIVATE "-sEXPORT_ES6")
endif()
target_link_libraries(binaryen_js PRIVATE "-sEXPORTED_RUNTIME_METHODS=stringToUTF8OnStack,stringToAscii,getExceptionMessage")
target_link_libraries(binaryen_js PRIVATE "-sEXPORTED_RUNTIME_METHODS=out,err,HEAP8,HEAPU8,HEAP32,HEAPU32,stackSave,stackRestore,stackAlloc,UTF8ToString,stringToAscii,stringToUTF8OnStack,getExceptionMessage")

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.

Why we need extended exported symbols? I haven't seen them being used. Also js-bindings works without all of them normally.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Most of these symbols aren't needed in this PR but they will be needed in future code migration (example links below are from #8826):

  • out will be used in emitAsmJS
  • i can remove err, looks like it's not used in the TS anywhere
  • all the heaps are used in various functions, e.g.:
  • stackSave, stackRestore, and stackAlloc will be needed in utilities
  • UTF8ToString, stringToAscii, and stringToUTF8OnStack for anything using javascript strings (e.g. parseText)

The reason the JS bindings work without them is because the current post.js file is appended to (i think) the WASM bindings before Emscripten processes them; that's the --post-js flag given on line 562. that's why the JS code is able to access the symbols in Emscripten's codebase without being exported. but now that the Emscripten build happens before calling await Binaryen(), we need those symbols exported on the object, so they need to be added to EXPORTED_RUNTIME_METHODS. (see the comment in binaryen_js.d.ts

@chharvey

Copy link
Copy Markdown
Contributor Author

TODO:

  • package.json: update engines.node and devEngines.runtime.version to ">= 22"
  • remove err from EXPORTED_RUNTIME_METHODS and accordingly in binaryen_js.d.ts, -pre.ts, & node tests

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants