Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PROPOSAL] Integrate Napi.rs to TSC to gradually migrate to Rust 🦀 #60480

Closed
wants to merge 1 commit into from

Conversation

markmssd
Copy link

@markmssd markmssd commented Nov 12, 2024

This PR is to contribute a suggestion, showcasing a working code example. It is not meant to be merged.

The web development ecosystem has evolved a lot, moving towards faster technologies, usually Rust or Golang. For example, Turbopack, Rspack, swc or esbuild (already used in this repo).

Unfortunately, those projects can only compile Typescript, not type check. Type checking remains a problem in large projects due to its performance.

There have been attempts at rewriting the TSC type checker in Rust, mainly by the well known @kdy1, creator of SWC, with the https://github.com/dudykr/stc project. However, keeping up with the Typescript changes is no easy task.

For this proposal, I use NAPI-RS directly in the Typescript repo, allowing us to gradually migrate the codebase to Rust. This is of course easier said than done, but I believe if the hot paths were migrated, it could already give a great performance boost.

This example is fully working, as you can see all the checks passing. I have only migrated 2 methods, escapeLeadingUnderscores and unescapeLeadingUnderscores, for the sake of demonstration. They are implemented in lib.rs, and running npm run build:napi will create rs.js and rs.d.ts files, allowing JS code to call them directly.

I'd love to hear your thoughts with such a solution. If there is interest, I can open another PR which would integrate it properly (using Hereby) and have all CI workflows passing.

PS: 2 CI workflows are failing, mostly due to configuration that needs to be tweaked, but npm test passes successfully for Linux, Windows, and MacOS.

@typescript-bot typescript-bot added the For Uncommitted Bug PR for untriaged, rejected, closed or missing bug label Nov 12, 2024
@markmssd
Copy link
Author

@microsoft-github-policy-service agree

rust ci

format

ci rust

mkdir built/local

install with older npm version

fix more ci

keep js

dummy run

run coverage conditionally

delete `rs.ts`

fix smoke

`escape_leading_underscores` and `unescape_leading_underscores`

format

fix ts?

run cargo tests

ls -a

revert

Revert "run cargo tests"

This reverts commit 57e29ad.

Revert "ls -a"

This reverts commit 904845a.

test:napi in ci

add as binary

rm rs binary

copy .node into lib

format

bins

rm rust tests
@asukaminato0721
Copy link

infamous: well known for some bad quality.

I guess you want to say: not famous?

@MartinJohns
Copy link
Contributor

This would prevent dogfooding.

@RyanCavanaugh
Copy link
Member

RyanCavanaugh commented Nov 12, 2024

This is of course easier said than done, but I believe if the hot paths were migrated, it could already give a great performance boost.

We've investigated this multiple times and it doesn't really work as you'd hope. The overhead from Napi.rs <-> JS is still higher than a monomorphic JS <-> JS call, and there is no singular "hot path" you can optimize (most time is spent in the checker where the call graph can and does go anywhere in checker.ts). Believe me, if you could get perf gains out of this, we'd have done it already.

@markmssd
Copy link
Author

Thanks for the clear explanation @RyanCavanaugh ! That's exactly what I was afraid of, but I was hoping that the Rust performance boost would compensate for the overhead. For example, I see in the NAPI-RS docs that using JsBuffer:

Passing data between JavaScript and Rust using JsBuffer has a small overhead so you might prefer it over other types.

I didn't compare it in my PoC though. I might try to convert more util functions to Rust and try it out when I get more time. I'm going to close the PR now, but at least the working code remains if it's ever reconsidered in the future!

@markmssd markmssd closed this Nov 13, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Uncommitted Bug PR for untriaged, rejected, closed or missing bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants