Seed creator here. For some context, I now code all my websites in HTML, CSS, and targeted JS (ie no frameworks or dependencies). Writing this was a great way to learn the ins and outs of DOM manipulation!
Overall, I'm happy with the way the Seed API turned out, but could never get the performance or package size to a good place.
That said, I love coding in Rust, and use it all the time for embedded!
I'll just say I really enjoy the "Why not Seed?" section of your readme. The honesty is refreshing and it really let me know the plusses/minuses of this.
I agree. The modern hip thing to do that many consider as “having character” is to wax hyperbolically about one’s most likely pretty janky code. I see this a lot with neovim packages and it’s rather annoying, though I can appreciate the enthusiasm.
> Are there any examples beating "HTML, CSS, and targeted JS" on typical webpage usecases?
No, and you won't find any. That's not the use case for WASM right now. If your JavaScript code's purpose is to manipulate HTML/CSS, then using WASM will likely make it slower and worse.
That will change and WASM gains the ability to access the DOM without going through JS, but that requires many other big features like GC and reference types, and given that there's not a lot of people working on these things anymore after the Mozilla implosion, it might take many years still, or even never happen.
Absolutely! The difference is dramatic for many types of functions.
You can write a full checkers game engine in a single wasm file weighing in at about 1500 bytes. I only use this example because I worked through it as a continuation of the 853 byte partial implementation in the pragprog wasm book. Even optimized and minified JS ends up being a far larger file for any similar amount of logic.
I could see some huge wins from rewriting popular JS utility libraries in web assembly, but of course it depends on the library how much sense it makes. There are limitations around DOM manipulation, as others have pointed out, but I'm sure we'll see more and more wasm over time.
That's an interesting perspective! As someone considering seed, do you consider it a useful thing to pursue Rust as a frontend language in its current form and given the state of the ecosystem? Obviously you decided to go pretty deep exploring this topic and eventually went a different route but I'd be grateful if you could share some insight here.
At work we built a customer dashboard using Yew (another Rust frontend framework) and absolutely love it. We share API models as a crate between frontend and backend (also Rust) and the same developers work on both. Definitely would never look back, unless larger browser support was a concern. (In our B2B SaaS it hasn't been an issue at all.)
Subjectively, no. Rust is a pleasure to work with for business logic, and some things like dates and times are much easier (via Chrono) than JS, but overall, modern JS is the way to go for DOM manipulation.
For anything low level like embedded, I highly recommend Rust.
For backend/servers, the language is fine, but it has no mature frameworks like Rails or Django. More like Flask analogues.
WASM in general is not suitable for DOM manipulation because it can't manipulate the DOM without calling into JS, which comes with a performance penalty. Hopefully that will change with future versions of WASM.
Not GP but as someone who loves Rust and spent a lot of time trying to use it as a FE language, I settled on F# for my own frontend projects. It has many of the nice things Rust has (discriminated unions, pattern matching, ML inspired syntax) but is much more aimed at typical business logic apps.
With Fable compiler in the frontend and .NET core on backend, you can write the same language on both and even share interfaces, types etc. and it’s just a pleasure to use. If you haven’t tried the .NET ecosystem in the past few years, it’s come a looong way from the old windows only days.
- VDOMs in general have poor performance; they perform unnecessary computations in the diffing algorithm, and even well-designed ones perform extra DOM manipulations, compared to deliberately-written code.
- The Rust WASM files would come out pretty large; a few hundred KB for a minimal app. This is better than some packages using React + common JS dependencies like Lodash and Moment, but with much room for improvement
- DOM manipulation calls made in Rust via WASM(currently!) don't have any performance benefit over the native JS API
Hi, author of Sycamore here. What kind of ergonomic improvements are you thinking about? If this is something actionable, it would be great if you could open a new issue on our repo.
At one point I prototyped a wasm framework inspired by Solid[1]. The results were very promising—an implementation of js-framework-benchmark was 41KB (18KB gzipped), and perforrmance was close to vanillajs. The developer ergonomics were definitely lacking, though.
Benchmark results (look for "cope")[2][3]
I definitely think whatever happens over the next few years, VDOMs are on their way out.
So your framework works on DOM? I thought that WASM - DOM interop is not so great and generally WASM apps would work by doing their own rendering on canvas, skipping DOM.
1. The Elm architecture seems to flow nicely in Rust.
2. The way of defining the elements on the page is more Rust like rather than html like. I initially tried Yew which is another similar framework, but since I am a more backend developer, I found writing in a more Rust style more comfortable than writing in a more html-like dsl. Other with different experiences may be more comfortable with more html-like syntax.
3. Very easy to perform REST API calls. I am using Actix for the backend, and I have a shared library that declares the types which both the backend and frontend use. This is one big advantage for using Rust for both backend and frontend, in that you never have to worry about your types getting out of sync.
4. In general as to why Rust for the front end, apart for being able to share types, for more complex algorithms, for me, having a compiled language with an emphasis on safety and that tries to ensure correctness as much as compile time (and especially pattern matching) makes writing complex code more enjoyable for me.
5. Excellent documentation on the Seed website. There are lots of examples and walkthroughs of basics as well as examples of how to do stuff like integrate with Javascript libraries.
Anyway, thanks again to the authors for making and supporting such an awesome library.
- This is one big advantage for using Rust for both backend and frontend, in that you never have to worry about your types getting out of sync.
One thing to be aware of here, you may have users with stale clients after deploying an update to the server. e.g. picture someone who leaves a tab open for a week and then comes back to it and interacts with your app some more without refreshing.
Text based serializations will tend to be more forgiving of changes in the RPC schema (in the sense of erroring out when required fields are missing), while more compact serializations are more likely to incorrectly decode a message when they should fail.
The quick and dirty solution to this is to have a client response handler that checks for a header set on responses to ensure its a compatible version, then prompt a page refresh if not.
At this point, I feel like this is the most consistent way. There are notable web apps that do this. There are plenty of good reasons for this, including caching and service workers.
It feels dirty because you’re not handling these issues silently. But it’s explicit, clear and it enables a consistent and performant experience.
An equally-quick but not-at-all-dirty version of this is to use the Accept header and do content negotiation. There is a solution to this exact problem in the HTTP spec.
One thing you can do in the shared library is to have a version number constant that is always passed in the rpc. That way if the client is stale, it can easily be detected, and you only have to change 1 place when you update the shared structs.
> This is one big advantage for using Rust for both backend and frontend, in that you never have to worry about your types getting out of sync.
Of course this is a hack compared to Rust BE and FE, but I’ve been finding that auto-generating Typescript type definitions from a Pydantic (Python) API works pretty nicely. Of course, what’s going on under the hood there is all a lot uglier than a beautiful modern compiler with an expressive modern type system, but it’s cool that it works.
My most sincere thanks to the author(s) for “Why Not” section. This level of self awareness and transparency makes me so happy; it takes so much guess work and unnecessary back and forth out of the discourse. Again - kudos!
In my opinion, this is the way forward. You cannot convince anyone that does frontend stuff to even try, or EVEN switch to this. We have to prove that this is a viable option, WASM is a viable way, WASM is actually more efficient etc. there are benchmarks and targeted studies... it just seems that browser vendors and devs haven't catched up yet
HTML & CSS is a viable option. HTML is actually more efficient. There are benchmarks and studies, yet they are not needed, as the difference is apparent.
Must we cede control of user agents to random third parties, loading and executing ever more obfuscated, inaccessible, bloated and hostile code? AFAICT, most of the coded loaded in a typical browser serves a user-hostile purpose.
Do you think wasm support should be mandatory for random web pages? Do you think it will not be used to shove even more bloated, hostile etc code? Will it not be used to circumvent/prevent adblockers etc? Do I need to link to a study showing most wasm is used in a hostile manner?
IMO, wasm is a net-negative on the web. Even though it does have significant good uses. It should be (or should have been) opt-in for specific pages that have a good use for it.
So often people get emotional about languages and frameworks. They’re tools, and tools have trade offs. The “Why Not” section recognizes that. Super impressive.
I’d call Sycamore fairly different from Svelte; both eschew VDOM, but they do it in decidedly different ways, which I would summarise as Svelte being a component-oriented compiler primarily modelling reactivity implicitly, but Sycamore being a data-oriented library almost incidentally capable of producing HTML, exclusively modelling reactivity explicitly.
Svelte is a compiler through and through, providing and requiring its own syntax for things like conditionals and iteration, and declaring reactivity at the syntax level, inextricably tying its reactivity to properties on components, except for stores which allow regular JavaScript to get involved in reactivity (though components also get special support for stores via the $foo syntax). Dirty tracking happens at the component level.
Sycamore, on the other hand, is straight Rust (though typically assisted by procedural macros, which I will admit weakens the distinction), with only explicit reactivity (like Svelte’s stores), but keeping track of dependencies at runtime (more like Ember.js) and with things like conditionals handled as regular Rust code, and iteration as just a component that gets given an iterable rather than needing dedicated constructs. Dirty tracking happens at the data level.
(Qualifier: I’m expert with Rust and Svelte, fairly familiar with Ember.js, and quite familiar with some of Sycamore’s similar precursors, but I have only skimmed Sycamore, reading docs and a bit of code; I haven’t actually used it.)
This is a great approach. Ie, declarative coding GUIs (like webapps) is nice, but VDOM is performance overhead, ie unnecessary computation. I haven't looked into how Svelte (Or Sycamore) do it, but being able to compile declarative code into targeted DOM manipulation seems like a best-of-both-worlds.
Looking the home page (which looks to be built with seed-rs), a ~500k wasm file is loaded.
The static part loads fairly fast, but none of the links work until after the wasm loads (you can tell because the header changes)
Looks like the entire site is in the wasm file as no additional network requests are made. Doesn't seem great for general purpose web sites (like your home page).
Is that 500k with or without gzip? With gzip, that would be huge.
Either way there are certain techniques like bundle-splitting and hydration that will probably have to be reinvented for these WASM frameworks, unfortunately. For the moment they're probably better suited to high-complexity browser-based tooling that needs the extra performance, vs simple crud sites.
Edit: on second thought, for an entire multi-page site in one bundle this wouldn't be super huge. I'm used to smaller numbers but I'm also used to split-bundles.
Not that I disagree — it's rather steep — but not super unlike many react/vue based sites.
Frameworks like Next.js can help by adding seamless server side rendering so at least your links will work before your js/wasm is loaded. Maybe seed-rs can move into that direction as well.
It works fine for me on Chrome (Linux or Android), Edge(ium, on Linux and Windows) and Firefox (Linux, for some reason not Android). It fails on Gnome Web (which is WebKit GTK), which is the closest I could get to Safari, because of SharedArrayBuffers being unavailable [0]. It seems like WebKit hasn't re-enabled them since the first Spectre mitigations like Chromium and Firefox have.
One reason it could fail for you on Chrome is that perhaps you tested on iOS; Chrome on iOS shouldn't make or break web applications because Apple forces WebKit onto every browser on that platform, so they're all Safari with a skin. A broken website in iOS Safari is usually broken in all other browsers by Apple's design.
Otherwise the code should work fine on up-to-date Chrome across all real Chrome platforms, unless you specifically toggled flags...
Date inputs were standardized with HTML5, but browser implementations are of variable quality (and, important to designers, variable default look-and-feel, and limited, IIRC, customizability).
There are native solutions in browsers. I think they mean that they'd have to use their own custom "rust to dom" ones, if they didn't like the native browser ones (they do have some limitations around styling and formatting)
Very very recently some do, and they aren't amazing. I'm not even sure Firefox 93 is officially released yet? Safari support was less than a year ago. https://caniuse.com/?search=datetime-local
Don't get me wrong. I'm glad we finally have some consensus, but this should have happened before ES6 (2015!) IMO. jQuery had a date picker before 2009 at least (probably earlier, but I'm not sure).
Author of sauron here, Yes sauron[0] is very much elm-like than any of the other rust framework, and it's very fast. How fast? Fast enough to be used in a text-editor[1] at ~15ms typing latency. It also suited application that has recurring events such as animation[2]
It also supports server-side rendering, and is used in one of my other opensource project svgbob[3]
I've been using it in production for svgbob. There have been a lot of breaking changes for the past month, but things are starting to stabilize[0] in the 0.43.x release. Hopefully the version stays at 0.43.x and no more breaking changes, due to using better, appropriate or more descriptive names in Struct and functions.
It's great to see good wasm frameworks. I know the DOM interaction still requires js bridging, but I'm still interested in knowing rendering performance relative to yew (another wasm framework) and reactjs.
Also last time I tested, the release bundle sizes were quite big, has there been any improvement here?
I'm looking forward to the time when JS bridging isn't required. Once that happens, it should be possible to use Rust as more of a conceptual "drop-in" to the JS DOM-manipulation API - framework or not.
* Avoid keeping types in TypeScript in sync with Rust.
* Do server rendering without including a JavaScript runtime.
* Avoid maintaining a JS stack, including TypeScript, Prettier, ESLint, and a bundler.
Because we split our project into many crates, incremental build times are about 1-2 seconds on a linux desktop. This is not as convenient for quick iteration on UI/UX as hot reload with React, but on the other hand, code that type checks is more likely to run correctly.
Overall, I would say that the trade offs are not clear, even for our unique case where we have a server written in Rust.
I am hopeful that in the future, browsers will enable native DOM access from WASM, and the Rust compiler will support code splitting between multiple WASM entrypoints. When this happens, I think there will be a strong case to recommend Rust for more front end projects.
I should add that we wrote a crate called pinwheel that uses futures-signals for fine-grained reactivity, uses the builder pattern to avoid macros entirely, and supports server rendering:
Yeah the build times were a killer for me. I did a small project with rust->wasm in the front-end, and this was a bit painful compared to a standard react workflow.
It would be really nice if this could be improved in the future.
I tried Seed out a while back, one thing I really enjoyed was the lack of JSX-like views. It's not necessarily the aesthetics of it, it's that it takes ages to compile those macros.
Having two separate coding languages in a single file that switch back and forth is such a ridiculous idea to me. And on top of that, I don't think jsx is any more readable than nested functions.
I like it. For me it makes it dead easy to glance through a file and instantly understand what's the boundary between the view layer and everything else. At the end of the day you're creating HTML, so JSX is like a WYSIWYG from that perspective.
Do you think that Rust (or any other language that compiles to wasm) will become preferred over traditional JS for single page applications and Electron desktop apps? Would there be any advantages to this, or would it be an overkill?
My thoughts;
Pros:
- Definitely will be useful for resource intensive application (rather not the majority of web and desktop apps)
- Better source code protection if you are shipping a proprietary product (some people may view it as a con)
Cons:
- Build times ?
- Larger download size (for web apps)
- Rust is safe, but a GCed language will always be safer and have less low level overhead for the developer
I will never understand why anyone would want to use a compiled language to do front-end development.
The beauty of JS and especially the beauty of ClojureScript is that you can immediately see the effects of your work in an interactive environment. Using the right libraries you can have true hot reloading without destroying state giving you a terrific, fast, fluid development experience.
What are acceptable compile and reload times for you guys loading WASM?
Because dynamic typing is terrible for big projects, and typescript's fake sense of security doesn't cut it. When you know that your code works you don't need to check it in your browser every nanosecond (although you could).
Updating and checking over and over is usually more about getting the ux right than making it work or fixing bugs. A tight feedback loop makes a huge difference when you're iterating on look and feel. If you have to wait 10 seconds and fill out a form or two to restore the full app state after each change, it becomes a nightmare and you'll likely just give up on making a good ux.
There are also lots of frontend bugs that aren't really bugs in the compiler sense, but just cause the user to see a slightly wrong or confusing thing for a given state. Tests can help, but for a UI with a lot going on, there are usually too many possible paths to write tests for them all, so doing a lot of QA as you go is hard to avoid.
Typescript offers a pretty good balance here since you can turn off typechecking for live reloading and instead check types in the background or as part of the test suite.
You don’t need to check it in your browser at all if you wrote proper tests for it. TypeScript (with proper lint rules) is a huge win in my book compared to vanilla JS. That said, Rust’s compiler guarantees are best in class. The hot-reload, want to see it happen immediately, is great for quick prototypes but for large projects, nothing beats full coverage.
You would never want to understand why this is better?
Here is a couple of reasons:
1. It is backed up by a statically typed, safe, elegant language that is like a strict teacher that tells you to fuck off when you make a mistake...
2. HMR is possible with this...
3. Look, WASM is not fighting against you, it is fighting for you... anyone who is targeting JS and is forced to do so is welcome to choose any other language you want...
In clojurescript you can press your slime or calva keystroke to send a form (or an expression from a rich comment) to the browser repl and see that immediately reflect and use the current state of the app without reloading.
What’s the equiv workflow when compiling to wasm? Save file > compile > hot reload? > reconstruct state somehow?
Is it like clojurescript where you interactively work on the app in the same way you might interactively craft a sql statement in a live db?
In Rust, no clue because I've never tried. However, I did find a hot reload of WASM compiled from C++ [1]. If they're not equivalent, I would imagine it's a matter of ecosystem maturity rather than it being impossible.
Realistically, hot reload is going to be something like inotify(7) hooked into a compiler and whatever it takes to reload seamlessly. If it's been solved in one general purpose language, it's likely to be possible in another.
When we say hot reload in javascript (or even better, hot module replacement) or java or rust or c++, there's usually annoying limitations like you can't change the arity of a function or you have to pause all the threads or you need some mechanism to reset state to a known good starting point because we just broke it (potentially).
The difference with a lisp is that you don't need do any of that. You replace the function object in the system image (atomically) and you crack on like nothing happened. No waiting around, no rerunning state into the app. And you triggered it just from a keystroke in your editor.
I fully agree that toolchain you mentioned gives blazing fast initial devX, hot reload and everything. If that’s what you are optimizing for, it is a perfect solution.
OTOH when you want to optimize for long term maintenance, growing codebase that is safe and easy to grow, easy to refactor, easy to check for odd things. I’d lean heavily on something compiled and with promise/guarantee of safety every time.
In other words, it is all about trade offs and to each his own.
I have seen a few of these Rust front-end projects, they are all really great except for the fact that very few support SSR. This is especially important given the fact that it is much slower sending wasm over the wire and instantiating the module and the wasm environment vs plain js
I'm not sure if this is because of the complexity of the undertaking (I imagine it would need some sort of virtual DOM) or just lack of interest
>This is especially important given the fact that it is much slower sending wasm over the wire and instantiating the module and the wasm environment vs plain js
You might be surprised. JS is a very slow language to parse. WASM was designed to be parsed quickly. And browsers have implemented streaming compilation for WASM, which means once the last byte comes over the wire, 99% of the work is already done.
Check out js-framework-benchmark[1] startup metrics. The page weight for Yew (another WASM framework) is pretty heavyweight at 300KB, but it has a consistently faster time-to-interactive than vanillajs.
What makes you think sending WASM over the wire is slower? The payloads should be smaller than JS, assuming you aren't shipping a runtime alongside your code (which Rust doesn't). I don't know about the bootstrapping side, but I know some people use WASM specifically for the small bundle sizes.
The Rust compiler and ecosystem are tuned more towards generating faster code rather than generating smaller code. In my experience, even small wasm apps that are careful about their dependencies end up shipping hundreds of KB of wasm over the wire, and if you're not as careful that easily tips over to MBs.
Time and space are in tension, and the web is more sensitive to binary size than most other targets, including many embedded targets.
To take one example that often contributes a ton to binary size, consider data serialization in Rust vs JS. JS will tend to just use JSON.parse and deserialize into a JS object with little to no data validation. The JS object is then exclusively accessed via dynamic field lookup (with a JIT doing its best to notice patterns and hopefully optimize the hot paths). The same code paths can handle many different message shapes. It's far from optimal in terms of runtime speed, but the code can be made very compact.
Rust deserializers by contrast seem to use compiler-time code generation to produce a different optimized struct layout, parser, and validator for every message type. When I've played with writing very small Rust + wasm apps, the choice of serialization library and format made a huge difference. If I recall correctly, using BSON + serde would have increased my total binary size by more than 3x.
This isn't a fundamental issue with Rust as a language, I think it's partly still early days for the tooling.
There is, however a certain fundamental amount of tension there in what's optimized for. In most environments, 30% faster deserialization for a binary that's 500KB larger (pulling numbers out of my ass) is in the "obviously yes, do that" category, but on the web adding 500KB to your binary is a steep price to pay, particularly for mobile users.
thanks for the correction, was formulating the sentence and somehow "wasm over the wire" injected itself in there. 100% transfering wasm in the binary format is a more efficient transfer than js.
I have been working on a virtual DOM library which will enable a few of these projects to support SSR. But, partly due to lack of interest, and partly due to lack of time on my part, it’s been going slower lately. Still, the effort is ongoing.
There are two steps there: (1) rust-rdom working enough to be used by Yew, and (2) SSR support built out in Yew utilizing rust-rdom. Part (2) is pretty far away, but (1) is probably about halfway there. I think a more realistic use-case for the library is Sycamore which is much earlier and simpler than Yew. Sycamore support has a tracking issue here: https://github.com/rust-rdom/rust-rdom/issues/15
I deleted my first question so that I could read on the subject a little to make sure the question wasn't a stupid one. After doing some reading I still have the same question so here it is again:
Does wasm app save memory significantly at runtime? If not why should one choose manual memory management outside of porting existing code?
I wouldn't imagine here that Rust's value add in this case is the memory management. Instead it's probably the strict and ergonomic control over constness (I prefer rust in that specfic context to js Object.freeze), the typesafe concurrency, and if you're the kind of crazy person that would use rust on the frontend in 2021 you probably are using it in the backend and you can therefore share code.
I could also see it helping with bundle size. Also, while uncommon, it's not impossible for VDOM rendering to be a performance bottleneck on complex apps. I used to work on one where we had enough components on the screen at a time that it was often a problem.
FP with typesafe concurrency hasn't really happened on the frontend yet in meaningful way.
And I wouldn't frame it as Rust succeeding where FP failed, but instead a way to sneak in FP into the frontend in a way that gets really angry at you when you try to structure your code as mutable and imperative. Yes, most of the frontend languages let you opt in to constness and compile time typesafety, but Rust makes you opt out. It's soft developer thing, but it seems to have benefits to code quality from my experience.
FP isn't a technology, it's a way of using technology. You can follow it using JavaScript, or Rust, or Elm, or whatever. But JavaScript doesn't offer true constness (at least, not enforced). Elm does, but no JavaScript-targeted language (including Elm) has proper concurrency at all, type-safe or not (there are Workers, but they come with a bunch of caveats). Rust has good support for FP, type-safe concurrency (whether in an FP style or not), and mostly type-safe constness. Of course it also has its own set of tradeoffs, like anything else.
I'm afraid that just like we have very simple web sites built with large SPA/frontend frameworks, we're gonna soon start seeing those same, but now built with WebAsembly.
Let me be first saying that just like you don't need React, Ember, Angular, etc. to build your site, you also don't need the WASM as well!
This project isn't just using wasm for the sake of it. It's the best browser-supported target language for Rust, so if you want a Rust front-end framework, you're going to compile to wasm.
Why Rust for this application, though? You don't really need to be "close to the metal" in the frontend (and there's wasm overhead in any case), so it seems like it'd be better to go with something a bit higher-level, with GC etc, rather than fight with the borrow checker.
Is there a way to use standard frameworks like bootstrap with this or other similar wasm based rust frontends? Otherwise, it's hard to see how it will ever have enough rich components to really take off.
I had some luck with yew + bulma.io. There's a crate called ybc they implements yew components using bulma classes. I had to reimplement a component myself though because I needed to hoist its state. Doing so wasn't very complicated.
It is higher-level than actix, though it's still surprising to see it as low as it is. I'm curious what the story is there too. It is significantly higher than Express and Flask, though it's lower than raw NodeJS and PHP.
I guess maybe these benchmarks only test the overhead of the framework itself, and ignore the benefits of having your business logic and middleware written in a faster language? The tests for node and PHP would pretty much only be running battle-tested native code if that's what's going on
Is there info on when the 0.5 is supposed to be released? I don't see anything on the Github except that the only issue left on the 0.5 milestone is updating the readme.
Oh yes I like Warp, don't get me wrong, but it's odd compared to the "standard". And the Result/Rejection system used for routing confuses people a lot (which is understandable, its use here is quite at cross purpose with normal uses for a Result).
Looks like an interesting project, how complete is the OpenAPI support? It seems like most Rust web frameworks have an open issue for it/some partial implementation
They are pretty much identical. Seed has better docs, Yew has a promise for multi-threaded stuff, but its not very well documented (or even working). I've tried projects with both and the nice thing with Yew is that the syntax for HTML is kinda compatible with the actual thing (think JSX.) Seed however is macros only. Both seem to compile in the same time, but I would bet there would be differences on bigger projects (which there are none atm?)
Re big projects: I'm (sort of) using Seed on web-based scheduling and training software used by 7 operational fighter squadrons.
The most complicated pages are in React/TS (eg the actual scheduling board), and the Seed pages are/were mostly simpler ones, like tracking qualifications, personalized schedules etc. I'm actively rewriting the smaller pages from Seed/Rust and TS/React to HTML/CSS/JS for performance and simplicity reasons.
Yew predates Seed, and provided inspiration. At the time, Yew wasn't in a usable state. There were no full examples, no documentation, and the starter code in the Readme didn't coincide with the release. I believe they fixed those sometime after Seed's release.
This doesn't directly answer your question, but is the context in why Seed started, with Yew already existing.
An immediately noticeable difference is that Yew uses a JSX-like syntax, while Seed uses a custom API based on list-like macros.
I used both yew and seed, but the svg support is lacking. Both framework don't render svg elements correctly. As I'm the author of svgbob[0], which heavily uses svg. I wasn't satisfied with both of the frameworks, So I created sauron web framework and I was quite happy with the result. Not only I can do an server side rendering for svgbob[0], I can also write a text-editor[1] with it and achieve a ~15ms typing latency.
The code is terse right now, but all of the ideas are there.
In two years, I fully expect Rust to begin taking off as a major frontend language choice. A framework like Seed will help usher this in.
It'll be faster than Javascript, eventually multithreaded, and produce portable binaries that can run on a wide variety of platforms and architectures.
It'll paint to DOM, but also do immediate mode and other types of rendering.
We'll see incredibly rich applications: games, video editors, IDEs, etc.
Electron will yield to this. We'll have fast, cross-platform apps that run not just on the browser, but natively on Windows, Linux, and Mac.
If we're lucky, we might even start writing mobile apps this way and ditch the iPhone/Android specific APIs.
I love your optimism but I think you're overlooking a lot of why we've ended up in the landscape we are now, and it's not because we lacked a well designed language. It's because Javascript is like PHP: easy to learn, quick to develop in, cheap to hire, and just about good enough for people to stick with it.
Don't get me wrong, I hate Javascript as a language. But sometimes worse is better.
[edited to make my point clearer]
This is not about "value" of the language (worse is better) it is just about cost (cheap is better).
Hiring js dev is cheaper because it is cheaper/faster to learn js.
I'd already said JS was quicker to learn and cheaper to hire though. The "worse is better" statement is just a phrase intended to succinctly summarise that point:
> It refers to the argument that software quality does not necessarily increase with functionality: that there is a point where less functionality ("worse") is a preferable option ("better") in terms of practicality and usability. Software that is limited, but simple to use, may be more appealing to the user and market than the reverse.
There is not a single chance that a language like C++ or Rust become mainstream in frontend dev. The complexity of the language is at the opposite side of what webdev is about.
> The complexity of the language is at the opposite side of what webdev is about.
That's not true, current JS is getting complex, but we don't have a choice, except for WASM but the options aren't great. TypeScript is also very complex, but it's the most popular so people use it. Basic Rust isn't that complex, and I would argue is easier than TypeScript. I wouldn't want to be the guy building the framework, but using Rust to write business logic? That might be nice.
On the backend side, Java dominates, with PHP, JS/TS, Python. All of these (in their modern form) are complex, usually by way of OO soup, or big frameworks, or a large ecosystem that you have to learn at first. On the other hand, languages that people like calling "simple" like Go or Clojure are relatively nice (at least for "business logic" web apps, Go is popular for "infra/devops" web stuff").
This is not a fever dream in my opinion, just replace Rust with your favorite language if that language targets WASM. Eventually, JS will be just another choice in a field of languages that would target WASM... then it is just a matter of preference.
Why not? WASM is gaining features after it's MVP, such as GC support, direct targeting with DOM APIs (with reference types and interface types), it's not a fast process, but it's coming. It doesn't take anything away from any programming language, but it provides a more efficient platform for those languages to run... what is there not to like?
Lots of languages target JavaScript too, but only one got very popular, because ecosystem matters a lot. People are going to have to recreate the current JavaScript ecosystem for each languages, and then probably for each framework in that language.
No, not really. The only language that has mindshare in the frontend outside of JavaScript is TypeScript. Elm, CoffeeScript, Rescript and all of these are not known at all. In the JS ecosystem, Angular, React and Vue are king, but React is really fragmented with all the options (Next, etc). All of this because JavaScript is the most popular language in the world. Most other languages won't get that mindshare.
Elm doesn't have the JS ecosystem, Rust doesn't, Rescript doesn't. The thing is, when you're doing backend stuff, it's usually relatively easy to pull a library with whatever framework you're using. On the frontend, for your components, you need basically a library by framework by language.
Not enough people care enough to make it happen. I think most people underestimate the breadth of the work that would have to be done. The people in the best position do do it (the browser vendors) aren’t willing to do that.
Overall, I'm happy with the way the Seed API turned out, but could never get the performance or package size to a good place.
That said, I love coding in Rust, and use it all the time for embedded!