[HN Gopher] Farewell, Rust for web
       ___________________________________________________________________
        
       Farewell, Rust for web
        
       Author : skwee357
       Score  : 99 points
       Date   : 2026-02-19 18:42 UTC (4 hours ago)
        
 (HTM) web link (yieldcode.blog)
 (TXT) w3m dump (yieldcode.blog)
        
       | mrbluecoat wrote:
       | Better title: "Farewell, Rust for Web"
        
         | testdelacc1 wrote:
         | Yeah Astro is a great choice for a static or mostly static
         | website. Moving to Astro is not a slight on any other language
         | or framework.
        
           | NewJazz wrote:
           | Aiui they are also migrating their backend api(s) from rust
           | to node. They were already using astro with rust on the
           | backend (after dropping ssr with tera).
        
         | porcoda wrote:
         | Yes. This is one of the things that drives me nuts about a lot
         | of titles on here: the context like "for the web" changes how
         | it's is interpreted a great deal. I see the same thing when I
         | see posts about other languages and AI and such. Context
         | matters versus making it sound like a broad, general statement.
         | Alas, the broad, general statements likely get more
         | engagement..
        
         | dang wrote:
         | Ok, we'll use that above. Thanks!
        
         | bigstrat2003 wrote:
         | Agreed! The context matters a lot. Rust is a great language,
         | but using it for the web is a poor choice just like using JS
         | outside the web is a poor choice. Programming languages all
         | have domains where they do well or poorly, and trying to make a
         | single language work for all cases is a fool's errand.
        
       | aaroninsf wrote:
       | This is oddly timed in as much as one of the big success stories
       | I've heard from a friend is their new practice of having Claude
       | Code develop in Rust, than translate that to WebAssembly.
       | 
       | That seems much more like the future than embracing Node...
       | <emoji here>
        
         | Wintamute wrote:
         | If you're making a web app your fancy rust wasm module still
         | has to interface with the dom, so you can't escape that. Claude
         | might offer you some fake simplicity on that front for awhile,
         | but skeptical that's it fully scalable
        
           | slopinthebag wrote:
           | There are plenty of Rust frameworks that handle this
           | interface for you, including calling Rust functions from JS
           | and JS functions from Rust.
        
       | bryanlarsen wrote:
       | Rust for Web is awesome for adding control interfaces etc to
       | other programs who have a different primary purpose.
       | 
       | And even then I do it by serving JSON API's and not by serving
       | HTML.
        
       | cyberax wrote:
       | Well, yep. People underappreciate the Typescript/JS ecosystem.
       | 
       | Typescript is pretty type-safe, and it's perfectly integrated
       | with hot code reload, debuggers, and all the usual tools. Adding
       | transpilation in that flow only creates friction.
       | 
       | That's also why things like Blazor are going nowhere. C# is nicer
       | than Typescript, but the additional friction of WASM roundtrips
       | just eats all the advantage.
        
         | throw-the-towel wrote:
         | IDK, I still miss Rust's strictness and exhaustive enum
         | matching.
        
           | socalgal2 wrote:
           | I don't know about what other strictness you're referring to
           | but exhaustive enum matching is common check in most TS
           | stacks via eslint. Yea, it's not builtin, just saying there's
           | a solution and it's super common.
        
             | cyberax wrote:
             | You can actually have it built-in (via default case in
             | 'switch' statements having a 'never()' statement). But it's
             | less powerful than Rust's.
        
               | nikeee wrote:
               | Or you don't use the defualt case and rely on definite
               | assignment analysis or checks for returns in every code
               | path.
               | 
               | I find the never type in TS actually being a proper
               | bottom type + having control-flow based types vastly
               | superior to what rust offers.
        
         | mdasen wrote:
         | I think the big thing keeping Blazor back is that C# doesn't
         | work well with WASM. It was built at a time when JIT-optimized
         | languages with a larger runtime were in-vogue. That's fine in a
         | lot of cases, but it means that C# isn't well suited for
         | shipping a small amount of code over the wire to browsers. A
         | Blazor payload is going to end up being over 4MB. If you use
         | ahead of time compilation, that can balloon to 3x more. The
         | fact that C# offers internal pointers makes it incompatible
         | with the current WASM GC implementation.
         | 
         | Blazor performance is around 3x slower than React, it'll use
         | 15-20x more RAM, and it's 20x larger over the wire. I think if
         | Blazor could match React performance, it'd be quite popular. As
         | it stands, it's hard to seriously consider it for something
         | where users have other options.
         | 
         | Microsoft has been working to make C#/.NET better for AOT
         | compilation, but it's tough. Java has been going through this
         | too. I don't really know what state it's at, but (for example)
         | when you have a lot of libraries doing runtime code generation,
         | that's fine when you have a JIT compiler running the program.
         | Any new code generated at runtime can be run and optimized like
         | any other code that it's running.
         | 
         | People do underappreciate the JS/TS ecosystem, but I think
         | there are other reasons holding back stuff running on WASM.
         | With Blazor, performance, memory usage, and payload size are
         | big issues. With Flutter and Compose Multiplatform, neither is
         | giving you a normal HTML page and instead just renders onto a
         | canvas. With Rust, projects like Dioxus are small and
         | relatively new. And before WASM GC and the shared heap, there
         | was always more overhead for anything doing DOM stuff. WASM GC
         | is also pretty new - it's only been a little over a year since
         | all the major browsers supported it. We're really in the
         | infancy of other languages in the browser.
        
       | Paul-E wrote:
       | I want to address this one point:
       | 
       | > Similar thing can be said about writing SQL. I was really happy
       | with using sqlx, which is a crate for compile-time checked SQL
       | queries. By relying on macros in Rust, sqlx would execute the
       | query against a real database instance in order to make sure that
       | your query is valid, and the mappings are correct. However,
       | writing dynamic queries with sqlx is a PITA, as you can't build a
       | dynamic string and make sure it's checked during compilation, so
       | you have to resort to using non-checked SQL queries. And
       | honestly, with kysely in Node.js, I can get a similar result,
       | without the need to have a connection to the DB, while having
       | ergonomic query builder to build dynamic queries, without the
       | overhead of compilation time.
       | 
       | I've used sqlx, and its alright, but I've found things much
       | easier after switching to sea-orm. Sea-orm has a wonderful query
       | builder that makes it feel like you are writing SQL. Whereas with
       | sqlx you end up writing Rust that generates SQL strings, ie re-
       | inventing query builders.
       | 
       | You also get type checking; define your table schema as a struct,
       | and sea-orm knows what types your columns are. No active
       | connection required. This approach lets you use Rust types for
       | fields, eg Email from the email crate or Url from the url crate,
       | which lets you constrain fields even further than what is easy to
       | do at the DB layer.
       | 
       | ORMs tend to get a bad reputation for how some ORMs implement the
       | active record pattern. For example, you might forget something is
       | an active record and write something like "len(posts)" in
       | sqlalchemy and suddenly you are counting records by pulling them
       | from the DB in one by one. I haven't had this issue with sea-orm,
       | because it is very clear about what is an active record and what
       | is not, and it is very clear when you are making a request out to
       | the DB. For me, it turns out 90% of the value of an ORM is the
       | query builder.
        
         | cogman10 wrote:
         | sqlx doesn't build queries, or at least it minimally builds
         | them. Which I think is the thing the OP is complaining about.
         | 
         | And, IMO, making dynamic queries harder is preferable. Dynamic
         | queries are inherently unsafe. Sometimes necessary, however you
         | have to start considering things like sql injection attacks
         | with dynamic queries.
         | 
         | This isn't to poo poo sea-orm. I'm just saying that sqlx's
         | design choice to make dynamic queries hard is a logical choice
         | from a safety standpoint.
        
           | spoiler wrote:
           | They didn't make them hard by design, I think, it's just the
           | limitations of the current API and prioritisation. Dynamic
           | queries are possible, just not trivial
        
             | cogman10 wrote:
             | Nope, it really was part of the design [1]
             | 
             | [1] https://github.com/launchbadge/sqlx/issues/333#issuecom
             | ment-...
        
       | fuddle wrote:
       | The TS/React ecosystem is so mature, it's hard for Rust to
       | compete with it. My optimal stack is currently: Rust on the
       | backend, Typescript/React for web with OpenAPI for shared types.
        
         | ChadNauseam wrote:
         | Running rust in wasm works really well. I feel like I'm the
         | world's biggest cheerleader for it, but I was just amazed at
         | how well it works. The one annoying thing is using web APIs
         | through rust - you can do it with web-sys and js-sys, but it's
         | rarely as ergonomic as it is in javascript. I usually end up
         | writing wrapper libraries that make it easy, sometimes even
         | easier than javascript (e.g. in rust I can use weblocks with
         | RAII)
        
           | resonious wrote:
           | It does work well logically but performance is pretty bad. I
           | had a nontrivial Rust project running on Cloudflare Workers,
           | and CPU time very often clocked 10-60ms per request. This is
           | >50x what the equivalent JS worker probably would've clocked.
           | And in that environment you pay for CPU time...
        
             | ChadNauseam wrote:
             | The rust-js layer can be slow. But the actual rust code is
             | much faster than the equivalent JS in my experience. My
             | project would not be technically possible with javascript
             | levels of performance
        
               | resonious wrote:
               | That's fair and makes sense. In my case it was just a
               | regular web app where the only reason for it being in
               | Rust was that I like the language.
        
         | resonious wrote:
         | I'm doing this now and it's mostly great but the openapi
         | generators are not good. At least the Typescript ones produce
         | confusing function signatures and invalid type syntax in some
         | cases.
        
         | papa0101 wrote:
         | React and its ecosystem is a pile of garbage perpetuated by
         | industry inertia. UseState, useMemo, useThisAndThat where you
         | have to _guess_ whether _that_ dependency will cause a re-
         | render? Or 20 different routers, state managers, query
         | builders? I 'm not even talking about html-in-ts with `!!a &&
         | (<div>...</div>)` A stodgy, bloated, overhyped and misused
         | monstrosity, that's what React is.
        
         | user205738 wrote:
         | Why not Angilar? React and Angular are not worth comparing
         | directly, but why not use Angular for the web interface?
        
       | robviren wrote:
       | I find the dependency creep for both rust and node unfortunate.
       | Almost anything I add explodes the deps and makes me sweat for
       | maintenance, vulnerabilities, etc. I also feel perpetually
       | behind, which I think is basically frontend default mode. Go does
       | the one thing I wish Rust had more of which is a pretty darn
       | great standard library with total backwards compatibility
       | promises. There are awkward things with Go, but man, not needing
       | to feel paranoid and how much can be built with so little _feels_
       | good. But I totally understand just getting crap done and taking
       | off the tin foil. Depends on what you prioritize. Solo devs don
       | 't have the luxury.
        
         | ngrilly wrote:
         | Same. That's why Go is such a great tool.
        
         | tasn wrote:
         | These are two sides of the same coin. Go has its quirks because
         | they put things in the standard library so they can't iterate
         | (in breaking manners), while Rust can iterate and improve ideas
         | much faster as it's driven by the ecosystem.
         | 
         | Edit: changed "perfect" to "improve", as I meant "perfect" as
         | "betterment" not in terms of absolute perfection.
        
           | incrudible wrote:
           | The cost of "perfecting" an idea here is ruining the broader
           | ecosystem. It is much much better for an API to be kinda
           | crappy (but stable) for historical reasons than dealing with
           | the constant churn and fragmentation caused by, for example,
           | the fifth revision of that URL routing library that everyone
           | uses because everyone uses it. It only gets worse by the
           | orthogonal but comorbid attitude of radically minimizing the
           | scope of dependencies.
        
             | dwattttt wrote:
             | > It is much much better for an API to be kinda crappy (but
             | stable) for historical reasons
             | 
             | But this does more than just add a maintenance burden. If
             | the API can't be removed, architectural constraints it
             | imposes also can't be removed.
             | 
             | e.g. A hypothetical API that guarantees a callback during a
             | specific phase of an operation means that you couldn't
             | change to a new or better algorithm that doesn't have that
             | phase.
        
               | TheDong wrote:
               | Yes you can, and Go has done exactly that.
               | 
               | Realize the "log" api is bad? Make "log/slog". Realize
               | the "rand" api is bad? Make "rand/v2". Realize the
               | "image/draw" api is bad? Make "golang.org/x/image/draw".
               | Realize the "ioutil" package is bad? Move all the
               | functions into "io".
               | 
               | Te stdlib already has at least 3 different patterns for
               | duplicating API functionality with minor backwards-
               | incompatible changes, and you can just do that and mark
               | the old things as deprecated, but support it forever.
               | Easy enough.
        
               | dwattttt wrote:
               | > mark the old things as deprecated, but support it
               | forever
               | 
               | Is that 'supported'? A library that uses a callback that
               | exists in 'log' but not in 'slog'; it'll compile forever,
               | but it'll never work.
               | 
               | 'Compiles but doesn't work' does not count as stable in
               | my book. It's honestly worse than removing the API: both
               | break, but one of them is noticed when the break happens.
        
             | TheDong wrote:
             | Which has been working great for go, right. They shipped
             | "log" and "flag" stdlib packages, so everyone uses... well,
             | not those. I think "logrus" and "zap" are probably the most
             | popular, but there's a ton of fragmentation in Go because
             | of the crappy log package, including Go itself now shipping
             | two logging packages in the stdlib ('log/slog').
             | 
             | Rust on the other hand has "log" as a clear winner, and
             | significantly less overall fragmentation there.
        
             | bobbylarrybobby wrote:
             | I think "the fifth revision of that URL routing library
             | that everyone uses" is a much less common case than "crate
             | tried to explore a problem space, five years later a new
             | crate thinks it can improve upon the solution", which is
             | what Rust's conservatism really helps prevent. When you
             | bake a particular crate into std, competitor crates now
             | have a lot of inertia to overcome; when they're all third-
             | party, the decision is not "add a crate?" but "replace a
             | crate?" which is more palatable.
             | 
             | Letting an API evolve in a third-party crate also provides
             | more accurate data on its utility; you get a lot of eyes on
             | the problem space and can try different (potentially
             | breaking) solutions before landing on consensus. Feedback
             | during a Rust RFC is solicited from a much smaller group of
             | people with less real-world usage.
        
           | aatd86 wrote:
           | There is a moral hazard here. By accepting that APIs are
           | forever, you tend to be more cautious and move toward getting
           | it right the first time. Slower is better... And also faster
           | in the long run, as things compose. Personally, I do believe
           | that there is one best way to do things quite often, but time
           | constraints make people settle.
           | 
           | At least it is my experience building some systems.
           | 
           | Not sure it is always a good calculus to defer the hard
           | thinking to later.
        
           | JetSetIlly wrote:
           | The golang.org/x/ namespace is the other half of the standard
           | library in all but name. That gets iterated often.
           | 
           | For stuff in the standard library the versioning system is
           | working well for it. For example, the json library is now at
           | v2. Code relying on the original json API can still be
           | compiled.
        
         | bryanlarsen wrote:
         | Python used to have a great standard library, too. But now it's
         | stuck with a bunch of obsolete packages and the packaging story
         | for Python is awful.
         | 
         | In a decade or so Go the awkward things about Go will have
         | multiplied significantly and it'll have many of the same
         | problems Python currently has.
        
           | mixmastamyk wrote:
           | Lots of removals have already happened and uv took over
           | packaging in Python-land.
        
             | encrux wrote:
             | Which, ironically, is written in rust
        
               | smokel wrote:
               | Well, Python is largely written in C, so there's that.
        
           | __mharrison__ wrote:
           | I just ported (this week) a 20-year-old Python app to
           | uv/polars. (With AI it took two days). App is now 20x faster.
        
             | minimaxir wrote:
             | Both uv and polars are technically Rust, too.
        
           | xnyan wrote:
           | > the packaging story for Python is awful.
           | 
           | Big caveat that this is just for me personally, but uv has
           | fixed this for me personally. Game changing improvement for
           | Python. Appropriately, uv is written in rust.
        
         | TheDong wrote:
         | I've found Go's standard library to be really unfortunate
         | compared to rust.
         | 
         | When I update the rust compiler, I do so with very little fear.
         | My code will still work. The rust stdlib backwards compatible
         | story has been very solid.
         | 
         | Updating the Go compiler, I also get a new stdlib, and suddenly
         | I get a bunch of TLS version deprecation, implicit http2
         | upgrades, and all sorts of new runtime errors which break my
         | application (and always at runtime, not compiletime). Bundling
         | a large standard library with the compiler means I can't just
         | update the tls package or just update the image package, I have
         | to take it or leave it with the whole thing. It's annoying.
         | 
         | They've decided the go1 promise means "your code will still
         | compile, but it will silently behave differently, like suddenly
         | 'time1 == time2' will return a different result, or
         | 'http.Server' will use a different protocol", and that's
         | somehow backwards compatible.
         | 
         | I also find the go stdlib to have so many warts now that it's
         | just painful. Don't use "log", use "log/slog", except the rest
         | of the stdlib that takes a logger uses "log.Logger" because it
         | predates "slog", so you have to use it. Don't use the non-
         | context methods (like 'NewRequest' is wrong, use
         | 'NewRequestWithContext', don't use net.Dial, etc), except for
         | all the places context couldn't be bolted on.
         | 
         | Don't use 'image/draw', use 'golang.org/x/image/draw' because
         | they couldn't fix some part of it in a backwards compatible
         | way, so you should use the 'x/' package. Same for syscall vs
         | x/unix. But also, don't use 'golang.org/x/net/http2' because
         | that was folded into 'net/http', so there's not even a general
         | rule of "use the x package if it's there", it's actually "keep
         | up with the status of all the x packages and sometimes use them
         | instead of the stdlib, sometimes use the stdlib instead of
         | them".
         | 
         | Go's stdlib is a way more confusing mess than rust. In rust,
         | the ecosystem has settled on one logging library interface, not
         | like 4 (log, slog, zap, logrus). In rust, updates to the stdlib
         | are actually backwards compatible, not "oh, yeah, sha1 certs
         | are rejected now if you update the compiler for better compile
         | speeds, hope you read the release notes".
        
           | throwaway894345 wrote:
           | Man, I've been using Go as my daily driver since 2012 and I
           | think I can count the number of breaking changes I've run
           | into on one finger, and that was a critical security
           | vulnerability. I have no doubt there have been others, but
           | I've not had the misfortune of running into them.
           | 
           | > Don't use "log", use "log/slog", except the rest of the
           | stdlib that takes a logger uses "log.Logger" because it
           | predates "slog", so you have to use it.
           | 
           | What in the standard library takes a logger at all? I don't
           | think I've ever passed a logger into the standard library.
           | 
           | > the ecosystem has settled on one logging library interface,
           | not like 4 (log, slog, zap, logrus)
           | 
           | I've only seen slog since slog was added to the standard
           | library. Pretty sure I've seen logrus or similar in the
           | Kubernetes code, but that predated slog by a wide margin and
           | anyway I don't recall seeing _any_ loggers in library code.
           | 
           | > In rust, the ecosystem has settled on one logging library
           | interface
           | 
           | I mean, in Rust everyone has different advice on which crates
           | to use for error handling and when to use each of them. You
           | definitely don't have _more standards_ in the Rust ecosystem.
        
             | TheDong wrote:
             | > I don't think I've ever passed a logger into the standard
             | library.
             | 
             | `net/http.Server.ErrorLog` is the main (only?) one, though
             | there's a lot of third-party libraries that take one.
             | 
             | > I've only seen slog since slog was added to the standard
             | library
             | 
             | Most go libraries aren't updated yet, in fact I can't say
             | I've seen any library using slog yet. We're clearly
             | interfacing with different slices of the go ecosystem.
             | 
             | > in Rust everyone has different advice on which crates to
             | use for error handling and when to use each of them. You
             | definitely don't have _more standards_ in the Rust
             | ecosystem.
             | 
             | They all are still using the same error type, so it
             | interoperates fine. That's like saying "In go, every
             | library has its own 'type MyError struct { .. }' that
             | implements error, so go has more standards because each
             | package has its own concrete error types", which yeah,
             | that's common... The rust libraries like 'thiserror' and
             | such are just tooling to do that more ergonomically than
             | typing out a bunch of structs by hand.
             | 
             | Even if one dependency in rust uses hand-typed error enums
             | and another uses thiserror, you still can just 'match' on
             | the error in your code or such.
             | 
             | On the other hand, in Go you end up having to carefully
             | read through each dependency's code to figure out if you
             | need to be using 'errors.Is' or 'errors.As', and with what
             | types, but with no help from the type-system since all
             | errors are idiomatically type-erased.
        
         | slopinthebag wrote:
         | Those deps have to come from somewhere, right? Unless you're
         | actually rolling your own everything, and with languages that
         | don't have package managers what you end up doing is just
         | adding submodules of various libraries and running their cmake
         | configs, which is at least as insecure as NPM or Crates.io.
         | 
         | Go is a bit unique a it has a really substantial stdlib, so you
         | eliminate some of the necessary deps, but it's also trivial to
         | rely on established packages like Tokio etc, vendor them into
         | your codebase, and not have to worry about it in the future.
        
           | Mond_ wrote:
           | The tradeoff Go made is that certain code just _cannot be
           | written_ in it.
           | 
           | Its STD exists because Go is a language built around a "good
           | enough" philosophy, and it gets painful once you leave that
           | path.
        
             | threatofrain wrote:
             | I see this as also a statement on the liveliness of Go 3rd-
             | party ecosystem. It's tangential but I'd also say that the
             | Go community, in terms of the actual people, are a bit more
             | quiet (relative to their size) in terms of hosting meetups,
             | having discussions on chat, etc.
        
           | pjerem wrote:
           | > Go is a bit unique a it has a really substantial stdlib
           | 
           | It's not that unique though. I can say that Python and hell,
           | even PHP have pretty complete but also well documented
           | stdlib.
           | 
           | Java is meh tier but C# is also pretty good in this aspect.
           | 
           | It's totally a choice for Rust not to have a real stdlib and
           | actually I feel like that would maybe make Rust maybe the
           | best language overall.
        
         | onyx228 wrote:
         | The dependency creep keeps on happening in web frameworks where
         | ever you look.
         | 
         | I was thinking of this quote from the article:
         | 
         | > Take it or leave it, but the web is dynamic by nature. Most
         | of the work is serializing and deserializing data between
         | different systems, be it a database, Redis, external APIs, or
         | template engines. Rust has one of the best (de)serialization
         | libraries in my opinion: serde. And yet, due to the nature of
         | safety in Rust, I'd find myself writing boilerplate code just
         | to avoid calling .unwrap(). I'd get long chain calls of .ok_or
         | followed by .map_err. I defined a dozen of custom error enums,
         | some taking other enums, because you want to be able to handle
         | errors properly, and your functions can't just return any
         | error.
         | 
         | I was thinking: This is so much easier in Haskell.
         | 
         | Rather than chains of `ok_or()` and `map_err()` you use the
         | functor interface
         | 
         | Rust:
         | 
         | ``` call_api("get_people").map_or("John Doe", |v|
         | get_first_name(v)).map_or(0, |v| get_name_frequency(v)) ```
         | 
         | Haskell:
         | 
         | ``` get_first_name . get_name_frequency <$> callApi
         | "get_people" ```
         | 
         | It's just infinitely more readable and using the single `<$>`
         | operator spares you an infinite number of `map_or` and `ok_or`
         | and other error handling.
         | 
         | However, having experience in large commercial Haskell
         | projects, I can tell you the web apps also suffer from the
         | dreaded dependency explosion. I know of one person who got
         | fired from a project due to no small fact that building the
         | system he was presented with took > 24 hours when a full build
         | was triggered, and this happened every week. He was on an older
         | system, and the company failed to provide him with something
         | newer, but ultimately it is a failing of the "everything and
         | the kitchen sink" philosophy at play in dependency usage.
         | 
         | I don't have a good answer for this. I think aggressive
         | dependency reduction and tracking transitive dependency lists
         | is one step forward, but it's only a philosophy rather than a
         | system.
         | 
         | Maybe the ridiculous answer is to go back to php.
        
           | slopinthebag wrote:
           | 24 hours? is the haskel compiler written in javascript
           | running in a python js-interpreter written in bash?
        
           | zozbot234 wrote:
           | Rust has trouble supporting higher-kinded types like Functor
           | (even though an equivalent feature is available, namely
           | Generic Associated Types) due to the distinctions it makes
           | between owned and referenced data that have no equivalent in
           | Haskell. Whether these higher abstractions can still be used
           | elegantly despite that complexity is something that should be
           | explored via research, this whole area is not ready for
           | feature development.
        
           | loglog wrote:
           | php is the only popular language that regularly removes
           | insane legacy cruft (to be fair, they have more insane cruft
           | than almost any other language to begin with).
        
         | rubyn00bie wrote:
         | Honestly this is one of the biggest reasons I stick with
         | Elixir. Between Elixir's standard library, the BEAM/OTP, and
         | Phoenix (with Ecto)--- I honestly have very few dependencies
         | for web projects. I rarely, at this point, find the need to add
         | anything to new projects except for maybe Mox (mocking library)
         | and Faker (for generating bits of test data). And now that the
         | Jason (JSON) library has been more or less integrated into OTP
         | I don't even have to pull it in. Elixir dev experience is truly
         | unmatched (IMHO) these days.
        
         | pstuart wrote:
         | With Go it's good to keep in mind the Proverbs, which includes
         | this gem:                 A little copying is better than a
         | little dependency.
        
           | Ygg2 wrote:
           | Good luck, if little copying is ICU based localization.
        
       | NewJazz wrote:
       | _due to the nature of safety in Rust, I'd find myself writing
       | boilerplate code just to avoid calling .unwrap(). I'd get long
       | chain calls of .ok_or followed by .map_err. I defined a dozen of
       | custom error enums, some taking other enums, because you want to
       | be able to handle errors properly, and your functions can't just
       | return any error._
       | 
       | This can be a double edged sword. Yes, languages like python and
       | typescript/JavaScript will let you not catch an exception, which
       | can be convenient. But that also often leads to unexpected errors
       | popping up in production.
        
       | eYrKEC2 wrote:
       | I looove Rust for the backend.
       | 
       | I've supported backends in typescript, python, Java, and Rust.
       | 
       | Rust pages me the least at night. Sleep is beautiful.
        
       | chrash wrote:
       | the idea of one language to rule them all is very compelling.
       | it's been promised a lot, and now everyone hates Java.
       | 
       | but the truth is that Rust is not meant for everything. UI is an
       | abstraction layer that is very human and dynamic. and i can come
       | and say, "well, we can hide that dynamism with clever graph
       | composition tricks" a la Elm, React, Compose, etc, but the
       | machinery that you have to build for even the simplest button
       | widget in almost every Rust UI toolkit is a mess of punctuation,
       | with things like lifetimes and weird state management systems.
       | you end up building a runtime when what you want is just the UI.
       | that's what higher level languages were made for. of course data
       | science could be done in Rust as well, but is the lifetime of the
       | file handle you're trying to open really what you're worried
       | about when doing data analysis?
       | 
       | i think Rust has a future in the UI/graphics engine space, but
       | you have to be pretty stubborn to use it for your front end.
        
         | bryanlarsen wrote:
         | Rust is "Jack of all trades, master of some".
         | 
         | There are real advantages to choosing a jack of all trades
         | language for everything; for example it makes it easier for an
         | engineer on one part of your project to help out on a different
         | part of your project.
         | 
         | But it sounds like the OP didn't get any of the benefits of
         | "jack of all trades", nor did he choose a field where Rust is
         | "master of some".
        
           | bitwize wrote:
           | Lisp is the master of all. Or it would be except "Parens?
           | Eugh! Brotha, eugh!"
        
       | wofo wrote:
       | I'm a heavy Rust user and fan, but I'd never pick Rust for web.
       | There are way more mature ecosystems out there to choose from.
       | Why would you waste "innovation tokens" in a Rust-based web
       | application?
        
         | u16 wrote:
         | I enjoyed using Rust/WASM for a web application I made. Once I
         | got the build step figured out, which took a week, the
         | application worked like I wanted right away.
         | 
         | I was trying to build an HTML generator in Rust and got pretty
         | far, but I don't think I'll ever be happy with the API unless I
         | learn some pretty crazy macro stuff, which I don't want. For
         | the latter project, the "innovation tokens" really rings true
         | for me, I spent months on the HTML gen for not much benefit.
        
         | daxfohl wrote:
         | Good to know! You probably saved me a lot of pain.
        
         | jmalicki wrote:
         | For a web backend? Rust is pretty mature there, it doesn't even
         | feel like an innovation token - it's by my favorite thing to
         | use Rust for.
         | 
         | You have very mature webservers, asyncio, ORMs, auth, etc.,
         | it's very easy to write, and the type safety helps a ton.
         | 
         | In 2020 it might have taken some innovation tokens, but the
         | only things that require a ton less (for web backend) are
         | probably Java, python, and node.js, and they all have their
         | unique pain points that it doesn't seem at all crazy?
        
       | taylorallred wrote:
       | Rust shines in user-space systems-level applications (databases,
       | cloud infrastructure, etc.) but definitely feels a bit out of
       | place in more business-logic heavy applications.
        
       | andrewaylett wrote:
       | It's a throwaway comment in the article, but I feel it's
       | important to push back on: HTML is _very definitely_ a
       | programming language, by any reasonable definition of
       | "programming language".
       | 
       | Edit to add: It might not be an imperative language, but having
       | written some HTML and asked the computer to interpret it, the
       | computer now has a programmed capability, determined by what was
       | written, that's repeatable and that was not available apart from
       | the HTML given. QED.
        
         | zem wrote:
         | agreed, it's a hill i am very willing to die on too.
        
         | tracker1 wrote:
         | How would one do an if condition or enumerate a list in HTML
         | alone? For that functionality you need another language to
         | generate/manipulate the HTML.. not to mention interpreting HTML
         | for display.
         | 
         | HTML is a markup language, it's even in the name... but it's
         | not a complete programming language by any stretch.
        
           | andrewaylett wrote:
           | It's not Turing-complete, and as you say, it's a markup
           | language and it's not general purpose. But neither is a
           | necessary component of "programming language".
        
             | Dylan16807 wrote:
             | Ifs and enumerations are a simpler requirement than Turing
             | completeness. They're an even more basic version of giving
             | the computer logic to evaluate.
        
         | Dylan16807 wrote:
         | Please explain how your edit doesn't apply to a .txt file
        
       | zem wrote:
       | rescript [https://rescript-lang.org/] would make a nice middle
       | ground between rust and typescript
        
       | stevage wrote:
       | > And the occasional struggles with typescript where the runtime
       | seems to be changing too often; is it ts-node? tsx? tsm? The
       | built-in typescript runtime in node? deno? bun?
       | 
       | This whole paragraph is so true. The last couple of years have
       | been pretty rough in Node land.
        
       | slopinthebag wrote:
       | As someone who went in the opposite direction from Node to Rust,
       | I feel like OP is just trading one set of problems for another
       | set of substantially worse problems. I guess the grass is always
       | greener in the other ecosystem -\\_(tsu)_/-
       | 
       | Idk, it just feels like OP chose all the wrong approaches with
       | Rust, including using a separate language and ecosystem for the
       | frontend, which is where most of the friction comes from. For
       | example, Dioxus is a React clone that is somehow leagues better
       | than React (and Next.js, too), and it has hot-reloading that
       | brings compiles down to subsecond times, which makes building UI
       | with it just as productive as with Node / Vite etc. I use it for
       | server side code as well and it's great. Compilation times can be
       | an issue with Rust, it's something I miss from Go, but there are
       | ways to improve on it, and just being smart about what deps you
       | include, avoiding overuse of macros etc can make a difference. I
       | know these things were not around when OP started using Rust for
       | their application, but they are around now.
       | 
       | Node and TS are quite frankly inferior to Rust in most ways. Bad
       | language, ecosystem full of buggy unmaintained packages with the
       | worse security profile of all the common languages, no unified
       | build tooling that seems to break your project every 6 months,
       | constant churn of blessed frameworks and tools, an stdlib that is
       | not much more comprehensive than Rust's and outright broken in
       | some ways, at least three different approaches to modules (esm,
       | commonjs, umd, and more...?), I could go on an on. There is a
       | reason why everyone seemingly reinvents the wheel in that
       | ecosystem over and over again -- the language and platform is
       | fundamentally not capable of achieving peoples goals, and every
       | solution developed comes with massive tradeoffs that the next
       | iteration attempts to solve, but that just creates additional
       | issues or regressions for future attempts to tackle.
       | 
       | I've been using Rust with Dioxus and was completely mind blown
       | when I started with it. With barely knowing any Rust (just React)
       | I was able to jump right in and build with it, somehow it was
       | _more_ intuitive to me than most modern JS full stack frameworks.
       | It seemingly already has most if not all of the features that
       | similar JS frameworks have been developing for years, and because
       | it 's written in Rust things like conditional compilation are
       | built into the language instead of being a third party babel
       | plugin. That helps to remove a ton of friction. And it's trivial
       | to build those same apps for desktop and mobile as well,
       | something that's basically not possible with the JS frameworks.
       | 
       | Even stuff like websockets, go try to implement a type safe web
       | socket connection with a server and client in Next.js or Astro.
       | You'll need a ws library, something like Zod for validation, etc.
       | In Rust it's just:                  #[derive(Serialize,
       | Deserialize, Clone, Default)]        enum SocketMessage {
       | Hello(id: i32) }               #[get("/api/ws")]        async fn
       | web_socket(options: WebSocketOptions) -> Websocket<SocketMessage>
       | {          options.on_upgrade(move |mut socket| async move {
       | while let Ok(msg) = socket.recv().await {              match msg
       | { SocketMessage::Hello(id) => {} } // handle messages
       | }          })        }             fn App() -> Component {
       | let mut socket = use_websocket(web_socket);          rsx!{ button
       | { onclick: move || socket.send(SocketMessage::Hello(42), "say
       | hello" } }        }
        
         | killerbreeze wrote:
         | I think this is spot on. I've used Iced and Dioxus and both are
         | great. I do take the author's point that the actual UI code,
         | even in Dioxus, is verbose. It is. And that's a trade off I'm
         | willing to make for guaranteed correctness.
        
           | slopinthebag wrote:
           | I haven't used Iced but re. Dioxus, I don't know if it's
           | necessary more verbose conceptually. One of the most
           | frustrating things with React is handling async updates, and
           | while Rust's async story is conceptually difficult, it's
           | ultimately much easier to reason about (imo). Like are we
           | sure a comparable component in React would be any less
           | verbose?                  let mut breed = use_signal(||
           | "hound".to_string());             let dogs =
           | use_resource(move || async move {
           | reqwest::Client::new()
           | .get(format!("https://dog.ceo/api/breed/{breed}/images"))
           | .send()            .await?
           | .json::<BreedResponse>()            .await        });
           | rsx! {          input {            value: "{breed}",
           | oninput: move |e| breed.set(e.value()),          }
           | div {            display: "flex",            flex_direction:
           | "row",            if let Some(response) = &*dogs.read() {
           | match response {                Ok(urls) => rsx! {
           | for image in urls.iter().take(3) {                    img {
           | src: "{image}",                      width: "100px",
           | height: "100px",                    }                  }
           | },                Err(err) => rsx! { "Failed to fetch
           | response: {err}" },              }            } else {
           | "Loading..."            }          }        }
           | 
           | Imo the RSX here is _much_ less verbose than JSX. Inline
           | match statement, inline if statement, inline for loop,
           | .take(3) compared to `Array.from({ length: 3 }).map((_, i) =
           | > urls[i]))`, etc etc. This gives you automatic cancellation
           | of the future, whereas with React you would need a third
           | party library like React Query, and then manually abort
           | requests in the asynchronous function with an abort signal --
           | in Rust, you get that for free. You also get data validation
           | for free, instead of needing eg. Zod for manual runtime
           | validation.
        
       | tracker1 wrote:
       | I would assume today that maybe Dioxus or Leptos would be
       | considered. Though that would be the "all in" approach on Rust
       | front to back... it wouldn't really reduce some of the handling
       | conditions levied in the article though.
       | 
       | I find C# can be a really good middle ground on the backend (not
       | a blazor fan)... the syntax and expressiveness improves with
       | every release. You can burrow as lot of patterns from the likes
       | of Go as well as FP approaches. What I don't care for are
       | excessively complex (ie: "Enterprise") environments where
       | complexity is treated like a badge of honor instead of the burden
       | of spaghetti that it is in practice.
        
       | Kalpaka wrote:
       | I run Rust/Axum for something that's less a web app and more a
       | living system -- autonomous agents, real-time state (pulse, mood,
       | health metrics), a frontend that shifts based on internal
       | conditions rather than just user input.
       | 
       | For this kind of use case, Rust's type system isn't overhead --
       | it's the reason things stay coherent when multiple agents are
       | running concurrently. The error handling that feels like
       | boilerplate in a CRUD app actually matters when a missed unwrap
       | means your system silently stops working at 3am.
       | 
       | The article reads to me like someone building a content site in
       | Rust, which yeah, is painful for no reason. But I'd push back on
       | the broader framing -- the web is more than blogs and dashboards.
       | When your backend does meaningful autonomous work beyond
       | serializing JSON, Rust pays for itself.
        
         | lloydatkinson wrote:
         | This comment sounds like an AI wrote it.
        
       ___________________________________________________________________
       (page generated 2026-02-19 23:01 UTC)