Hacker News new | past | comments | ask | show | jobs | submit login
Swc – Fast JavaScript to JavaScript compiler (swc-project.github.io)
131 points by bpierre 7 months ago | hide | past | web | favorite | 23 comments

Two things go unanswered for me:

First, why is it faster? We had Buble back in the day, and deviation from the spec turned out to mean that you were fine for a while until you weren't. Does this project cut corners? It looks like the project is mostly Rust, is the perf improvement simply because of that?

Second, it looks like it has its own parser for Typescript. That scares me. What version of Typescript does it target? How are you testing that it produces the same output as Typescript itself?

One of the biggest benefits to Typescript (in my opinion) is that a single tool verifies the correctness of your code and compiles it (and in all honesty, I've never been wanting when it came to tsc performance). You don't need to worry about your production build output differing from your debug version[0]. I'd be very hesitant to use this in production unless it was running the full suite of tests baked into the TS repo—and passing.

[0] Yes, you probably use a minifier on your production build, but the minifier operates on the ES code that you compile your Typescript down to.

One of the cornerstones of TypeScript is that types do not not alter the semantics of the underlying JavaScript. You can compile TypeScript by just ignoring all the types and dealing with only the minimal syntax which it adds to ES6/7.

TypeScript does add features like enums and decorators, though, which are not present in the underlying JavaScript.

You speak of Bublé as though it goes unused. It still gets plenty of use, not least because of how much faster it is than Babel, but also because of its focus on cheapness of its transformations at runtime—Babel focuses on being as close to correct as possible, but at quite a substantial runtime cost in code size and speed. (I understand Babel also has loose transformations, https://babeljs.io/docs/en/babel-preset-env#loose, that are like Bublé’s, but I have never compared the two; they definitely feel like they’re a second-class citizen in Babel.) The less-different code is also great for when you inevitably need to read the generated code without source maps, too, since it is made up of simple AST-guided source transformations rather than total rewrites of features.

In all, I much prefer Bublé to Babel for code I control, although sometimes I would like the extra transformations that you can do with Babel.

For my priorities, I would genuinely see switching to swc as a functional regression if it does not support such loose transformations.

I’d be interested to see a hybrid approach that focused on loose transformations and used the faster AST-guided source transformation approach where feasible, and localised full AST rewrites where not feasible. In JavaScript the performance difference between a full AST rewrite (Babel) and AST-guided source transformation (Bublé) is stark; my feeling is that it will be less distinct, but still substantial, in Rust.

Why don't you just run it on your target codebase and then run your test suite to make sure nothing is broken?

I suppose I could, but then I'm running my tests twice (once against the actual compiler and once against swc). Compiling my code is necessary to run the tests anyway, so it seems a bit moot to go through the trouble. I could ditch "real" TypeScript compilation altogether, but then you're not building for TS anymore, you're building for the variant of TS that swc supports.

Plus, I'm not writing unit tests that test the behavior of things like enums and decorators, I'm testing the business logic of my application. If the compiled code behaves strangely under abnormal conditions that wouldn't occur in the test environment, it's going to be a hell of a time for me to figure out what's going wrong.

One suggestion I like is that open source projects include a TRADEOFFS.md file that details the technical decisions made on the project.

Hiding that information means that by default consumers don't have the information they need to make an informed decision. This leads to better marketing beating out better technology and, more importantly, fractures in the community.

Although it works 99% of the time, I'm not a huge fan of "Just run the tests" style of ... testing. Unit tests are important, but I feel slightly insecure if I don't think about the process mechanically rather than as a black box.

In this case your suggestion is a good one, obviously.

> project is mostly Rust, is the perf improvement simply because of that?

I would think so.

It’s suprisingly difficiult to use use these tools just to bundle your code, but not transpile it down.

I’ve seen code that transpired down to Es3, yet used webgl

Why is it difficult? It's just a command line tool with a config file.

I'm not familiar with this tool, but with Babel, you wouldn't use it to bundle your code. That's what Webpack/Rollup/Parcel is for.

If you don't care about targeting older browsers, you can use ES Modules today without a bundler. Even dynamic imports work without transpiling or polyfilling.

> It’s suprisingly difficiult to use use these tools just to bundle your code, but not transpile it down.

Isn't that what Rollup is for?

My first thought is this was a rehast of the js2js joke: https://eleks.github.io/js2js/

After looking over the website briefly I'm still trying to figure out if this is a joke or not. It's only after reading more that it's clear this is a transpiler. Not the clearest of communication.

Why would it be a joke?

We've had compilers that compile from newer JS syntax to older JS syntax for years (not to mention all the compilers that compile from another language into JS). Traceur was the first reasonably well-known one I remember hearing about, then Babel came out and took over the ecosystem.

Devs want to be able to use the latest JS syntax, but also have to target older browsers. Compiling new syntax to equivalent older syntax is a perfectly reasonable thing to do.

Effectively all JS build tools have been written in JS, but this looks like an attempt to recreate some of that functionality in Rust.

I'm curious how much of an actual perf difference there is in practice, given that Babel is usually just one part of the build pipeline.

I'd love to see Sucrase (https://github.com/alangpierce/sucrase) included in the performance comparison.

But why? For IE11? A browser for which support will end next year?

All current browsers support ES2015 already. If you really want to support the few users still using IE11, you can use Babel. Why invest many hours in a project to make this faster? And that will be obsolete in two years?

Tanspiling from ES2015 to ES5 is no longer the main usage of babel. For example, there is transforming JSX to normal JS. And object rest/spread proprerties (ES2018) is often used by front developers, even if it is not supported by Edge. So, I don't think that babel and swc will be obsolete in 2 years. The most used transform plugins for those will change, but the parser and engine will remain. And having fast and robust tool here is a good thing for this field.

If you use dynamically rendered content then ES6 won’t work in googlebot, since that’s still Chrome 41. https://developers.google.com/search/docs/guides/rendering.

JS is not browser only for a long time now, there might be situations where you have to target old JS runtimes.

IE 11 is still relevant and large code bases can take a long time to compile with Babel.

Why invest time? Probably someone thought it would be fun to beat Babel's performance :)

Checked this using Webpack and swc-loader vs ts-loader on a tiny(300LOC) TypeScript project and got 4s vs 6s so maybe not 15-20x faster, but at least 50% faster, which is still an improvement.

Every github repo should have the prefix 'super-fast'

> 15-20x times faster..

Compared to babel, big team, smart guys, using standards.... Sure

Babel actually doesn't have a big team. IIRC it's 3-4 developers who have stated that they don't have enough time as they would like to focus on performance.

That, plus this being written in Rust rather than JavaScript makes the claim entirely plausible.

Applications are open for YC Winter 2020

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact