Paul Mikulskis: Hi there, and welcome to PodRocket. I'm your host Paul, and today we're joined with Daniel Thompson. Daniel is the co-founder of Tauri. And we're going to be talking about Rust, and desktop applications, and the future of what might be UIs. So welcome to the podcast, Daniel. Daniel Thompson: Thanks, Paul. Paul Mikulskis: So you told me right before we hopped on that you are a co-founder of Tauri. So this was a team effort, right? Daniel Thompson: Right. Well, we started working on it about three and a half years ago. I think, before COVID happened actually, before the world went all weird, I guess. And at the beginning, we were just a little dissatisfied with... I mean, I'd like to say we were dissatisfied with the ecosystem, and this is probably going to come up anyway so it's best to just address it right away, we didn't like the fact that so much code was being shipped for desktop apps. We felt that there had to be a better way than shipping a runtime and a browser with a runtime, with every single app you sent. And one thing led to the other and after a couple years, we had put together a project that seemed kind of feasible. Paul Mikulskis: So one thing that you have on your LinkedIn, when I had to do my cursory research on who we're going to be talking with, you say, "I really want to affect... Software is an underrated medium by which you can do social change in the world, or change for good," sort of. Did this project have any place from your heart where you're like, "I really want to make something better for the community?" Or was it purely out of dissatisfaction? You were like, "Man, we just need something better?" Daniel Thompson: Well, I mean the long-tail of that answer is that I've always been one of those kinds of people who is just generally dissatisfied with things. I guess it started back in art school. And coming out of art school and realizing, this was the 2000s, and you want to make video art and you have to burn a DVD. And the DVD players don't auto loop, so you have to have someone sitting there, or maybe there's a special way to burn the DVDs so that it does loop properly. And then, there's these media players that come out, but they're all sort of geared toward consumers and they were never designed for makers. And as time goes on and open-source becomes a phenomenon, what you ended up seeing is this hybrid personality of a creative person who understands that sometimes to get their message across, they need to write some code, use some software. Whether that's writing Python, or getting into tinkering with some Adafruit hardware projects. It seemed like that kind of crossover happened about 10, 12 years ago. And I think, that notion of dissatisfaction, is really kind of the driving force behind why we actually do things, right? If everybody was totally content, there wouldn't be any new companies started, there wouldn't be any new rendering engines, there wouldn't be new graphics cards. It's because we're constantly dissatisfied. And it might sound like there's a tone of bitterness in my voice, there absolutely isn't. I think that by finding means to take back the ownership of tools for social change, be they the firmware of a John Deere tractor, or the boot loader on your phone, or the to-do app that you've been dreaming of having, these kinds of tools are things that we are finally empowered to dream of. I mean, the simple fact that Shenzhen exists and there are ways to make custom silicon, I can tell you in the '90s, that wasn't really a thing. You were a multinational conglomerate and you had to know Arcane programming languages, and chip programmers, and all of that stuff to even approach the functionality, that is today, trivial to master. Paul Mikulskis: I mean, as somebody who's only been in the workforce for four or five years now, when I go to my folks, I'm like, "Hey, I can go to JLCPCB and print this thing." They're, "What? You can just print a chip like that. Do you have any idea where I would be right now if I could do what you have the ability to do?" Yeah, it blows their mind. But, so this general like ethos, okay dissatisfaction, driving force of change, right? Daniel Thompson: When you put that into the macro-socioeconomic condition that the world is in, whether you're looking at the wage disparity, or you're looking at poverty, dead destroyed viruses coming back to life, floods everywhere, threats of nuclear war. We have to find every single way possible to positively impact the world that we live in and move toward a world we want to live in. And it might sound like a grand step, but everything we can do to reduce our carbon impact is viable and good. If it means one less Starbucks coffee a week, if that's your contribution, that is still a contribution because you're not throwing that paper cup in the trash, right? And when we look at the evolution of developer tooling, over the past, let's call it a decade, what we've seen is that there's now a whole branch of engineering called developer experience. Where framework designers try to make the tools intuitive, the command-line interfaces intelligent, and create things that help people make better things. And I guess the question there, because we're sort of getting into this morality topic like, what is good? What is better? And obviously, one of Tauri's main concerns is environmental impact. So again, the elephant in the room, your average Electron app is 200, 300 megabytes. If you're a coder and you use VS Code, you know you're closing in on a terabyte. And that means, every single time there's an app update, those hundreds of megabytes get sent across the wire. And if you have an incredibly popular application, it can actually lead to your downfall. Way back when, when people used to use mirrors to share files, these mirrors were servers and these servers would have limited bandwidth. You'd have limited traffic over a month that you were paying for. And if your mirror was hosting some debian ISO, and it became popular because you had high availability or whatever, at a certain point, you end up paying for that traffic. And that payment is, on the surface, it's about money. Underneath the surface, there's energetic costs for shoving bits into pieces of fiber that go across the planet. There are real energetic costs to that. And I mean, I'm familiar with modern techniques of using WebSockets and just pushing JSON down the pipe till the end of time. And I know that, that also creates traffic. But this original binary that developers are sending to their consumers, that is a massive chunk of known ecological damage. Reducing that size, however trivial it might be, at scale has real meaning. In our announcement post for the 1.0 that we released last summer, you can find a breakdown of energetic analysis. Which this was, again, contextually seen before the global recession that some people say is immediately ahead of us. Some people say it's here already. In the context of rising energy prices, we might actually have to revisit that table, right? Because from what I'm hearing, a megawatt in Germany, it's going to cost like 1,000 Euro and someone is paying for that. Okay, it's a distributed system. So the user who has a phone or a desktop that's downloading the app, they're paying part of that electricity cost, the internet service provider is paying a part of that electricity cost. So it's a global perspective of this electricity cost and not the opportunistic perspective of, "What do I have to pay as a consumer?" It's more, trying to look at this holistically because we have a global problem. And as opposed to these 2, 3, 400 megabyte binaries, Tauri is able to, on Mac and Windows at least, ship... I mean, generally they're around 8 or 10 megabytes, fully production ready. And the way that that works is, we don't ship a Node.js runtime, we actually, the backend is written in Rust. So that means that you have a compilation phase that compiles it for the specific hardware that you're targeting. And that means it's just creating functional systems, there's no extra stuff there that you're shipping. I mean, a classic example is, if you're shipping Node.js in an Electron app, you're shipping all of the fetch functionality or whatever systems that Node.js needs to be Node.js, to function as a runtime. You're shipping all of that. And if your app doesn't use any internet connectivity, why would you need to ship that? It's a waste of space, and time, and energy. Paul Mikulskis: And it'll be shipped every time, right? Every single time. Daniel Thompson: It'll be shipped every single time. And there's a couple reasons that make that scary. Once you start peaking under the bonnet of what an Electron app is composed of, it's not just the Node.js runtime, it's also a modified version of Chromium. And I'm not going to hate on Chromium, I'm not going to hate on Node.js, and I'm definitely not hating on Electron, but... And this brings us into our second perspective. From a security point of view, shipping a known version of Chromium means you are shipping future one-days. So I'm sure you've heard of a zero-day, where a zero-day is a vulnerability that no one knows about until it comes out. And then, Chromium will patch that zero-day and ship an update. If you as, a developer, don't keep up to date, that means that it's possible to discover which version of Chromium you shipped with your app. And all of the known exploits between right now and that version being released are theoretically leverageable against your app. So size, environment, security. And I don't know, there's something special about Rust as opposed to C++, these systems level languages, and that is that the compiler is there to help you. The Rust compiler is very well known for telling you exactly what you're doing wrong and not letting you do something. I don't want to call it stupid because I don't think that C++ engineers and C systems administrators are stupid, but there are a lot of ways to introduce things like use-after-free bugs in the memory processes. And if you look at the number of critical vulnerabilities being discovered all of the time in any large C based project, it makes you really wonder, would these problems all exist if there was proper memory management done for the user? You could look at it like syntactic sugar for memory, right? When your frontend languages, for example, I'm probably going to get this wrong, but what's the last one I remember using? Vue.js, for example. There's a way to address all of these attributes of a DOM element using v-model. You can address them individually, but v-model allows you to treat all of them. So you write one thing, and it sort of gets transformed under the hood into the things that the system is expecting. All right. And I guess, maybe a good example would be C++'s JavaScript, and Rust is like TypeScript SolidJS. I don't know, I'm going out on a limb here. But I hope you get what I'm saying. Yeah. Paul Mikulskis: Rust, I mean, as a student of Rust, I am no practitioner by any means. But having used C and Rust, you can actually produce something that, it feels operable without being a expert in memory management because of the fact that the compiler will tell you, "Hey, this is in the wrong spot. You need to do this." It's having a conversation with it versus a battle, even though at first it feels like a battle. You just need to get through, you need to understand the way it talks and then it's more like a conversation. Daniel Thompson: Well, it's kind of ironic, right? Right now, we're at a point in time where neural networks or artificial general intelligences, whatever, are entering into the mainstream. And they're pervading our creative lives as authors of code, as authors of artwork. And in a sense, again, I'm going on a limb here, but the Rust compiler is treating us like humans. Yeah. People, we make mistakes, we make typos, we might forget something because it's a complex language. Whereas, my feeling is that, C always expected you to be perfect. If you are not a perfect engineer, you have no business writing C because bad things are going to happen. Kitty cats are going to get sick. Paul Mikulskis: I really like that. "You have no business being here if you ain't perfect, buddy." Ah. Daniel Thompson: And now we have AI. We have, what is Microsoft's Copilot. Copilot's probably great to help you write perfect C. I mean, I'd want to have an artificial intelligence guiding me down that road for sure, because half the world can't be wrong, can they? Paul Mikulskis: Let's not be so quick to judge. Really quick, so we're going to get into some of the API and the structure about Tauri so we can just take a little bit of deep dive for listeners and see what's going on. But before we do that, if you're listening to the podcast and you're enjoying what we've talked about already, we like to have more existential and grandiose conversations as well as getting to the technicals. So check out our episodes, we're going to have more coming every week. Please tune in, we hope to see you there. So Daniel, let's get into a little bit about how you are using Rust to take this next step of curing your dissatisfaction. So yeah, could we step into the architecture a little bit and talk about the API concept that you bring to the table? Daniel Thompson: Absolutely. So I mean, basically, let's start at the very beginning. You have a computer. And that computer has internet access, and it's got a screen, and it's got a keyboard. And I'm starting simple because I think it's important that we lay some ground rules. You have a command-line or a terminal interface, and you go into that terminal interface and you install some system dependencies. Now, depending on your platform, you're going to need different kinds of build tooling. You're going to need to have, probably, some kind of compiler. You're going to maybe have to have some kind of special Apple tooling, if you're on Apple. And I'm telling you, each platform is different. Apple, Windows, and the multitude of Linuxs. Once you have your build dependencies installed, Rust is literally the only language dependency that Tauri has. However, if you do plan on using a JavaScript frontend framework, like Angular, React, Vue, Svelte, SolidJS, you're probably going to also want to have some kind of Node package manager and a Node runtime. Because those products, those frameworks, they use the Node runtime to help you scaffold out your project and run a development server. You absolutely need a development server. And then at the end, they're going to transpile the source code that you have into something small and manageable. You know, you need some HTMLs, some CSS and JS."Why do you need that in a desktop app?" you might be asking yourself. So now we can get into the fundamentals of a Tauri app. An app always starts with a launcher. You need something to kind of keep all the bits together, that's what we call the binary. And the binary is a bundle, actually, it's a bundle of assets that sit together. You might have an Icon, you probably want an Icon, you're going to need some kind of system bootstrapping. If you're on Linux, you need to make sure that you're addressing the proper WebView. If you're on Mac OS, you're going to want to have that proper folder structure so that the permissions that you need to grant your app can be found and analyzed by the system. And this stuff gets all munged together. And there's this kickoff moment, where the binary is valid, everything starts, and we enter what's called the main loop. The main loop is something that just runs forever, and the instantiated system will then create a window and inject something into that window, right? So up till now, we're in pretty familiar territory. You can inject if you're into GL, just a pure GL context, right into that window, and then you get to modify that. We're using the wonderful egui library in Rust for that. But if you're coming from egui, egui, I think it's called egui, and that gets injected directly into the tau window. So if you think of a Tauri project, you have a window, you have a view. That view can be, in this case, I was just talking about the GL context from egui or a WebView. Now you're probably familiar with WebViews because you've seen it in apps. I don't know, for example, Instagram, you click a link somewhere because they're impossible to find, but it opens up something like a browser in Instagram. And that browser has HTML, CSS, JS, it generally works a bit like a browser. Except, you can't really navigate and a few other things I'll maybe talk about later. So you've now created a window and you've given it, let's just for the sake of argument say, we've put a WebView context in that window with our WebView rendering library called wry, then you need to put content in. And this is where, through a custom protocol, we take the code that you wrote for your frontend and we send it to the WebView. It's kind of like having a local server, except, there's no ports that are opened, right? There's no local host. Which means, that only the instantiating executable can talk with that WebView. From a security perspective, it's pretty helpful. Now, once you have your HTML, CSS, and JS hydrated, well, then you know if you're familiar with Webtech how that kicks off. You load your assets and as soon as JavaScript's there, he's like, "Hey, what's up?" And does all of its funny, funky, DOM mangling, CSS tinkering, gooey goodness, right? So that's the kind of first layer, right? To get to that point, you don't need to write a single line of Rust for Tauri. Now let's say for example, you want to save a file. I don't know, let's say you're making the world's greatest markdown editor and you have a markdown converter that shows you the nice great HTML. And then when the person's finished editing their wonderful document, they want to save it to the disc. Well, we have APIs for that. Now there are APIs for a lot of things, notifications for example, we have APIs... But in this case, we'll stick with file system. So the development team would empower the app to use certain parts of the file system such as a dialogue, because a user probably doesn't know all of the C:\Documents, users, whatever. No, so they're going to want a gooey, they're going to want to pop up a window, right? So our API pops open a window for them to choose where they want to save that document. And again, we get very granular with permissions for important security reasons that I'm not going to get into yet. But the user chooses, let's say a spot on their desktop and a file name, and they say, "Save." Well, what happens is that location is then communicated to the Core, and the frontend can find out about it. And this is all done with these JavaScript APIs that we provide. So again, to do this whole flow, you won't really need any Rust code. And we've tried to do this because we feel like, for a lot of people who are new to Rust, this barrier to entry is very high. We like to give people small successes. And a small success is installing the compiler, running yarn tauri dev or cargo tauri dev to create the dev service and seeing the window pop up, and having your hot module reloading that, your HMR, changing the way the window is displayed. And then, being able to communicate with the Core APIs from the comfort of JavaScript means that you can really do, let's say, 90% of the things that apps might want to do. Of course, there's limitations and things that might require you to go a little bit deeper. And for that, we built a plugin system. So what we've tried to do with Core is keep it performant and lean, and doing something that we know every app is going to need or potentially need. For other uses, let's say for example, you want to hook into the fingerprint reader on your Mac OS for some kind of user verification. Well, there is a library, a Rust crate, it's the [foreign language 00:26:00] to node-module. A Rust crate that allows the Rust programming language to communicate with that button, piece of hardware. And the architecture of the plugin is pretty simple. You interface with the library, you expose the functionality that the library gives you, and you turn that into an API. And then you create the, I mean generally TypeScript, but JavaScript interface that then talks over the bridge. And maybe that's the point I didn't talk about yet, but I'll get to in a second. It communicates from the WebView to the Rust Core and directs the Rust Core. So a common flow would be, the user enters a login window and they've authorized the app to use the fingerprint reader, and it says, "Hey, use your fingerprint. So click here," or whatever. There's a button that clicks there, you click there, and it sends the message to the Core to open up that certification process, and returns success or fail. If you get a fail, that can bubble back to the user interface. And if it's a success, that can bubble back as well, but it can bubble back with the trigger, "Yeah, this was successful. Move on to the next stage," for example. And this opens up a lot of possibilities for people to come up with whatever integration they want. And we've seen some neat ones come out there, like SQL. Somebody made an SQL interface, so you can pretty much just declare it in your system and integrate the API, if you're into using SQL, and you can interface the frontend from the backend. And I guess the point is that there is a bridge, how do you communicate between the WebView and the Core? And WebViews all provide a kind of communication pathway, a two-way communication pathway, between the WebView and the backend. Paul Mikulskis: Would you dare to say that you're almost taking a jab... or I don't want to say jab, that's an aggressive word. Let's rewind. Would you say you're taking a gander around your own native development sort of platform here? Because there's all these APIs and hardware level interactions that exist in this library of Rust code that is callable and operable from different places of invocation. Kind of reminds me of developing for a native ecosystem. Daniel Thompson: Oh. Well, I mean, now we're getting into long future kind of talks, right? One of the problems of all of the WebViews is that, up until March this year, there wasn't really a W3C standards body behind them. And the Linux version of WebViews that we're using is WebKitGTK. Which is at, I don't know, version 2.36 or something like that. And they haven't enabled WebRTC, it's behind a feature flag, but that's not really installable on any platform right now. On the Mac system, your users are going to be using the WebView that's shipped with their version of the operating system. Because every time Mac OS updates the Safari, it ships with a new WebView and that's the one you get. And you don't know which version people are going to have at build time. With Windows, the Windows team decided to move over to a Chromium based version of Edge that also provides the WebView, so you're probably on the latest version. On Windows 11, for sure, you've got WebView installed. On 10, it's a gamble. And behind corporate firewalls, you have no idea. So you might actually have to ship the WebView that you need. And I'm not claiming to be sad about the situation, we knew this when we got into it. And we knew that we were accepting certain kinds of technical debt. One of the things that gets brought up a lot in the ecosystem is, "Oh, it looks different on Safari than it does on Windows." And this is what web designers have been struggling with for decades. I think people need to, sorry for sounding kind of aggressive there, but get over it folks. This is why we style things with frameworks. This is why component libraries exist, so that you can get the same behavior on every device. Now, what could be better about WebViews? Well, I'll tell you one thing for sure, having shared memory. Because right now, one of the bottlenecks for WebViews, and it's got a lot to do with why we actually built that GL window, is when you need to transfer large amounts of data, you're doing it across a serialized border. What that means is, the Rust side to the frontend, they need to communicate somehow. So you're using a kind of data channel that's... Paul Mikulskis: Whether it be software or hardware, it's still, it's serialized at some level because... right? Daniel Thompson: Right, exactly. And that's a process that takes double time. And so, by having shared memory buffers between the backend and the frontend, you instantly get super fast. I mean, well, not super fast. Basically, as soon as it's in memory, it's in memory, right? And that means that both sides can, depending on your mood text or your lock or whatever, both sides can manipulate it. Which means, you suddenly get kind of superpowers in a way. Obviously, it also comes with massive security risks. Anytime you're playing with memory like that, it's dangerous. But I guess the point is, coming back to this dissatisfaction I spoke about at the beginning. You know, you give a mouse a cookie, he's going to want a glass of milk. You give him a glass of milk, he'll ask for a napkin to dab his mustache. You give him a napkin, he'll ask where the trash can is. And I think we're in this kind of phase of Tauri where the next steps are, "Well, all right. We created an ecosystem, we created something that works. How can we make it better?" And right now, we are realigning our milestones for the next things that we want to address. And obviously, in any crashing airplane, you put your own oxygen on first, right? Got to make sure that people can really ship apps to the Mac App Store. Got to make sure that systems compile everywhere, every time. Got to make sure that CI/CD is solid, the updates really perfectly work. There's this kind of housekeeping that we're in right now. This is like the 1., I guess we're almost at 1.2, we're looking at 2.0 sometime next year. And what happens then? There's a lot of discussion inside our research teams, which is pointing toward the theoretic possibility of actually constructing our own WebView as a dynamic library. Which means, it's something that we could ship like Chromium ships theirs. I mean, I think Facebook made a new WebView the other day for Android, based on Chromium. And I mean, we know it's not an impossible feat, it will take a lot of engineering talent and time. But, we think that in the long-term, having a shared runtime is exciting. And again, I'm under no illusion that it's going to be instantly workable, and instantly safe, and instantly ready for production. But I think that, once you are in that kind of position, then systems integration becomes really interesting. Especially, with the broader ecosystem recognizing the benefits of the Rust programming language. I mean, I wouldn't be surprised if in a couple years this approach of building software really resonates with larger organizations, and you start seeing it's in space for government use, right? It's a lot easier to certify a binary the size of 6 megabytes than it is to certify one that's 600 megabytes and has a Node.js runtime. I think that the benefits still outweigh the risks. And I mean, Tauri OS, if you see an announcement about Tauri OS make sure it's not April 1st, okay? Paul Mikulskis: Yeah, okay. That's a cool statement, it kind of wraps up a foreshadowing of the future and a dose of realism all in one. So if people wanted to try out Tauri... I mean, one thing that you were touting a few minutes back was like, "We wanted to make sure it was a good, easy win. Small easy wins at first, so you can get the framework, you can get an app running." Do you have a tutorial sort of thing on your website that we could point people to? Daniel Thompson: Our website has a lot of guidance on setting up your system. On the process of going from development to testing, to building, to debugging, to distribution. So there is a lot to follow through on. But if you're comfortable on the command-line, and you have no JS installed, and you're thinking about installing Rust, then install Rust with rustup. It's all documented on our site, you know, getting started page. And my advice is to dive in and just run, I don't know, npm, PNPm, yarn create-tauri-app. And the beautiful part about that system is, it's like React's Create App. It asks you, "Okay, do you want to use Vite? Do you want to build with Angular?" It lets you kind of construct your favorite flavor of frontend. And then on the other side of that command, it spits out a folder that has all of the prereqs already made and a sample page that is already rigged up for Tauri. So it's a really easy way to see if it's for you. And we have an amazing community over at Discord. A couple people from our working group are always monitoring the questions and doing their best to help people understand, and get over that kind of learning curve at the beginning. But in the years I've been watching our community grow, I can say with confidence, the first hurdle is installing Rust. After you've installed Rust and you've built a Tauri app, you cannot any longer say with any shred of credibility, that you've, "Never used Rust." So that means that, you can call yourself a Rust user. And once you have that kind of mental model, then you start thinking, "Well, okay, how do I do this?" And you can check out the examples in the GitHub repo. You can see how things are done, and you can start appropriating the knowledge of the crowd, and adapting it for your own use. And again, I firmly believe that the community is the greatest resource that you'll have on any journey of software engineering. But specifically for Tauri, I think it's a very healthy, dynamic group of excited people. Paul Mikulskis: Point taken. The website has a lot of stuff, it might feel overwhelming, but install Rust. And yeah, call yourself a Rustaceans because that's a very exciting time in your life. Because you're like, "Wait, what's this new mojo going on?" Yeah, I like that. Embody the mental model, appropriate the information of the community. So we can also link the Discord if people want to just hop right in, and see what's popping over there. Daniel Thompson: All right. Paul Mikulskis: Awesome. Well Daniel, thank you for your time. This was a really interesting podcast. Especially, our first 15 minutes of talking about the ethos of Tauri and what motivates you. But yeah, thank you for your time and thank you for coming on. Hopefully, some people are going to be motivated to go download this right away and do the create-tauri-app. Daniel Thompson: Perfect. Well thanks for having us, it's a pleasure.