denoland / deno

A modern runtime for JavaScript and TypeScript.
https://deno.com
MIT License
94.05k stars 5.23k forks source link

TypeScript compiler in Rust #5432

Closed kitsonk closed 3 months ago

kitsonk commented 4 years ago

This is long, but please read before you comment. If you are interested in following this, use the subscribe button to the right instead of just adding a comment.

Since the Deno v1 announcement there has been a lot of community interest in the TypeScript compiler in Rust that was mentioned. This issue is intended to provide information on that. First a few points:

The Problem

We need a bit of context of what problem we are really trying to solve here. Type checking, especially with a structural type system built on top of a weakly typed underlying language, is expensive. As TypeScript as a language has grown, and the type checking become more and more advanced and safe, means that it is increasingly "expensive" to do this type of checking. Deno treats TypeScript as a first class language. At the moment Deno also always runs TypeScript through the TypeScript compiler and treats any type errors as it would treat a JavaScript runtime error.

This is "expensive". If you look at Deno benchmarks you will see that there is currently a cost of about 10x just spinning up the compiler to get some TypeScript transpiled into JavaScript.

Benchmarks_-_Deno

We have tried a few things to improve that, but there is still a big cost, and we want to try to narrow that gap significantly. For other things in Deno we have had really good experience in moving to Rust things we used to do in JavaScript. There are several reasons for the performance improvement, but the most compelling is that it is just plain easier to get performant code in Rust. If you resort to non-obvious structures in JavaScript, you can often get lots of performance from v8, but it is really really really hard work. Our text encoder is an example. We started with a spec complaint implementation, following the structures laid out in the IDL. It was abysmal performance. We then implemented a fairly "magical" non-obvious implementation in JavaScript/TypeScript which dramatically increased performance, but that wasn't even enough, we got eve more performance moving that to Rust, with even the overhead of "copying" that data in and out of the JS sandbox is faster than what we could get out of heavily optimised JavaScript. Could we have gotten more out of our JS implementation... maybe... but it just gets too hard.

How does it work today?

I realise a lot of folks might not understand well where we are at today, so some background context is helpful. It sort of works like this...

How the CLI is put together

"Running" TypeScript code

Loading JavaScript into the isolate

The Approach

Ok, so what do we do about it. The discussion I have had on the subject with various people have always been about an evolutionary approach. Also this approach is what I personally feel is right for Deno. Solving everyone's problems is tough, but if solving Deno's problems helps out everyone else 🥳.

Here are the major items that I think we need to tackle, and likely in the order presented here:

Bnaya commented 4 years ago

I'm not sure how feasible to integrate with deno, but tsc have the incremental flag to speedup re runs, or spin up language server and keep it alive https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#faster-subsequent-builds-with-the---incremental-flag
https://github.com/microsoft/TypeScript/wiki/Using-the-Compiler-API#incremental-build-support-using-the-language-services

dsherret commented 4 years ago

@Bnaya see https://github.com/denoland/deno/pull/5094

kitsonk commented 4 years ago

Thanks @dsherret. Yes it might speed up big projects where there are incremental changes. Once we get to the point where we are only type checking in the compiler (I guess it really becomes the "type checker" at that point) we would want to see if incremental compiles would help.

matklad commented 4 years ago

it may not perform that much faster

I think there's a possibility that perf gains here would be substantial, for two reasons.

First, tsc is a compiler geared towards interactive IDE/LSP server use-case. My experience as an author of such IDE tooling tells me that this has non-trivial perf implications (pervasive lazyness, lossless-ish syntax trees, and the tax of additional complexity). By shifting focus to batch compilation, it should be possible to simplify and speed-up things on the architecture level.

Second, while type-checking can't really benefit from something like simd, there's still a lot that can be gained by using a language with full control over data layout. Type checking is mostly pointer chasing and cache invalidation, and having tightly packed arena-allocated data structures helps a lot. HashMap performance is also super important. Sorbet, the typechecker for Ruby, was written in C++ for these reasons (some info 1, 2).

The fact that type-checking could be made faster at significant dev cost, of course doesn't necessary mean that it should. --no-type-check for running tests and tsc in your IDE for on-the-fly type checking seem to be cost/benefit sweet spot.

kitsonk commented 4 years ago

@matklad thanks for the feedback and thoughts.

Your second point is really interesting. There might be some data structures, or operations that are simply not performant. Because of the legacy of the compiler, evolving over a language that has moved a lot, and not specifically optimised for the engine it primarily runs in (v8), there could actually be a lot of ground to be gained in making sure the performance of the data structures is optimised.

TypeScript core team, for lots of valid reasons, is never going to move off of building the compiler in TypeScript. Therefore my biggest fear is the while getting 100% syntax parity is "easy" getting 100% type checking parity would be hard or impossible. That is why I am hopeful that the long road to get there means we may never get to the final destination.

@95th that is effectively what we are talking about here.

znck commented 4 years ago

esbuild can be used for transpiling typescript without type checking.

kitsonk commented 4 years ago

@znck esbuild is built in Go and is not designed to be embeddable... It offers no advantages over swc which is built in Rust and which we have already integrated in Deno.

elektronik2k5 commented 4 years ago

Go is an implementation detail and shouldn't matter. Quoting @evanw, esbuild's author:

The Go code in this repo isn't intended to be built upon. Go is just an implementation detail of how I built this tool. The stable interfaces for this project are the command-line API and the JavaScript API, not the internal Go code. I'm may change the internals in a backwards-incompatible way at any time to improve performance or introduce new features.

The real issue IMHO is that esbuild doesn't (currently) support decorators - so that's a show stopper.

I also recently learned about sucrase, which seems substantially faster than swc. Should we consider it?

kitsonk commented 4 years ago

@elektronik2k5 it matters if you are thinking of leveraging it. Why port something to Rust when we already have something that does exactly the same thing, written in Rust? That just doesn't make sense. Plus esbuild's focus is on being a bundler, Deno's need is for single file asynchronous transforms.

Sucrase's what it is not would likely not be suitable based on its own statements: https://github.com/alangpierce/sucrase#what-sucrase-is-not. In particular it does not transform decorators, saying it needs to be supported by your runtime, but there are no runtimes that support decorators. It also says itself that it isn't intended for production use. swc's metric comparison there is sort of obscured, because of the way swc is being used. We have yet to really baseline what swc could do. swc is significantly faster when it is targeting more modern versions of JavaScript then when it is targetting older version. The benchmark's on Sucrase's website don't really indicate what the configuration of swc was, nor what the inputs were. Coupled with the fact that all those stats are some obfuscated by using the Node.js APIs to orchestrate everything. Because we have already indicated swc, and aren't going to get rid of it any time soon, and we don't have any strong indication that it is going to be a performance barrier, it doesn't make sense to pursue Sucrase.

Also, all of these would only solve bullet point two, which is important but clearly not the whole picture. None of these solutions do type checking. They all just do type stripping and transforms. The bigger fish to fry is always how to improve the speed of the type checking.

apiel commented 4 years ago

As I mention in this issue https://github.com/denoland/deno/issues/6173 why not to give the possibility to the user to decide for their transpiler? Of course having by default a super efficient TS transpiler build-in inside Deno would be a huge advantage and would maybe be the reason of people switching from Node to Deno. But giving the possibility to give the choice to user to decide for their transpiler is an easy move and would also open the door to other programming language like dart, coffescript...

swc might be a great option but this would mean that we might not be up to date to the latest version of TypeScript. When a new TS version is release, we would first have to wait that swc update their code and then you could update Deno and finally user would have the latest version of TS. In the other way, if you give the users the chance to use their own transpiler, they could just pull the latest version of TSC and use it right away inside Deno, till the whole process from swc to Deno is done.

