Thanks, this really demystified the concepts for me. Various pointer types aside it's quite intuitively organized. Big fan of Leptos, I've tinkered with a few Rust web frameworks and it has been the most ergonomic by far.
The 2023 (re)-invention of global variables, with lots of code mutating it from everywhere and no where :) This was the "model" I used in the 1980s for my C programs. Now I know it was "reactive" not "spaghetti" :)
I am new to Rust, new to reactive systems and yet this video makes it so easy to understand the concepts and the inner workings. Thank you for the insightful video and clear explanation!
Greg, what a captivating introduction and thorough explanation! I was journeying through TH-cam in search of info on Leptos and serendipitously landed on your masterpiece. It was the guiding light I needed. Immense gratitude to you!
Just coming over from Svelte4 -> Svelte5 ; having to compare/contrast SolidJS style signals in both those frameworks, and seeing your talk just made EVERYTHING make so much more sense. Thank you.
31:29 This is exactly why Rust is so great. Even if it's a runtime borrow-check, it's still a borrow-check, and not a data race. ^^ Same thing in 33:56.
Thanks for video. Super informative. Though the audio is a bit quiet. I'd appreciate it if you could make it louder in the future. I wonder how equivalent JS frameworks handle this. On one hand, they don't need to worry about things like RefCells and pointers. On the other, if they _do_ want to implement that (for performance), I imagine it'd be a lot harder, if not impossible. But I doubt they care. The performance gain is probably marginal for most UIs.
Thank i m new to rust and its so hard for me to tackle wasm closure, your framework are really great and this vidio are plus plus. Now i understand better into borrow checker with your explanation
Would've loved to see you detailing how this system works with effects with multiple code paths, that depend on different signals depending on some other signal, as it will also "discover" all the dependencies as they get relevant during the runtime. Really neat. In some cases, it could even be advantageous to remove entries from the hashmap again as they become irrelevant to the effect again, though most likely this kind of micro-management of subscriptions is probably overkill for the mostly straight-forward effects.
I may be wrong but isn’t this exactly how react hooks work? React maintains one giant array where all the state is maintained (don’t need to do because js is dynamically typed) and it returns the reference to read the state and a function to update the state
This is awesome. My concern is that these signals and effects don't ever seem to be cleaned up, so the innocent single leak in reality turns into a bigger leak as you add more and more of these signal values. Wondering what the approach is to clean those up when the app no longer needs them / references them. I've also built a reactive system but had to use reference counts everywhere for this reason
Perhaps I am a bit late to this great tutorial… on 2:22 , how did you spawn up this web server? And what versions of Leptos and Web sys did you use? I am trying to follow along but the imports seem not to be working… thanks!
Just came back from a Frontend Sheffield Meetup and one of the speakers, an Amazon engineer Tom Johnson, said they were using Leptos in their Prime team for 3rd party devices.
Very interesting! I am wondering, however, if signals (and their associated data stored in Runtime) in leptops ever get freed. I could see this becoming problematic for eg. a popup, where signals and effects are created whenever the popup appears, and won't be needed after the popup closes. Do those values in Runtime just sit there until a page reload?
No this is just a simplified form of it - in reality they are tied to reactive scopes and disposed of appropriately when different parts of the UI and removed. So in that example, the signals would be disposed after the popup is closed.
Very nice. When there will be a rich ecosystem around this framework like a big UI library? Like the Primeng library for Angular? Is such a thing already being build?
This was incredibly interesting, and your explanations were very clear :) One thing that stood out to me is the requirement that the initial call to an effect calls and registers the appropriate signals. If, for example, I had an effect that counted how many times it had run, and didn't call the getter of some signal A on the first run, but only on subsequent runs, could I fool the runtime into declaring the effect as having no dependencies (thus, never running) when in reality it uses the value signal A?
I don't think this toy version actually does it (I'd have to look back) but in real reactive systems like this dependencies are dynamic, so they always only subscribed to the signals accessed on the previous run. You can manually say "track this signal without reading its value" if you want to, which is basically what you're describing I think... "Always run this effect if this signal changes."
Hi, Greg. Can you make a short video on how one can learn the js/wasm interoperability and how the whole machinery works down one level compared to current video. Maybe just a bunch of links, as you probably won't be interested in sharing deeper secrets you've learned and educating instead of spending time developing.
Yeah! Are you thinking like a “How to build some basic stuff with Rust and wasm-bindgen” or “How does wasm-bindgen actually work?” If it’s “how to build some basic stuff” I went on Ryan Carniato’s stream a while ago and walked through this- if it’s “how does wasm-bindgen really work” then yeah but it’s over my head a little :-D
Why not set the current running effect in the create effect method instead of run effect method. because you only need to figure out which effect depend on which signals only once and not every time the signal is run?
Because in a real system you'd really want to newly figure the dependence out every single run: the basic idea is that you want to minimize how often effects are run at basically any cost. If you have have an effect that does something like `if some_signal() { do_something_expensive(signal_1()) } else { do_something_expensive(signal_2()) }` you wouldn't want to rerun the effect if `signal_2` changes while `some_signal` was `true`. Moreover this effect couldn't even subscribe to `signal_2` if `some_signal` started out as false.
Box::leak() gives you a &'static T, which is very useful in particular cases where you want a lifetime with a static reference so that everything that holds it doesn't need to have a lifetime. In this case as it's called once ever, it's not really a leak per se, just a single allocation that doesn't get deallocated until the end of the program.
For sure! In the real library I do it with a thread-local, they’re just slightly more awkward to work with than a static reference so I took the simplest path here.
Could you provide code you created throughout this tutorial? It'd be so helpful to study your code without scrolling youtube video back and forth :p Great work, BTW, many thanks!
Nice video, I hoped you would show conditions inside create_effect and how you unsubscribe first before resubscribing again as you explained in other video
already got lost use leptos::{create_element}; #[derive(Default)] struct Runtime{ } fn main(){ console_error_panic_hook::set_once(); let body :HtmlElement=body().unwrap(); let p =create_element("p"); p.set_text_content(Some("OK")); }
Big fine-grained reactivity fan over here!!!!! ❤❤❤❤
holy
Wow, one of the easiest voices to listen to on TH-cam! Thanks for the video, I'm excited to start my Leptos journey!
Thanks, this really demystified the concepts for me. Various pointer types aside it's quite intuitively organized. Big fan of Leptos, I've tinkered with a few Rust web frameworks and it has been the most ergonomic by far.
The 2023 (re)-invention of global variables, with lots of code mutating it from everywhere and no where :)
This was the "model" I used in the 1980s for my C programs. Now I know it was "reactive" not "spaghetti" :)
That's some impressive coding while presenting , and great explanations along the way
Man, seeing how easy you walk through it and how well you can explain that.. I feel intimidated :D
fantastic presentation, thank you so much!
I'm evaluating leptos for multiple future projects, and it looks very promising to me.
Such a fun demo and really interesting to see how it works under the covers
I am new to Rust, new to reactive systems and yet this video makes it so easy to understand the concepts and the inner workings. Thank you for the insightful video and clear explanation!
Brilliant! Thanks. Really helped me understand the reactive system!!!
Greg, what a captivating introduction and thorough explanation! I was journeying through TH-cam in search of info on Leptos and serendipitously landed on your masterpiece. It was the guiding light I needed. Immense gratitude to you!
Great explanation, really made me interested in dive SolidJS and Leptos internals
Just coming over from Svelte4 -> Svelte5 ; having to compare/contrast SolidJS style signals in both those frameworks, and seeing your talk just made EVERYTHING make so much more sense. Thank you.
31:29 This is exactly why Rust is so great. Even if it's a runtime borrow-check, it's still a borrow-check, and not a data race. ^^
Same thing in 33:56.
That was amazing. I didnt fully understand all the rust parts. But i feel like i finally get signals and effects. Phenomenal video. Thanks a lot
This is fantastic. Please make more videos! I'd love to see you go into the reactive scopes.
This is really helpful. I've been wanting to try Leptos, but I was having difficulty grokking the signals and how the view! macro worked exactly.
Super cool. Needed to watch it a second time to code along. Thanks a ton !!!
Thanks for this! This is a fantastic explanation on how Leptos works.
Thanks for video. Super informative. Though the audio is a bit quiet. I'd appreciate it if you could make it louder in the future.
I wonder how equivalent JS frameworks handle this. On one hand, they don't need to worry about things like RefCells and pointers. On the other, if they _do_ want to implement that (for performance), I imagine it'd be a lot harder, if not impossible. But I doubt they care. The performance gain is probably marginal for most UIs.
Amazing stuff, great rust skills and great simple design for a non-trivial problem/system
Thank i m new to rust and its so hard for me to tackle wasm closure, your framework are really great and this vidio are plus plus. Now i understand better into borrow checker with your explanation
Thank you for this content!! Super excited with what you're building here.
This was really cool.
Thank you for explaining this so beautifully.
You should link these videos in the documentation somewhere as a reference maybe.
its good that you are making content!
Thank-you, a lot of new info to connect up, going to be back to review
Great vid! Thanks! Keep them coming ;)
Love this video. Reminds me of solid's 'introduction to reactivity' video. Very very cool to see it for rust/leptos.
Actually made me understand the solid-video better, the whole subscription-context was a part i could never fully grasp. Very well explained!
Would've loved to see you detailing how this system works with effects with multiple code paths, that depend on different signals depending on some other signal, as it will also "discover" all the dependencies as they get relevant during the runtime. Really neat.
In some cases, it could even be advantageous to remove entries from the hashmap again as they become irrelevant to the effect again, though most likely this kind of micro-management of subscriptions is probably overkill for the mostly straight-forward effects.
Thanks for a great explanation! :)
Thanks for making the video.
I may be wrong but isn’t this exactly how react hooks work?
React maintains one giant array where all the state is maintained (don’t need to do because js is dynamically typed) and it returns the reference to read the state and a function to update the state
Thanks Greg.
love this! thank you
This is awesome. My concern is that these signals and effects don't ever seem to be cleaned up, so the innocent single leak in reality turns into a bigger leak as you add more and more of these signal values. Wondering what the approach is to clean those up when the app no longer needs them / references them. I've also built a reactive system but had to use reference counts everywhere for this reason
Perhaps I am a bit late to this great tutorial… on 2:22 , how did you spawn up this web server? And what versions of Leptos and Web sys did you use? I am trying to follow along but the imports seem not to be working… thanks!
This is such a great video
Just came back from a Frontend Sheffield Meetup and one of the speakers, an Amazon engineer Tom Johnson, said they were using Leptos in their Prime team for 3rd party devices.
Very interesting!
I am wondering, however, if signals (and their associated data stored in Runtime) in leptops ever get freed. I could see this becoming problematic for eg. a popup, where signals and effects are created whenever the popup appears, and won't be needed after the popup closes. Do those values in Runtime just sit there until a page reload?
No this is just a simplified form of it - in reality they are tied to reactive scopes and disposed of appropriately when different parts of the UI and removed. So in that example, the signals would be disposed after the popup is closed.
I’m definitely betting my e-commerce startup on Leptos
Very nice. When there will be a rich ecosystem around this framework like a big UI library? Like the Primeng library for Angular? Is such a thing already being build?
Hi, man. Great content. Very interesting, though hard to grasp in one pass.
do you have the project in github?
❤ it really helped
How current is it in the context of Leptos versions, please? For example, the logic in this video would be mapped to which Leptos version?
This was incredibly interesting, and your explanations were very clear :) One thing that stood out to me is the requirement that the initial call to an effect calls and registers the appropriate signals. If, for example, I had an effect that counted how many times it had run, and didn't call the getter of some signal A on the first run, but only on subsequent runs, could I fool the runtime into declaring the effect as having no dependencies (thus, never running) when in reality it uses the value signal A?
I don't think this toy version actually does it (I'd have to look back) but in real reactive systems like this dependencies are dynamic, so they always only subscribed to the signals accessed on the previous run. You can manually say "track this signal without reading its value" if you want to, which is basically what you're describing I think... "Always run this effect if this signal changes."
Nice video, great start! try to ajust the audio next one pls, its too low.
Nice man!
Does anyone know what that color theme is? I really like it a lot.
Hi, Greg. Can you make a short video on how one can learn the js/wasm interoperability and how the whole machinery works down one level compared to current video. Maybe just a bunch of links, as you probably won't be interested in sharing deeper secrets you've learned and educating instead of spending time developing.
Yeah! Are you thinking like a “How to build some basic stuff with Rust and wasm-bindgen” or “How does wasm-bindgen actually work?” If it’s “how to build some basic stuff” I went on Ryan Carniato’s stream a while ago and walked through this- if it’s “how does wasm-bindgen really work” then yeah but it’s over my head a little :-D
Beautiful
Why not set the current running effect in the create effect method instead of run effect method.
because you only need to figure out which effect depend on which signals only once and not every time the signal is run?
Because in a real system you'd really want to newly figure the dependence out every single run: the basic idea is that you want to minimize how often effects are run at basically any cost.
If you have have an effect that does something like `if some_signal() { do_something_expensive(signal_1()) } else { do_something_expensive(signal_2()) }` you wouldn't want to rerun the effect if `signal_2` changes while `some_signal` was `true`. Moreover this effect couldn't even subscribe to `signal_2` if `some_signal` started out as false.
I got really distracted by the usage of Box::leak earlier in the video. I tried looking around and couldn’t find why we’re using it. Ideas?
Box::leak() gives you a &'static T, which is very useful in particular cases where you want a lifetime with a static reference so that everything that holds it doesn't need to have a lifetime. In this case as it's called once ever, it's not really a leak per se, just a single allocation that doesn't get deallocated until the end of the program.
thank you ❤🎉
Could you make the runtime 'static with something like lazy_static! as well instead of a Box::leak?
For sure! In the real library I do it with a thread-local, they’re just slightly more awkward to work with than a static reference so I took the simplest path here.
Could you provide code you created throughout this tutorial? It'd be so helpful to study your code without scrolling youtube video back and forth :p Great work, BTW, many thanks!
Is this all static?
Nice video, I hoped you would show conditions inside create_effect and how you unsubscribe first before resubscribing again as you explained in other video
Some people I know use Leptos with gtk-rs
Brooo why did you choose the leptospirosis name????
already got lost use leptos::{create_element};
#[derive(Default)]
struct Runtime{
}
fn main(){
console_error_panic_hook::set_once();
let body :HtmlElement=body().unwrap();
let p =create_element("p");
p.set_text_content(Some("OK"));
}
|
301 | pub struct HtmlElement {
| ^^^^^^^^^^^ --
help: add missing generic argument
|
11 | let body :HtmlElement=body().unwrap();
| ++++
error[E0425]: cannot find function `create_element` in this scope
--> cache_front\src\main.rs:13:12
|
13 | let p =create_element("p");
|