[HN Gopher] Rust Is the Future of JavaScript Infrastructure
       ___________________________________________________________________
        
       Rust Is the Future of JavaScript Infrastructure
        
       Author : leerob
       Score  : 188 points
       Date   : 2021-11-11 19:32 UTC (3 hours ago)
        
 (HTM) web link (leerob.io)
 (TXT) w3m dump (leerob.io)
        
       | [deleted]
        
       | forty wrote:
       | > The Rust version probably could be made to work at an
       | equivalent speed with enough effort. But at a high level, Go was
       | much more enjoyable to work with.
       | 
       | Wow. I always thought Go was a language for depressed (or
       | depressing? :)) devs ;) . I mean, it's boring _by design_. On the
       | other hand Rust is really a cool language, with many things that
       | are designed cleverly, and really enjoyable to use. Well, to me,
       | at least, as it seems some people like boring more :)
        
       | tbeseda wrote:
       | Nice writeup, Lee. Zig is also pretty interesting for this type
       | of tooling, see https://bun.sh/
        
         | leerob wrote:
         | Thank you! Jarred is doing incredible work, worth following on
         | Twitter too: https://twitter.com/jarredsumner
        
       | steventey wrote:
       | Bullish on Rust
        
       | game_the0ry wrote:
       | Front end engineer, here. Not very experienced, less than 10
       | years exp.
       | 
       | Dumb question - why do we still need compilers like Babel and SWC
       | to compile our es6 (excluding TS) to...whatever version of js the
       | compiler is targeting? Are browsers still so out of sync with
       | each other that we still need to compile to es5? If yes, wouldn't
       | it be more worthwhile for the front end community, including TC39
       | and every major browser engine developer (google, apple, mozilla,
       | etc), to focus on the base implementation (engine) so they are no
       | longer so out of sync? The most popular browser are based on open
       | source engines anyway.
       | 
       | Don't get me wrong, I am sure there is a good reason for all this
       | rust tooling - faster compilation does not hurt, but it seems
       | inefficient to have an intermediate compiler (Babel / swc/ TS/
       | etc) that creates deployable code that will eventually be
       | interpreted by the user's JS engine (V8 / webkit / gecko) anyway.
       | 
       | A standardized engine seems the way to go and it seems like we
       | are going in that direction with only a handful of JS engines in
       | use today.
        
         | Androider wrote:
         | You have to realize that it is not at all in the interest of
         | most commercial web applications to be transparently delivered
         | as ES modules, all neatly split up and perhaps lightly
         | minified. No, the fact that your 1000+ constantly version
         | churning NPM dependencies and your proprietary business code
         | are all bundled up in a big undecipherable blob is seen as a
         | feature. The only thing that I can see that is going to replace
         | it, is probably going to be WASM or a binary format blob, or
         | the application code executing entirely on the backend and the
         | frontend streamed like Netflix.
        
         | totaldex wrote:
         | In a perfect world, things would be like you describe.
         | 
         | Unfortunately we live in a diverse landscape of browsers and
         | devices, many of which have not been updated in quite some
         | time. Factors ranging from IT policy at older companies, to
         | geographical limitations, may prevent many users from upgrading
         | to the latest and greatest.
         | 
         | Some companies choose to cut their losses, and support only
         | certain browsers - these can get away with less compilation and
         | polyfills. Other companies may be targeting these specific
         | segments (such as B2B), and can't get away with such a luxury.
        
           | game_the0ry wrote:
           | But we are so close - the wound has almost healed, and
           | instead of taking off the band aid, we are putting on another
           | band aid.
        
             | WJW wrote:
             | How are we 'so close' though? Browser fragmentation hasn't
             | really decreased at all, perhaps even the opposite.
        
         | rizky05 wrote:
         | Browser competition is one that sparks inovation. Each vendor
         | wants to be the leader. So they compete.
         | 
         | And also anyone want to browse web using any browser they have
         | at the time, it may be outdated.
        
         | leerob wrote:
         | While a compiler-free world sounds ideal, my take is there will
         | always be different, newer, syntax developers will want to
         | write that isn't natively supported by the browser. For
         | example, JavaScript language proposals that are maybe in stage
         | 1 instead of the later stages.
         | 
         | Overall, browsers have gotten a lot better at implementing and
         | supporting a common set of web APIs. There's still work to be
         | done, but we're in a far better place than we were five years
         | ago (in my opinion).
         | 
         | 100% agree with your sentiment though.
        
         | winterplace wrote:
         | Because there are old computers and phones with old browsers
         | that are still running today and will not be upgraded. Many
         | companies cannot risk upgrading and many consumers have not
         | upgraded or bought a newer device.
         | 
         | The old browsers are on ES5.
        
         | __s wrote:
         | You don't need Babel anymore. I recently updated a project of
         | mine to only use Babel on jsx files only for jsx transform.
         | webpack handles everything
        
         | acemarke wrote:
         | There's many reasons to have a JS compilation step:
         | 
         | - Still targeting legacy browsers like IE11
         | 
         | - Using React / JSX syntax
         | 
         | - Using TypeScript
         | 
         | - Using other brand-new JS syntax that hasn't trickled out to
         | wider support yet
         | 
         | - Using custom JS transforms for libraries like `styled-
         | components` (see this Next.js discussion thread for examples of
         | the many different non-standard Babel transformations that
         | people are using:
         | https://github.com/vercel/next.js/discussions/30174 )
         | 
         | That said, the ideal target language version _is_ getting
         | better. Jason Miller ( creator of Preact) has done a lot of
         | research on both browser support for ES2017, as well as tooling
         | to reverse-compile ES5-targeted published libraries upwards to
         | ES2017 syntax again for improved bundle size:
         | 
         | - https://jasonformat.com/enabling-modern-js-on-npm/
         | 
         | - https://web.dev/publish-modern-javascript/
        
           | leerob wrote:
           | Excellent summary. Thank you!
        
           | Buttersite wrote:
           | None of those are good reasons. If you need a JS transpiler
           | you are overusing/misusing JS, probably to an extreme degree.
        
         | skohan wrote:
         | It seems to me the future is rather in gradually replacing JS
         | engines with a WASM back-end. The whole webpack/babel ecosystem
         | could be replaced by a toolchain which targets WASM, and
         | browsers could ship with a JS engine which just translates es5
         | to WASM for legacy support.
         | 
         | I guess the WASM api is lacking a lot of features which would
         | be required to make this work, but I don't see why it shouldn't
         | be the goal.
        
           | sroussey wrote:
           | JS is too complex for that. But you can have a look at
           | AssemblyScript.
        
         | kag0 wrote:
         | It's more of an issue on the end user's side. All the main
         | browsers have had support for ES6 and newer features for years.
         | But that doesn't mean end users are running the latest versions
         | of those browsers. So when you transpile/polyfill a feature,
         | you're aiming to support that small number of users who haven't
         | updated their browser in 5+ years. If you don't care about
         | those people, you have no need for that intermediate step. Or
         | if you want to be really sophisticated, you can look at the
         | user agent for an incoming request and serve a response that's
         | transpiled/polyfilled exactly as much as is needed.
        
         | dexwiz wrote:
         | At this point, if you are only targeting modern browsers, it's
         | more for the bundler than the transpiler. The module loader
         | standard is still a mess, mostly because there is little
         | incentive to fix it. Unless you are using HTTP/2 or another
         | streaming connection, loading the hundreds of project files and
         | thousands of dependencies, is just not feasible. The compilers
         | also do a bunch of tree shaking to remove dead code from your
         | dependency graph.
        
           | sroussey wrote:
           | It will be interesting to see a tool that does dead code
           | elimination (tree shaking) and minimization, then writing
           | back individual es6 module files for http2. Maybe one of
           | tools can be configured to do so now?
        
             | jsmith45 wrote:
             | The Rollup tool supports that in conjunction with the
             | `preserveModules` option. I've never used it outside of
             | playing around, so can't vouch for it from experience, but
             | yeah it exists. It can also do more of course, like convert
             | to older module formats or the like, but obviously you
             | don't need to use that.
             | 
             | The biggest downside is that even in http2 or http3,
             | bundles can still perform better in terms of lower overall
             | loading times, since individual modules you need to
             | download the first one, and perform at least a bit of
             | parsing to find the other modules statically imported
             | before you can start downloading those, repeat.
        
         | keb_ wrote:
         | The important part is to know your target. I'm currently
         | working on a project that has a complex webpack/babel setup.
         | The reason for the complicated toolchain? I have no idea. Our
         | target (Electron) supports ES6+ syntax yet we're still
         | compiling down to ES5. The only other reason I can think is
         | that the developers wanted ES2020+ features, but this, in my
         | mind, is a bad tradeoff. The toolchain has broken more than
         | once for me. Realistically, all we need is `tsc` and `esbuild`.
         | 
         | I've been a JS developer for almost 10 years. I'm convinced
         | young hip developers are just addicted to tooling.
        
           | sroussey wrote:
           | Electron uses node and node support for es6 modules is new,
           | and electron itself is just putting its toes in the water.
           | Same with Typescript. Are you using .mts .mtsx files?
        
             | vorpalhex wrote:
             | Node support for ES6 modules has been out for years...
        
               | josephg wrote:
               | Es modules are one of hundreds of features that have been
               | added to javascript since es5. Others include typed
               | arrays, promises, async/await, and so on. Babel
               | configured to recompile code to es5 will polyfill all of
               | those JS features. So the highly efficient V8
               | implementation of Uint8Array is replaced with slow
               | javascript. Code using async await will be rewritten to
               | use a promise polyfill and callbacks. And so on. The
               | resulting code will be bigger and slower. Sometimes much
               | slower depending on what it's doing.
               | 
               | List of features in each version of JS:
               | https://kangax.github.io/compat-table/es2016plus/ (also
               | check the ES6 tab)
        
           | josephg wrote:
           | The answer is usually that whoever set up webpack grabbed the
           | configuration from another project, and nobody wanted to
           | touch it since then because it worked and it looks scary.
           | 
           | Young developers don't know what they don't know. If they
           | don't see editing the webpack configuration as part of their
           | job, they'll probably just never touch it.
           | 
           | And that means it's your job to go fix it! Compiling down to
           | es5 can have terrible performance implications for the
           | resulting application - particularly if any of the bundled
           | code touches typed arrays. There's some free performance wins
           | sitting on the table. If your coworkers are too junior, it
           | falls to you to fix the build.
        
           | cuddlecake wrote:
           | The best way to drive a wedge between young and old
           | developers is to negatively attribute something to a specific
           | age group.
           | 
           | So keep going, you're on the right track.
        
             | keb_ wrote:
             | Point taken.
        
           | eatonphil wrote:
           | > Realistically, all we need is `tsc` and `esbuild`.
           | 
           | esbuild and babel/webpack do basically the same thing.
           | esbuild can also target older versions of JavaScript (just
           | not es5).
        
             | keb_ wrote:
             | Which is great! And it even takes care of JSX/TS
             | transpilation.
        
               | eatonphil wrote:
               | I'm confused about what your point is then since either
               | way you are using some system in between your code and
               | the browser or Node.
        
               | keb_ wrote:
               | You'd likely still need a bundler for vendor packages.
               | esbuild ships as a static binary, is a single dependency,
               | and is one of the fastest bundlers around. It's also
               | pretty much zero-config. That other stuff is just icing
               | on top. I don't know why someone would pick webpack +
               | babel + the endless plugins and config involved over
               | that.
        
         | RcouF1uZ4gsC wrote:
         | Also, if we are going through a compile step anyway, why not a
         | future for more support for WebAssembly and then we can use
         | other languages instead of JavaScript.
        
       | caymanjim wrote:
       | People tend to write dev tools in the languages they develop in.
       | C compilers written in C, JavaScript minifiers written in
       | JavaScript, etc. There's often no reason to use the same language
       | for the tooling, but you use what you know and like to work with,
       | and if you've got a need for a language-specific tool (like
       | Webpack) you're probably going to start out writing it in the
       | same language.
       | 
       | If Rust becomes popular for JavaScript tooling, how long until
       | those developers abandon JavaScript entirely? This isn't
       | necessarily a problem, but it could lead to some, if you can't
       | fix your own tools because you're not conversant in the language.
       | More importantly, if the key toolmakers all switch to Rust and
       | lose interest in JavaScript, the tool authors might lose touch
       | with (or interest in) the problems of the JavaScript community.
       | We all talk about dogfooding, and this is the opposite.
       | 
       | Rust seems to have this cult-like power. Rust developers are
       | definitely drinking a lot of Kool-Aid. Maybe if all the
       | JavaScript tools are written in Rust, we'll start seeing
       | Rustscript in the browser.
        
         | Daishiman wrote:
         | > Rust seems to have this cult-like power. Rust developers are
         | definitely drinking a lot of Kool-Aid. Maybe if all the
         | JavaScript tools are written in Rust, we'll start seeing
         | Rustscript in the browser.
         | 
         | Rust has tremendous popularity because it solves an enormous
         | class of problems for system programmers and require very few
         | compromises compared to any alternative.
         | 
         | The hype is real, but it is very unlikely that another language
         | will compete for this space.
         | 
         | Rust doesn't really work well in the niches most impacted by
         | fad-driven-development. Nobody is claiming you should do web
         | dev in Rust nor consider it comparable to much better languages
         | for that space.
        
       | skohan wrote:
       | I agree that wasm should be the future of web, but to be honest
       | I'm not sure rust is the best candidate to replace JS from the
       | developer perspective.
       | 
       | For one thing, Rust is slow to compile. I built a simple one-page
       | app in rust/wasm to kick the tires, and it was _much_ slower from
       | a developer perspective than for instance a react /ts app. Even
       | with hot reloading set up, it took noticeably longer for the rust
       | app to refresh after hitting the save button.
       | 
       | Also rust is fairly demanding on the programmer. Right now there
       | are an army of js programmers keeping the web running. To be
       | perfectly honest, I don't think there is sufficient supply of
       | programmers in the world with the aptitude to replace all those
       | js programmers with rust programmers. Due to the sheer scale of
       | the web, front-end programming has to be fairly easy for things
       | to keep moving at the pace which they are.
       | 
       | I hope wasm does supplant js as the main deployment target for
       | web development. But I think it will have to be a much simpler
       | language than rust which is the one targeting wasm.
        
         | rektide wrote:
         | > _I agree that wasm should be the future of web, but to be
         | honest I 'm not sure rust is the best candidate to replace JS
         | from the developer perspective._
         | 
         | Rust & wasm don't replace JS, in my view. They're there to
         | create good libraries & frameworks for the scripting languages
         | to consume & use, at many times.
         | 
         | There will definitely be some Rust entering the scene, but I
         | tend to think Rust & other wasms will not be the entire web
         | app, but be used for engineering the better crafted, more re-
         | usable bits.
         | 
         | Wasms success, imo, is ultimately gated on how well it's host-
         | object bindings work. Wasm doesn't really yet play well with
         | JS. Rust has a fairly unique edge right now in that Rust
         | pioneered their own wasm<->js foreign interfacing, via wasm-
         | bindgen, then generated a web-sys crate with all the web
         | foreign objects already defined in it, allowing Rust far better
         | inter-operation.
         | 
         | Because host-object binding/ interface types/ &c are still in-
         | progress, there's much less ability to experiment with what
         | pieces of the webapp make sense to keep in JS, and what pieces
         | make sense to go engineer in wasm. We'll see more interesting
         | blends, with more webdevs writing JS, but consuming/authoring
         | against Wasm tools, as we start to emerge a real wasm ABI.
        
       | forty wrote:
       | I'd love to build my stuff faster (of course), I tried SWC and it
       | seems impressive. But as long as it doesn't include a TS compiler
       | that check types, I'm not exactly sure where/how I would use it.
       | Both locally and in my CI I want my types checked, otherwise I
       | wouldn't bother writing them.
        
       | Zababa wrote:
       | > With Rust, developers have more control over memory allocation,
       | without it being as painful as C++ or Go.
       | 
       | Memory allocation is painful in Go?
        
         | leerob wrote:
         | That was my takeaway from folks who had moved from Go to Rust.
         | I'm not a Go expert though, so feel free to correct me.
         | 
         | https://blog.discord.com/why-discord-is-switching-from-go-to...
        
           | kgeist wrote:
           | Storing billions of states in garbage-collected memory sounds
           | like using a wrong tool for the job (by the way, I wonder why
           | they didn't use something like Redis? didn't scale well?). I
           | think it's an edge case they ran into -- which doesn't mean
           | Go's memory management is painful per se. It's not secret
           | that large heaps with many old generation objects are
           | problematic in presence of GC. And few projects have
           | requirements of the scale of Discord. For stateless servers,
           | Go is more than enough in my experience; in our services we
           | do allocate garbage like there's no tomorrow and we're yet to
           | run into GC problems, because all caching is delegated to a
           | redis cluster and all garbage we produce during request
           | processing is ephemeral so we don't have large object graphs
           | that would slow down the GC. Rust is perfect for this kind of
           | "core infrastructure" projects where you need maximum
           | performance (Redis itself is written in C), but actual
           | business logic on top of such infrastructure can easily be
           | written in a simpler language like Go and GC is rarely a
           | bottleneck there.
        
             | dahfizz wrote:
             | According to Redis themselves, a high end and well tuned
             | redis server will get you ~200k requests per second[1].
             | This is if all your application does is send requests in a
             | loop.
             | 
             | Am I correct that redis does not offer a native API and so
             | forces you to craft commands as strings? Just having to run
             | snprintf 500k per second wastes a considerable amount of
             | CPU. Combined with the normal overhead of communicating
             | over a socket, using redis is going to be considerably
             | slower than just keeping that memory in your own process.
             | That's assuming the overhead of the redis internals is 0.
             | 
             | [1] https://redis.io/topics/benchmarks
        
               | Karrot_Kream wrote:
               | The trick is to precompute the Redis command strings
               | whenever possible. We (not going to name names here) use
               | Redis at above that scale. Our keys all have a fixed
               | size, so we preallocate a buffer that can hold the
               | command and the key, clear (so move the write pointer
               | back to the beginning of the key) it on every new
               | request, write directly into the buffer, and then pass a
               | pointer to the buffer when writing to the socket. This is
               | a similar trick we use whenever we're constructing load
               | tests as a lot of the time can be spent creating request
               | bodies instead of just pushing bytes onto the socket as
               | fast as possible.
        
               | kgeist wrote:
               | In the article, they say:
               | 
               | >The service we switched from Go to Rust is the "Read
               | States" service. Its sole purpose is to keep track of
               | which channels and messages you have read
               | 
               | >On cache key eviction, we commit your Read States to the
               | database. We also schedule a database commit for 30
               | seconds in the future whenever a Read State is updated.
               | 
               | So it's a separate service whose only purpose is to store
               | data in-memory with occasional commits to persisted DB,
               | which sounded a lot like Redis. But of course, a special
               | optimized service is always going to outperform a general
               | purpose tool such as Redis.
               | 
               | They also replaced HashMaps with BTreeMaps, reduced the
               | number of memory copies they were doing, etc. -- which
               | has nothing to do with Go, but also contributed to a
               | performance increase
        
           | j03b wrote:
           | The takeaways in this article are much more why Go's memory
           | model becomes difficult at scale. When you're dealing with
           | memory at Discord scale garbage collection is hard, for
           | example on the mentioned Discord microservice:
           | 
           | > There are millions of Users in each cache. There are tens
           | of millions of Read States in each cache. There are hundreds
           | of thousands of cache updates per second.
           | 
           | This is something that is probably never going to be hit
           | locally in the development toolchain. You can certainly
           | prefer the Rust memory system to Go and have that be a valid
           | reason to use Rust over Go for something like dev toolchains,
           | but you're not going to hit scale problems like those
           | mentioned in the article.
        
             | AaronFriel wrote:
             | Not just at scale, Go doesn't make it obvious when an
             | allocation is on the heap or stack. The escape analysis can
             | change (hopefully without regressions) from version to
             | version of Go, and that can mean performance regressions
             | can happen. It also means small refactors risk de-
             | optimizing code without an obvious reason why that would be
             | the case.
             | 
             | I think more engineers are becoming skeptical of optimizing
             | compilers with that sort of implicit, potential "spooky
             | action at a distance" where nonlocal code can cause
             | performance regressions.
             | 
             | In Haskell, laziness and iterator fusion can do the same
             | thing. Nonlocal code can cause local expressions to compile
             | differently, resulting in - from an engineer's POV -
             | nondeterministic performance, memory usage, GC pressure.
             | "Space leaks" can also occur, again, due to nonlocal
             | effects.
             | 
             | In JavaScript, the JIT can similarly cause local
             | regressions due to nonlocal code. A single expression deep
             | in a call stack mutating an object can result in it no
             | longer fitting an optimized "shape", resulting in function
             | deoptimization.
             | 
             | Just say no to spooky action at a distance in programming
             | languages, in my opinion. It leads to tremendously
             | difficult to debug regressions.
        
               | Thaxll wrote:
               | > the escape analysis can change (hopefully without
               | regressions) from version to version of Go, and that can
               | mean performance regressions can happen.
               | 
               | Because it's not the case with Rust or any compiled
               | language? LLVM has shown regressions wich is what Rust
               | uses to compile code.
               | 
               | 2sec search on google: https://github.com/rust-
               | lang/rust/issues/24194
        
               | kgeist wrote:
               | >Not just at scale, Go doesn't make it obvious when an
               | allocation is on the heap or stack. The escape analysis
               | can change
               | 
               | I thought heap allocations are only triggered by taking
               | pointers, i.e. using reference semantics (including
               | casting to interface and calling a method whose receiver
               | is by-ref)? If I'm careful to only use variables by-value
               | (for types that can afford it, i.e. excluding map/array),
               | what else can trigger heap allocation?
        
               | jdreaver wrote:
               | Making a closure usually requires allocation. For
               | example:                   package main
               | import "fmt"              func main() {
               | closure := make_closure()
               | fmt.Println("closure():", closure())         }
               | func make_closure() func() int {             x := 1
               | return func() int { return x }         }
               | 
               | This prints:                   $ go run main.go
               | closure(): 1
               | 
               | If x were allocated on the stack, it would get nuked
               | after we returned from make_closure(). In Rust you could
               | move x to the closure, but I think in this Go example x
               | would be heap allocated, assuming the Go compiler doesn't
               | notice it can inline all of this and avoid allocating.
               | Maybe assume a more complex example with a struct that
               | had to be computed via a function argument or something
               | :)
        
               | kgeist wrote:
               | Oh yes, closures too. Coming from C++ background, you
               | kinda intuitively understand when things escape and when
               | they don't, because you assume that Go would implement it
               | in the most straightforward way (like it usually does),
               | and in the case of closures, heap-allocating a captured
               | variable is the simplest implementation (just let GC
               | handle it!) considering the implicit reference semantics
               | (that you can change "x" anywhere outside of the closure
               | and it should be immediately visible in the closure,
               | too). I.e. assume the worst (and don't expect Go to do
               | some clever special-casing similar to move semantics in
               | C++/Rust), and it's often the right answer :)
        
             | foota wrote:
             | I don't know, building JavaScript things involves similar
             | orders of magnitude.
        
           | tialaramex wrote:
           | Two things about this pain:
           | 
           | * They incur the pain _even when nothing needs doing_. This
           | is really terrible. If you spend ten minutes furiously
           | reading data from a network device into a fixed RAM buffer,
           | twiddling it, and writing it out again, in Rust (or C, C++
           | and various other explicit allocation languages) you neither
           | allocated nor de-allocated anything, therefore you pay
           | exactly zero for this work you didn 't do. In Go you will
           | incur the cost of the GC verifying that yup, everything is as
           | it was, there's nothing to do, apparently five times.
           | 
           | * The pain is swallowed in lumps, you can't spread it out. So
           | you must either size hardware for lump swallowing, even
           | though as we saw above we don't even want to swallow any
           | lumps, or accept poor performance each time a lump is
           | swallowed. With explicit allocation you can choose to swallow
           | bigger lumps (e.g. arena allocation) to reduce overheads
           | elsewhere, but you decide on the size of lumps you want for
           | your allocation.
        
         | mountainriver wrote:
         | Sure when you disable the GC =P
        
         | twic wrote:
         | Perhaps memory allocation is not, but _control over_ memory
         | allocation is. Like most other managed languages, Go trades
         | less control for more ease of use.
        
         | PragmaticPulp wrote:
         | Definitely not painful for simple operations (obviously).
         | 
         | But every large Go project I've worked on has eventually
         | invested a lot of time into minimizing allocations, rewriting
         | critical path sections to use pools, and various other
         | techniques to improve performance by taking more control over
         | memory allocation. Go's GC is very good, but it still has
         | limitations.
         | 
         | Honestly it's not a bad tradeoff most of the time. Write code
         | that works as quickly as possible, profile it as load scales,
         | and apply further optimization as hot paths are identified. On
         | the other hand, I've been working with Rust long enough that I
         | can almost write the same thing in Rust as fast as I could in
         | Go (Rust is inherently more verbose and requires more cognitive
         | overhead). I've been writing prototypes in Rust more and more
         | lately and haven't really been missing Go as much as I did when
         | I first started with Rust.
        
           | romero-jk wrote:
           | Sure maybe, but here we are talking about short running CLI
           | applications not long running processes. IMO, Go is better
           | suited at this 'js infrastructure' stuff.
        
           | Thaxll wrote:
           | When you work at certain scale with C++ and Rust you ends
           | rewriting a GC inside those language because default
           | allocator are not good enough. That's why GC languages are
           | faster than C++/Rust in some scenarios.
        
         | honkycat wrote:
         | There is a lot of pain over garbage collection and tuning that
         | in really high pref cases
        
       | leerob wrote:
       | Author here. A few other Rust projects to note that I didn't
       | mention in the original post I've since found:
       | 
       | - Boa (JS engine in Rust) - https://github.com/boa-dev/boa
       | 
       | - RSLint (JS/TS linter in Rust) -
       | https://github.com/rslint/rslint
       | 
       | - Node version manager in Rust - https://github.com/Schniz/fnm
       | 
       | If you know of any other popular ones, let me know. I'm keeping a
       | list :)
        
         | cjpearson wrote:
         | Volta is also written in Rust. I've only used it for managing
         | Node and npm versions, but it can do more than that and
         | describes itself as a "tool manager" rather than a node version
         | manager.
         | 
         | https://docs.volta.sh/guide/
        
         | timClicks wrote:
         | I was interested to see that bun (https://bun.sh) is being
         | created in Zig. "bun is like postcss, babel, node & webpack in
         | one 100x faster tool for building modern web frontends."
        
         | jbbe wrote:
         | fnm was a game changer for me, it is significantly quicker than
         | nvm.
         | 
         | It was mentioned in the article but swc as an alternative
         | typescript compiler has really sped up builds.
        
           | leerob wrote:
           | Now, it just needs type checking to replace tsc :fingers-
           | crossed:
        
         | leerob wrote:
         | Another one: Electron alternative Tauri written in Rust -
         | https://news.ycombinator.com/item?id=26194990
        
         | dceddia wrote:
         | I've been using NAPI-RS to bridge from Electron <-> Rust and
         | it's been nice - https://napi.rs/ I believe SWC uses it behind
         | the scenes.
         | 
         | They just put out an alpha release that makes it _way_ more
         | ergonomic to write Rust functions that interop with JS, too.
         | There 's a small example of it in the README:
         | https://github.com/napi-rs/napi-rs#taste
         | 
         | NAPI isn't as well-known in the JS-to-Rust bindings world (Neon
         | is the more well-known library, https://neon-bindings.com/) but
         | it seems to be gaining steam.
        
           | leerob wrote:
           | Ah yes, how could I forget! NAPI-RS is very, very slick.
        
       | buzzwords wrote:
       | Reading some of the comments here has really made me feel better.
       | I felt like I was the only one that felt JS ecosystem is just bad
       | and painful to work with. Thanks everyone.
        
       | amelius wrote:
       | Rust is good for systems programming. For everything else, use a
       | language with GC so you don't have to reinvent the wheel for
       | every memory allocation and your brain is free to think about
       | functionality, architecture, security, UX, ...
        
       | gigel82 wrote:
       | I doubt that; for the foreseeable future, the future of
       | JavaScript infrastructure will likely continue to be TypeScript
       | and C++.
       | 
       | deno is too opinionated to absorb a significant number of node.js
       | developers that just want to get stuff done.
       | 
       | Sure, there will be tools written in Rust (because it's the new
       | sexy thing) just like there were tools written in Go (when it was
       | the "new sexy thing"), but it's not going to take over the
       | ecosystem any time soon.
        
       | threatofrain wrote:
       | Rome is also being rewritten into Rust.
       | 
       | https://rome.tools/blog/2021/09/21/rome-will-be-rewritten-in...
        
         | bruce343434 wrote:
         | Good luck on your rewrite!
        
       | cairo140 wrote:
       | I've worked in JS for around 12 years now and welcome this change
       | of keeping JS as a scripting language but incrementally retiring
       | it for performance-intensive general-purpose applications.
       | 
       | To my eye, JavaScript has three applications:
       | 
       | * A GUI-building language: A language and ecosystem we use to
       | build UIs, where code runs on the end user's machine, served over
       | the Web or as desktop applications using a compatible API (e.g.
       | Electron).
       | 
       | * A scripting language: An approachable high-level C-like
       | language.
       | 
       | * A general purpose programming language: A server-side or
       | developer machine-side programming language for computational
       | tasks like linking dependencies, transpiling code, type checking,
       | orchestrating tasks.
       | 
       | At the first it's unbeatable, and the ergonomics and ecosystem
       | are phenomenal. This is why it "won" as a language to write even
       | desktop apps like VSCode and Discord.
       | 
       | At the second, performance doesn't matter anyway, so making JS
       | capable of this just makes it approachable for folks who learned
       | the language for the GUI-building purpose.
       | 
       | It's at the third application that the fundamental limitations of
       | JavaScript---the programming language---really show. These are
       | things like the lack of true multithreading (technically possible
       | with significant limitations around shared memory and messaging
       | and high overhead with Web Workers), lack of low-level primitives
       | to fine-tune performance, and the ease with which authors can
       | accidentally write extremely slow code. So much of this
       | (TypeScript compilation, NPM package resolution/linking, Webpack
       | bundling) in the modern Web ecosystem is regrettably still done
       | in mostly JS.
       | 
       | I hope the JS community rallies around one general-purpose
       | language to offload these tasks to as well as a uniform shim
       | layer like Ruby's C extensions so we don't end up with a chaotic
       | mishmash of different technologies. If nothing else, it would be
       | nice to have a good excuse to write not-JS every once in a while!
        
         | xboxnolifes wrote:
         | > At the first it's unbeatable, and the ergonomics and
         | ecosystem are phenomenal. This is why it "won" as a language to
         | write even desktop apps like VSCode and Discord.
         | 
         | I don't really think this is attributed to JS in any way
         | besides it being the _only_ browser language. Desktop apps use
         | JS because they are browsers, not necessarily because JS was
         | the best language option. An ecosystem has developed around it
         | not because it 's good, but because there is no other option
         | for working in a browser.
        
       | nickcw wrote:
       | Go is active in this space too, esbuild is a very fast JavaScript
       | bundler
       | 
       | - https://github.com/evanw/esbuild
        
         | onox wrote:
         | Recently I've used ReScript + esbuild for a completely webpack-
         | free experience with just a small node_modules folder
        
           | keb_ wrote:
           | The more popular this kind of setup gets, the better. I've
           | also vastly simplified a lot of my projects with just esbuild
           | as the sole dev dependency.
        
             | merb wrote:
             | our webpack based build took 70000ms (70s) to finished with
             | a cached built. it only took 5s in esbuild (esbuild has no
             | cache... or at least i don't know it yet).
        
       | cosmotic wrote:
       | The use of the word 'modern' is inappropriate in these sorts of
       | articles.
       | 
       | > It's a modern replacement for languages like C++ or C with a
       | focus on code safety and concise syntax.
       | 
       | Instead: "It's a replacement..."
       | 
       | > Babel: developers wanted to write modern JavaScript while
       | supporting older browsers.
       | 
       | Instead: "developers want to write with new versions of
       | Javascript..."
       | 
       | > Deno, created in 2018, is a simple, modern, and secure runtime
       | for JavaScript and TypeScript that uses V8 and is built with
       | Rust.
       | 
       | Instead: "Deno, created in 2018, is a runtime for JavaScript and
       | TypeScript that uses V8 and is built with Rust, with a focus on
       | Security."
       | 
       | > WebAssembly (WASM) is a portable low-level language that Rust
       | can compile to. It runs in the browser, is interoperable with
       | JavaScript, and is supported in all major modern browsers.
       | 
       | Instead: "all major browsers."
        
         | lifthrasiir wrote:
         | It's futile, from the history we can expect that the next major
         | generation of browsers would be called postmodern browsers, and
         | next one would be post-postmodern browsers.
        
           | bqmjjx0kac wrote:
           | I only use Pre-Raphaelite browsers.
        
         | VWWHFSfQ wrote:
         | now this is the kind of pedantry i come to hn for
        
       | lostmsu wrote:
       | The state of Rust debugging is atrocious. No expression
       | evaluators work with traits, and their implementations are the
       | majority of all Rust code.
       | 
       | Until somebody fixes this, I don't see Rust taking on any
       | mainstream languages.
        
       | coliveira wrote:
       | Rust probably will have its place, but it is useless to assume
       | that it will oust code that is already used and trusted. Even the
       | people at Firefox figured out that it would be near impossible to
       | replace their C++ infrastructure to use something unproven. I
       | guess rust advocates would have an easier time creating something
       | new and successful rather than preaching that people should throw
       | their code in the garbage just to rewrite it in the language of
       | the day.
        
       | davnicwil wrote:
       | I really like how javascript tooling appears to have followed the
       | make it work -> make it good -> make it fast pattern, which is
       | pretty much always the correct way to build software.
       | 
       | It is reassuring that we have actually got the feature sets and
       | interfaces correct, since we are now, at last, turning to making
       | stuff really fast. If we had started with speed being the goal of
       | tools, I'd wager they would have been nowhere near the standard
       | they are today in those regards.
        
         | c7DJTLrn wrote:
         | >make it good
         | 
         | Wait, when did that happen?
        
           | Already__Taken wrote:
           | to be fair they didn't say it has completed the progression
           | through that program.
        
           | layer8 wrote:
           | Even "make it work" is debatable.
        
           | te_chris wrote:
           | This got a genuine laugh from me. Stockholm syndrome is a
           | prerequisite for writing JS
        
           | zeroxfe wrote:
           | I'd say when ES6 landed. I used to hate JS, but since ES6, I
           | think it's a pretty good language for building frontends.
        
       | vzaliva wrote:
       | Picking a random example from the article: "Deno's linter, code
       | formatter, and docs generator". Why you need to write a tool like
       | this in low-level system language like Rust? And please, do not
       | answer "performance" because: a) it is not critical for tool like
       | this b) many other high-level modern languages for this type of
       | project will give performance only marginally inferior to low-
       | lewel implementation in Rust or C.
        
         | VWWHFSfQ wrote:
         | what should it be written in
        
           | bruce343434 wrote:
           | Javascript
        
             | [deleted]
        
         | nicoburns wrote:
         | JavaScript linters and more specifically the TypeScript type
         | checker are one of things that slow my computer down the most
         | at work. Probably doesn't help that I have 7 projects open at
         | once, but that's the nature of working a micro services based
         | code based. Performance absolutely matters for this kind of
         | code.
         | 
         | Many other high levels languages might give you the performance
         | you need, but JavaScript won't, and not many languages are as
         | nice to use as Rust. So if you have to do it in another
         | language then it's a good pick.
        
         | Asraelite wrote:
         | I use Rust for a lot of things where performance is completely
         | irrelevant. It has a lot of nice features and benefits other
         | than memory safety and performance.
        
         | howdydoo wrote:
         | I'll go ahead and answer "performance". People are switching to
         | these faster tools because speeding up the edit-compile-run
         | cycle speeds up their work.
         | 
         | Yes, it's theoretically possible to write fast tools in JS, but
         | somehow after all these years and millions/billions of dollars
         | invested in the V8 JIT, they are all still slow enough that
         | people will switch to newer tools, with fewer features, purely
         | for the performance win. And these new tools end up faster with
         | little developer time spent on profiling/optimization, because
         | performant code is in the pit of success.
         | 
         | I also wouldn't think of Rust as a low-level language. It has
         | plenty of high-level features like macros, typeclasses,
         | iterators that are nicer than in JS, etc. Speaking as a
         | developer, these make Rust much nicer/faster to use than other
         | languages that lack these things.
        
       | blondin wrote:
       | yesterday, i recommended "the c programming language" here on HN.
       | and i wanted to see if it's still a number one best seller on
       | amazon. i was quite surprised.
       | 
       | "the rust programming language" has taken over "the c programming
       | language" in the "c programming" best sellers mind you!
       | 
       | i am getting more and more curious about this language. i have
       | avoided it for a long time because of the inconsistent syntax i
       | have seen in the wild.
        
         | leetrout wrote:
         | The syntax feels more unusual than some others but it isnt so
         | bad once you use it.
         | 
         | It still baffles me when i try to understand parts of it in
         | isolation. As with all things it normalizes with exposure.
        
         | worik wrote:
         | > i have avoided it for a long time because of the inconsistent
         | syntax i have seen in the wild.
         | 
         | What do you mean?
        
           | tialaramex wrote:
           | I'm intrigued too. One obvious cause of "inconsistent syntax"
           | would be if you saw any pre-1.0 Rust. Early Rust is a very
           | different animal, it has a different concurrency model, it
           | has a garbage collector, and the syntax is not at all like it
           | is today. Such radical changes would of course be completely
           | unacceptable for an industrial language, and sure enough 1.0
           | is the end of it.
        
             | worik wrote:
             | There have been some changes since too.
             | 
             | I am hazy, not done as much Rust as I would like
             | 
             | I am interested in what the issues are people have had
        
           | nabakin wrote:
           | I'm wondering about this too.
        
         | runevault wrote:
         | It seems as though the C Programming category on Amazon really
         | just means System Programming. I've seen several different Rust
         | books show up high on that list in the past several months
         | (normally by looking at the book and seeing it listed as rank
         | #x on that list, I don't tend to look at the C language list).
        
       | codethief wrote:
       | It's been 16 or 17 years since I wrote my first line of
       | JavaScript and I still hate the language and almost everything
       | that comes with it. The language is still arcane, even if or
       | sometimes even more so if you use TypeScript; browser
       | incompatibilities are still prevalent (though not as ugly as they
       | used to be); and even popular libraries are barely documented and
       | you regularly have to wade through hundreds of wannabe tutorials
       | on Medium/Hackernoon/... by people who, as it turns out, don't
       | have a clue any more than you do, until you finally come across
       | that one open Github issue that explains (and confirms) all the
       | reasons for your frustration. What's more, people are adding more
       | magic and opaqueness to their build pipelines every day. There's
       | not one linker ("bundler", "loader") and one compiler/transpiler,
       | no, there are several. And depending on the bundler, loaders,
       | compiler and transpiler and the target platform, some things like
       | imports might work in completely different ways. (If you thought
       | getting imports right in Python was difficult, good luck with
       | JS.) Of course, these often happen to be precisely the things
       | that are not well documented at all.
       | 
       | I'm not sure what the point of my post is, other than to vent. I
       | guess sometimes I just wish we would get rid of JavaScript
       | entirely and switch to a sane language with sane build tools.
        
         | ostenning wrote:
         | Your frustrations are felt by many.
         | 
         | Every tool is attempting to dethrone the competition, coming up
         | with yet another way to do the same simple yet infinitely
         | elusive fucking goal: render a website.
         | 
         | The whole ecosystem is fucked
        
         | ASalazarMX wrote:
         | JavaScript was made in like ten days just to add missing
         | interactivity to HTML. If Brendan Eich had known how it was
         | going to be used today, the language would have been very
         | different, if at all.
         | 
         | Edit: it seems I don't have to wonder. Type coercion is one of
         | the worst features IMO, and coincidentally one of his regrets:
         | 
         | > "One of the notorious ones was, 'I'd like to compare a number
         | to a string that contains that numeral. And I don't want to
         | have to change my code to convert the string to a number, or
         | the number to a string. I just want it to work. Can you please
         | make the equals operator just say, Oh this looks like a two,
         | and this looks like a string number two. They're equal
         | enough.'"
         | 
         | > "And I did it. And that's a big regret, because that breaks
         | an important mathematical property, the equivalence relation
         | property... It led to the addition of a second kind of equality
         | operator when we standardized JavaScript." One of the people
         | who helped standardize JavaScript was Guy Steele, one of the
         | co-creators of Scheme. "Guy said, 'Don't worry about it. There
         | are Lisps that have five kinds of equals operators. We'll just
         | add another one.'"
         | 
         | https://thenewstack.io/brendan-eich-on-creating-javascript-i...
        
           | deckard1 wrote:
           | The problem with equality and dynamic typing is rather deep
           | and intractable. Kent Pitman (of Lisp fame) has an entire
           | essay about it: https://www.nhplace.com/kent/PS/EQUAL.html
           | 
           | > If COPY can't be done properly, then neither can EQUAL.
           | And, in fact, that's the case. There is no uniquely
           | determined equality function for complex structures--there
           | are _only arbitrary ones_.
           | 
           | What Steele says about equality is true for Scheme. Everyone
           | has seen the famous "Wat" video of adding "{} + {}" in Ruby
           | or JS. But no one ever mentions Scheme or Lisp:
           | scheme@(guile-user)> (eq? "test" "test")       $1 = #t
           | scheme@(guile-user)> (eqv? "test" "test")       $2 = #t
           | scheme@(guile-user)> (define x "test")       scheme@(guile-
           | user)> (define y "test")       scheme@(guile-user)> (eq? x y)
           | $3 = #f       scheme@(guile-user)> (eqv? x y)       $4 = #f
           | 
           | Of course, if you read the RxRS specs then it's all
           | documented and to be expected. But the same is true for
           | JavaScript. As much as I hate typing the "===", there is
           | precedence.
           | 
           | > breaks an important mathematical property
           | 
           | Even mathematicians get lazy and create new syntax and short
           | cuts to express their ideas. Programming is ultimately a
           | human UI. It's easy to see why automatic type coercion was
           | once popular (and probably will be again, I can almost
           | guarantee this).
        
       ___________________________________________________________________
       (page generated 2021-11-11 23:01 UTC)