HKhademian commented 4 years ago

Rewriting typescript in rust can truly improve its speed and memory consumption but (a big one) separating deno typescript from main typescript development line can cause many problems:

  1. any bug fixes and ... must patched in rust code as another process which need additional maintainer.
  2. new features and improvement has delay to come in rust equivalent environment also in deno.
  3. rewriting may cause new errors and ... problems in its implementation.

All of those, at the end, cause deno to use an outdated and much bug-proof version of TypeScript, and I think it does not worth unless TypeScript maintainers decide to port entire language to Rust or any low level language.

But (another big one)

We can use tools like AssemblyScript,or any other similar tools to Compile/Convert latest versions of TypeScript's compiler with some little modifications to WebAssembly version and use its higher performance version.

Yes, I know, AssemblyScript is so young and ..., but we can put/redirect any required affords from TypeScript->Rust rewrite process to help these projects.

At last, yes Rust conversions are good if they don't have costs and problems, like V8 engine in rust, windows kernel in rust, Linux complete rewrite in rust, but are they possible for any projects that use these libraries? (I think it's not possible even for their main maintainer, unless use a progressive work to convert like what Mozilla team did in Firefox)

kitsonk commented 4 years ago

AssemblyScript (and Web Assembly) have come up a number times. Let's make it clear, it is not suitable. There are fundamental differences between how JavaScript and WebAssembly work. JavaScript is a garbage collected language, WebAssembly is a memory allocated language, like Rust and C++ is, where the code itself manages the language.

AssemblyScript makes it clear on their GitHub page: "Definitely not a TypeScript to WebAssembly compiler". It is similar to TypeScript, which makes it easier for those familiar with TypeScript to write Web Assembly, but it is not a general purpose TypeScript/JavaScript to WebAssembly compiler, which is what would be needed. Why isn't there a general purpose JavaScript to WebAssembly compiler? Because that is effectively v8 or any other JavaScript engine, which provides all the other infrastructure needed, like a highly tuned garbage collector, to be able to deal with general purpose JavaScript. Even if there was a general purpose JavaScript/TypeScript to WebAssembly compiler, it wouldn't speed up the code, for two reasons. First, Web Assembly is an abstraction on top of another language. In the case of v8, C++. C++ is abstracting WebAssembly from the underlying CPU, still morphing the op codes to something the native architecture of the CPU understands. The second is that v8 is really really really really good at optimising JavaScript, a lot better than some other compiler could be, and types don't significantly help with runtime performance of JavaScript (Google experimented with this a while ago, it effectively didn't work).

AssemblyScript is great, if you are a TypeScript developer, and you need to move a hot path out of JavaScript/TypeScript to WebAssembly. It is a lot lower overhead for you then having to learn Rust or C++. Which is an awesome thing. AssemblyScript is a really cool project.

So if we accept that converting the TypeScript compiler to WebAssembly is impossible and wouldn't work, why not move some of the hot paths AssemblyScript/WebAssembly? In Deno, we simply wouldn't do that. Why? Because as state before, WebAssembly is still an abstraction on top of another language, it is "cheap" and "easy" for us to right things in Rust, and native compiled Rust will always run faster than Rust to WebAssembly. Working around the limitations of AssemblyScript, for Deno, wouldn't make it any easier.

The wider community shouldn't worry, people are talking to each other. Since Deno was started there has been communication between the Deno team and the TypeScript core team. Like all groups of people, we don't always see eye-to-eye, that doesn't mean we can't have productive conversations about how to improve the things for everyone.

HKhademian commented 4 years ago

First of all, I know and said that everything in Rust is Fast (compair to JIT langs, but not even every nodeJS task!, suggest to watch Ashley Williams - How I Convinced the World's Largest Package Manager to Use Rust, and So Can You! from npm team) and Secure (memory-wise). It's a fact, an obvious one. But all I said is the Ideal transformation has some cost, issues and problems.

I see deno, as alternative to nodejs mess in future, but like every other thing in this world it has its own limited budget, eager followers, volunteer maintainers, ... . if deno maintainers spend big chunk of these resources where are not much important (compare to others), denos fate will be like WeWork and other prodigal ideas, platforms and services.

One of TypeScript compiler problems is it's boot time and JIT speed, we can (with some modification, maybe automatic ones) convert TypeScript compiler source code to make it compatible with tools like AssemblyScript then compile it to WASM or even find some tricks to use LLVM and generate native binaries for top used platforms (like Windows, Linux, MacOS, ...) to speed this part up and use main typescript compiler on other not supported platforms.

This conversion is fast (maybe some weeks to setup tools, develop solutions and CI/CD tasks and ...) and already available. It costs very low.

Even if we work together and reach our Ideal purpose (some day, full functional TypeScript Compiler in Rust), then we can switch to that better solution, till then we have our good temporary solution to TypeScript compiler's problem.

kitsonk commented 4 years ago

@HKhademian you are not understanding...

if deno maintainers spend big chunk of these resources where are not much important

I am glad you know what is and isn't important for us.

we can (with some modification, maybe automatic ones) convert TypeScript compiler source code to make it compatible with tools like AssemblyScript

This cannot be done, and even if it could it would run slower then it currently does.

This conversion is fast (maybe some weeks to setup tools, develop solutions and CI/CD tasks and ...) and already available. It costs very low.

Great, I await your proof of concept.

rezonant commented 4 years ago

Regardless of the WASM thing, I think @HKhademian has a point about the maintainability of such a solution, which is why I've watched this issue for some time somewhat worried about this Rust TS compiler plan. @kitsonk is the plan to rely on pulling in TS' automated test suites to ease tracking advancements in TS, or is there some other strategy long term?

rezonant commented 4 years ago

Apologies for the double post but I do want to also say that provided the TS specification is sufficiently detailed, it ultimately isn't inconceivable that multiple implementations of the language can be handled-- after all, it is commonly a sign of language maturity (and an insurance policy) when there are multiple distinct compiler implementations. But it will be a large effort. I do think it will be necessary to decouple this effort from Deno so you can get contributors who just want a faster TS compiler without losing some decent level of type checking.

kitsonk commented 4 years ago

Regardless of the WASM thing, I think @HKhademian has a point about the maintainability of such a solution,

Which I also extensively made as the last bullet point of my original post, and might even be unnecessary.

@kitsonk is the plan to rely on pulling in TS' automated test suites to ease tracking advancements in TS, or is there some other strategy long term?

If we end up at that point, ensuring the language doesn't become fractured would be a goal.

HKhademian commented 4 years ago

I am glad you know what is and isn't important for us.

I didn't decide anything for you, I said deno can work without faster Typescript compiler. so it has less importance than fixing some bugs, issues and even add new features.

I love deno idea and it's existence, I love to help it and anything I said was in direction of my thoughts for its good. They are just my opinions.

phaux commented 4 years ago

Try to move type checking to Rust. even if it were ported over and kept in sync with the TypeScript based type checker, it may not perform that much faster.

If type checking was ported to Rust then what's the point of keeping it in sync with TypeScript? I would understand it, if there was a huge ecosystem (like npm) that needs to be supported, then it would be valuable to be compatible with all of that old TypeScript code, but that's not the case.

If Deno had it's own type checker, I wouldn't care if it supports code already written in TypeScript, because most of that code is written for Node anyways. It could reuse existing TypeScript syntax (or even Flow, Hegel or a custom one), but it wouldn't be a huge problem if it worked differently than one of the existing type checkers. Even the current approach of using slightly modified tsc already isn't compatible and needs editor plugins to work properly.

Also, having a custom type checker would be a great opportunity to create something that is more strict and correct by default. TypeScript has had a lot o strict options added and had to make a lot of compromises for backward compatibility, so it's not that great at all.

rezonant commented 4 years ago

No, there already is a lot of Typescript code out there and I think a lot of us want to be able to use it both on Node and Deno. If Deno were to become (even more) incompatible to tsc, I would opt to simply compile/transform my TS code to Deno-compatible JavaScript and ship that for use with deno. Honestly, it already looks like the better path given the performance and compatibility headaches that already exist.

Ebuall commented 4 years ago

If Deno had it's own type checker, I wouldn't care if it supports code already written in TypeScript, because most of that code is written for Node anyways.

Compatibility with old ecosystems is the biggest reason TypeScript is popular. And the are a lot of code. Most of which doesn't even care if it's written for node or browser.

CreatCodeBuild commented 4 years ago

@HKhademian Deno's compile time is not a problem if you are talking about the production environment where most of the time we don't care about the start-up time.

But, when it comes to development, it is a major developer experience killer.

I am working on an HTML5 game and was using Deno at the beginning because Deno has bundle options so that I don't need to set up a whole webpack/babel thing.

It costs 20s to compile while my game was just several thousands lines of code. The speed of iteration was killed by this slow compile time. I switched to Node and setup a webpack/babel thing.

I am not sure if Deno has incremental compilation enabled for TSC or if that is even possible for Deno. However, I believe if even Deno team doesn't implement TSC in Rust, there are places where TSC can be faster in JS implementations or Deno's internal pipeline.

apiel commented 4 years ago

@CreatCodeBuild completely agree with you. If developer experience is not good, people will not use Deno. Right now, Deno is still in a very early stage and I would not recommand it to anybody in a professional project. For the moment, we still have to wait till we get reasonable performance and flexibility. But at least, we could help to build the eco-system by creating new modules, compatible with Deno.

In another thread, we point out that one of the main problem of TSC is the types checking of the code. Would be great if we could just deactivate this type check when we are in dev mode.

Also another point that you mention, is that in node many people use babel because it is much much faster than TSC. So would be really great to give the possibility to decide for our own transpiler. Of course by default, it would be TSC but if someone want to tune it, he could just mention to deno to use something else (for example to use babel). And doing this, would also open lot of room to developers, we could then use a different module loader than the native one from v8 and therefor use nodejs module.

HKhademian commented 4 years ago

Maybe it's a silly idea but could we just convert TS code to JS by removing all type-chekings and type-system and see the bare ts code as JS one (which it is), feed it to V8 and skip typescript compiler?

We could use deno check (something like in rust) to check for types and ... , Aslo to bundle the final product in CI/CD work-follows we can have flags like --type-system to enable this feature.

This idea (maybe it's silly) came from where I saw deno can run JS like TS codes, if we don't have any problems with JS code, so by fast convert (not compile or analyse) it to JS, we can use JS's benefits.

dsherret commented 4 years ago

@HKhademian this has been discussed before. See https://github.com/denoland/deno/issues/5436

kitsonk commented 4 years ago

@HKhademian to add to @dsherret is specifically discussed as a step (second one!) in the approach in the original post that we are working towards. 😕

littledivy commented 4 years ago

https://github.com/swc-project/swc/issues/571 might be an interesting one to keep an eye on.

ry commented 4 years ago

Since https://github.com/swc-project/swc/pull/886 has landed, we should be able to do type stripping in Rust now.

kitsonk commented 4 years ago

Regarding the type stripping: #6864 is the tracking issue.

bartlomieju commented 4 years ago

Update: type stripping has been implemented using SWC and takes impressive ~70ms compared to ~1s before the change. Screenshot 2020-07-29 at 12 45 56

kitsonk commented 4 years ago

@bartlomieju after the compiler refactor, my opinion is that we need to investigate the swc AST -> TypeScript AST and feed the compiler pre-parsed AST (this in theory would also open the door to just using tsc for type checking as well, but as we discussed, we can't do that without a significant breaking change, because Deno would only work effectively with "isolatedModules": true).

06kellyjac commented 4 years ago

Another option would be to have the current default behaviour + the faster swc AST -> typescript AST available for just isolatedModules enabled projects?

kitsonk commented 4 years ago

Possibly... We were talking about introducing a top level option of --isolated in addition to the existing --no-check which would set the config to "isolateModules": true without needing to use a --config tsconfig.json. We could use the code paths then to just do the type checking with no emit and then use the swc type stripping, even before we could do the AST transform. That would be a stepping stone to making that the default in a future version.

bartlomieju commented 4 years ago

@bartlomieju after the compiler refactor, my opinion is that we need to investigate the swc AST -> TypeScript AST and feed the compiler pre-parsed AST (this in theory would also open the door to just using tsc for type checking as well, but as we discussed, we can't do that without a significant breaking change, because Deno would only work effectively with "isolatedModules": true).

@kitsonk that sounds good to me, let me know if I can help with compiler refactor

nonara commented 4 years ago

@wongjiahau With respect, that is not an uncommon case. Classes, themselves, are functions with properties attached. Many who know JS take advantage of functions' object nature.

Also, things like declaration merging are widely used with TS. It can be tempting to avoid supporting some of the more advanced features of TS, like declaration merging, but in my experience, it's best to consider them from the start. Otherwise you'll end up re-engineering much of the core later on.

ChayimFriedman2 commented 4 years ago

If you consider such far things, I feel conformant to suggest a more ridiculous one 😄

Instead of moving the type checking to Rust, we can (oh, can theoretically) create a new TS/JS engine in Rust. I guess it will be able to do further optimizations. Although https://softwareengineering.stackexchange.com/questions/275497/why-doesnt-v8-compile-typescript-instead-of-javascript think that not, I still think the bytecode interpreter (until the JIT is fired) can take advantage of that.

But of course, this is just a joke and not really going to happen 😄

kitsonk commented 4 years ago

People have been generally keeping the noise down on this, which is great, but let's remember to keep focused.

It has been a while, so I wanted to give an update on current thinking, what has been learned, etc.:

I am still personally of the opinion that moving the type checking to Rust is going to be super complicated and not something we would ever really want to consider, just looking at the features that shipped in TypeScript 4.0 (really complex variadic types) and even more complex type system structures like recursive conditional types coming in TypeScript 4.1, it would be just silly to try to tackle those things, and when we start talking about things like a type system, the inefficiency of JavaScript will get in the way a lot less. If we can feed the TypeScript compiler the AST it needs, and unburden it of its need to emit, we might be able to really get going super fast, to hopefully the benefit of not only Deno but the wider community.

kitsonk commented 3 years ago

Another update...

In master (which will soon be released as 1.5) we have added deno bundle --no-check support and migrated deno bundle emits out of tsc and use swc (tsc still does the type checking). We also refactored a lot of the infrastructure in Rust and rewrote the way we interface with tsc to clean things up quite a lot.

This has resulted in performance benchmarks for our "medium" workload that looks like this:

Benchmarks___Deno

When we started tracking this, the full type check and emit for the workload was 1700ms. That is now 1100ms be cleaning up the Rust infrastructure. As mentioned previously, when you skip type checking, we started at about 1100ms, but when we moved that wholly to Rust via swc, we ended up around 60ms.

With our previous bundling of that same workload, which was using tsc to emit the bundle, we were around 1400ms. In master, while we still perform type checking in tsc for the bundle, using swc for the emit, we dropped to around 540ms. That is a significant drop. Which is a strong indication to us that not using tsc for the emit at all would give us a further speed increase. The "problem" with that, is that transpilers like swc and Babel cannot handle the type directed emits that are supported by tsc. Since Deno 1.4 we have enabled --isolatedModules when working with TypeScript and are making that the default in Deno 1.5. This means that some code that previously worked under Deno will no longer compile, but this helps ensure that your code would work if we use tsc for the emit or not.

Given that there is potentially a savings of ~600ms in our benchmark workload, it seems like we really need to migrate to not using tsc for the emit and solely use swc.

Using the tsc performance APIs, we can see the breakdown of the time spent on this benchmark workload:

This is just time spent into tsc and there are some overheads when emitting to take the emitted code out of JavaScript and into Rust.

This is also a strong indication to me, personally, that we need to investigate parsing in Rust and sending in a pre-parsed AST to tsc for type checking. I don't know if we could save the full 15%, but based on the fact that we can parse, transform and emit the same workload in 60ms compared to 1100ms, it is a strong indication that we need to offload whatever we can from tsc and do in Rust, and really let tsc focus on type checking.

ChayimFriedman2 commented 3 years ago

If we'll use WASM with swc, will we can pass the AST between tsc and swc more easily?

kitsonk commented 3 years ago

@ChayimFriedman2 not really. Passing data structures from WASM to JavaScript is harder for Deno then it would be from Rust to JavaScript. Plus you have a material impact on performance of running Rust -> WASM over just Rust, and we already have everything we need with SWC built into Deno in Rust for other reasons that will keep it there.

stale[bot] commented 3 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

ghost commented 3 years ago

Can't Deno fire off two threads, one running SWC stripping types and emitting into a temporary file, the other thread running TSC --no-emit for performance, then, depending on the result of TSC, running the emit file from SWC, or returning with a non-zero exit status?

Would that even help?

schickling commented 3 years ago

That's also how https://github.com/rsms/estrella works (except it's using esbuild instead of SWC).

ghost commented 3 years ago

In that case, if it's viable, based on that benchmark,

Parse Time - 15% Bind Time - 12% Check Time - 49% Emit Time - 24%

we could cut out the 15% and the 24%, reducing the overall time by roughly 40%. That sounds pretty good, but is Deno already doing something like this?

kitsonk commented 3 years ago

but is Deno already doing something like this?

Yes.

ghost commented 3 years ago

@kitsonk In that case, what does "bind" refer to from that benchmark? Could we help there?

VienDinhCom commented 2 years ago

Is this good new for JavaScript/TypeScript?

Rome will be written in Rust 🦀

Rome started off written in JavaScript because that is the language of choice for our team and it made it easier for others in the community to join as contributors. We love JavaScript and TypeScript (and HTML and CSS) at Rome, and we want to build the very best tooling possible for these languages. For a number of reasons, we’ve decided that Rust will provide a better foundation for this tooling.

We are also taking the opportunity to explore fundamental shifts in the architecture of Rome. These changes give us more flexibility and will allow us to build tooling JavaScript and the web has not had before.

Read more: https://rome.tools/blog/2021/09/21/rome-will-be-rewritten-in-rust

kitsonk commented 2 years ago

@Maxvien the core teams between both projects are in communication. There are certainly things that we can collaborate on that are mutual interest. Having more JavaScript/TypeScript projects focused on Rust certainly will help things. One thing we both agreed on is that we are a ways away from full type checking TypeScript in Rust, though Rome has some interesting ideas at ways of chipping away at the problem, as well as we are keeping an eye on what is happening with swc's work on type checking in Rust as well.

charrondev commented 2 years ago

as well as we are keeping an eye on what is happening with swc's work on type checking in Rust as well.

Looks like the SWC doesn't have any intention of releasing their type-checker under an OSS license (and development has stalled on it), instead intending to monetize the software under a proprietary license to fund it's development. https://github.com/swc-project/swc/issues/571#issuecomment-998390982

So far SWC -> TSC AST conversion seems to be the avenue that would be fastest to gets some speedups. Is there a separate tracking issue for looking into that and/or has someone already done some evaluation of the work required for that.

majo44 commented 2 years ago

In the context of the discussion: I’m porting tsc to Go - DongYoon Kang