[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)