This video is sponsored by TryHackMe. Good evening. Tonight I will attempt to answer the question, does Dioxus spark joy or at the very least, whimsy? What is Dioxus, you ask? It is first and foremost a name that is "legally not inspired by any Pokémon", even if the author concedes in a Hacker News comment that the Dioxus Pokémon is, I quote, "awesome". To cover any upcoming legal fees just in case Nintendo doesn't buy the origin story, Dioxus is as of the summer of 2023, a Y Combinator startup. Regulars of this channel might be wondering at this point of what does any of that have to do with Rust? Well, don't worry, I have gone and checked for you. Dioxus is in fact getting money from Huawei, which makes it a Rust project just like any other. Please find on this diagram in red every Rust project funded by Huawei or any other kind of -wei. Dioxus is the promise of having a single code base for your mobile apps and web apps and desktop apps. It makes me think of React Native or PhoneGap. If you've heard of PhoneGap, remember to stretch. It is very important at our advanced ages. dioxus-fullstack goes one step further with a single code base for the client and for the server. But what does that mean? How did we get there? Let's go back in time for a minute or 12. But first, a word from today's sponsor. TryHackMe is the world's largest hands-on cybersecurity training platform with over 6 million users globally. What does that mean? That means you're not reading courses. That means you're doing real hacking from the comfort of your laptop. With your hands on, Don't take your hands off! Not gonna work. See, learning by doing is the greatest. It's my favorite. The problem with learning by doing specifically for cybersecurity is that unless the company is literally paying you to do it, it's probably illegal and you're probably going to jail. And that's where TryHackMe comes in. Not in jail. If you're in jail, you need... someone else. TryHackMe lets you hack real machines directly in your browser, making cybersecurity education fun, accessible, and keeps you out of jail. I cannot emphasize enough how little jail is involved in this whole process. I'll show you by doing their offensive security intro course live in front of your very — well, I mean, it's not live. It's just — it's pre-recorded, but it was the first take. I had no idea what to expect going on. You get it. You're smart. Offensive security. Hell yeah. Log in streak. TryHackMe will use virtual machines — it's starting. Your first hack. We will use a command line application called GoBuster. Step one. Open it at a terminal. Wait, this is an actual — okay. I thought it was like a bunch of commands that you would run and the commands would run in the VM, but it's an actual, actual VM. Most companies have an admin portal page. Ew. So at this point, it should already be flagged by the bank's website for, like, making way to many requests. Probably. Bank transfer. Ka-ching! 8881. And my mission is to transfer 2,000, which, of course, you know, always leave a little bit for yourself. Transfer completed. I'm impressed! This is fascinating. It's been a while since I've done remote desktop to an actual VM in my browser. As in, I've actually never done this. If you like what you saw and you would like more of it, go to TryHackMe. com today and use code FTL25 to get 25% off an annual subscription. Question: What happens if you try FTL50 or FTL100? I don't know. That's a good question. That's the right mindset. Always be scanning. Thanks to TryHackMe for sponsoring. Back to the video. There's been plenty of different paradigms when it comes to web apps, and I won't cover them all. In short, in the first generation, generating HTML is the job of the server. You are allowed to sprinkle some JavaScript — or, god forbid, Visual Basic Script — to make some stuff move, but that's as far as it goes. Note that I'm saying "render" in that diagram for generating HTML with my apologies to people who work on Servo and Skia and whatnot. I'm just reusing the React nomenclature. Sowwy:3 In the second generation of web apps, the world has now written a critical mass of JavaScript. We're starting to have something that resembles DevTools. If you remember Firebug, that was among the first. And maybe you should work on a will or something like that. We're starting to get comfortable with the idea of a real application living inside of the web browser, which renders HTML based on structured data coming from the server. Then follows a decade of developers using something called XML HTTP request to send JSON around. Oh well. We're starting to have web apps that work offline. However, the initial loading experience is bad. Visitors have to wait for the entire app to load, and they have to wait for the app to do its API calls, and then for the app to render the HTML, which can take a long time. Planet Earth is starting to develop a collective aversion for the spinner. That's not the only problem we'll have to address for SPA — single-page apps. We'll have accessibility, navigation history, search engine optimization, and of course, data loading. If every component on a page does its own API request to get some data and then render, that's a lot of requests per page. Especially if you look at React the wrong way and your component is doing API calls in an infinite loop, then it's a lot, a lot of API calls. And yes, that is actually what took Cloudflare down recently. So boom, third generation, full stack, best of both worlds. We do the render on the server like before, and we stream it to the clients, which can display it as it's being received. But alongside that render HTML, the server also sends the structured data that it used to render the HTML. Here's a practical example. It's a counter written in Dioxus. When we do the server-side rendering of that component, we just say, "Okay, there's a variable x that starts at zero.
Segment 2 (05:00 - 10:00)
It's used in the macro rsx! {}, and then there's two buttons. The two buttons do something if you click on them, but can we do something about it on the server side? " No, those event handlers have to be registered on the client side. All we can do is send hints. Here's the HTML marker sent by the server. There's no "onclick" attribute on the button text directly. There's only information that references the structured data that I'm not showing you here to avoid a wall of text. So the client has the same data the server had. It's doing the same render the server did, and then it creates a mapping between what the server sent and what the client rendered. Then it takes over the document, installs event handlers, making everything interactive, a process we call hydration. Now the whole point of having the server stream markup is that we can show it early before the app is even loaded on the client. But what happens if we click on a button in the middle of the hydration process? In theory, the server markup could include actual links or forms that would trigger regular browser actions. But in practice, it's been a while since I've seen anybody big bother doing that. Now what happens if during hydration, the client render doesn't match the server render? Then it can't create a mapping and everything's just broken. I think the best case scenario here is just replacing everything with the version that the client rendered, which is still pretty bad as everything would just jump around. And finally, what if we need data that takes some time to fetch? For example, we're fetching from a database or an API. That's a family of problems that the industry has been trying to solve for years. And Dioxus offers several solutions in the form of hooks. Though something for everyone here, there's synchronous hooks, there's asynchronous hooks, there's reactive hooks, there's hooks that cache the results, there are hooks that are only on the server side or on the client side. It's a little bit intimidating, to be honest. How far from the "if it compiles, it works" that I got used to in Rust. If you break the rules of hooks, you don't get a build error or even a runtime error. You just get weird behavior which can be hard to debug. But there's kind of a good reason for that. It's that full stack stuff is complicated. It truly is. It's not that Dioxus added complexity where we didn't need any. It's that this is a problem that's inherently complex. Now I have a confession to make. I was originally planning to be a little rough on Dioxus because I challenged myself to use it to build the quizzing software that I used at Euro Rust in Paris. And it was honestly a pretty frustrating experience. But! As I dug deeper, I realized that most of my complaints were really just misunderstandings, or already in the process of being fixed in the main branch, or simply limitations of the current web assembly slash Rust ecosystem. But I'm going to start with praising the developer experience of Dioxus with their DX tool which wraps cargo and takes care of compiling web assembly. I was going to praise the loading screen you see in the browser while it's compiling everything. But then I was going to complain about the fact that if there's a panic in the app, it just becomes unresponsive. There's nothing that shows you that something went wrong and the entire app is broken. Well, in the main branch of dioxus, there is! Of course they added it. It makes sense and they're smart people using their own stuff. Next I was going to complain that the stack traces are completely useless because all we see are function names with numbers and hexadecimal offsets into a big wasm file. But since then, I found this Chrome extension called C/C++ DevTools support (DWARF) which looks exactly like what someone would come up with if they were trying to target me specifically with malware. And yet it works. It doesn't actually give us the name of the functions, but it does show the name of source files and lines. And if you click on them, they open up in DevTools and you can place breakpoints, you can step in, step over, step out, like a real debugger. It's honestly a lot better than I imagined. I didn't even know we were so far with wasm debugging or that we had picked DWARF for that. But I guess that makes sense. Next I was going to complain about subsecond, their hot-patching thing. So what is hot patching? When you develop a web application, it's kind of a given now because of React and Svelte and whatnot. It should be able to modify source code that corresponds to a component and that when saving that file in your editor, the change should apply directly in your browser without changing the state of the application. Right? So if you're navigating deep into your application's hierarchy, hot patching doesn't reload you back to the start page. It doesn't reload the page at all. Instead it updates only the components that have changed on the current page. And I thought I was using subsecond, Dioxus's hot patching thing. And I thought, wow, it doesn't really work very well at all. It actually does lose state. It's not actually under a second. It turns out it wasn't enabled. I forgot you have to pass --hotpatch and I guess I did not know. When I did enable it finally, I noticed that it actually worked really well really quickly. It crashes all the time because what it's doing is a lot more complicated than the JavaScript frameworks and it's still early days and all that. But the promise is here, you can make a change and you can see the result very quickly in your browser. And when there's something funny, when you enable hot patching, stack traces show the actual name of Rust functions, but it also breaks dwarf debugging. So your choice, I guess. And now it's time to answer the question, does Dioxus spark joy? I'm gonna say not yet. For now, without subsecond and everything, it's still really unpleasant for the most part compared to Svelte 5, which is my gold standard. But I can see what the Dioxus team is going for and I'm really excited for it. I was gonna skeptical going into this. I was like, I'm gonna get Rust enums, which is great, but everything else is going to suck. But I was wrong. The generational references make event handlers not actually miserable to write. Server-side functions with WebSockets actually work pretty well and get rid of a lot of boilerplate, The Dioxus team is doing a lot of hard, interesting work. They have a Flexbox implementation that they're sharing with Servo.
Segment 3 (10:00 - 10:00)
They're doing their own HTML and CSS renderer now to make desktop applications without a full fledged web engine. I'm very much looking forward for Dioxus and the entire WASM-on the-front-end ecosystem to catch up with the JavaScript based solutions in terms of developer ergonomics. In the meantime, I'll be doing Rust on the back end and TypeScript on the front end. Thanks for watching and I'll see you next time.