skip to content

Ship native apps with web tech using Tauri

Access native APIs using a JavaScript runtime to ship fully functional native apps with Tauri without needing to write Rust. Atila Fassina teaches us.

Full Transcript

Click to toggle the visibility of the transcript

Captions provided by White Coat Captioning (https://whitecoatcaptioning.com/). Communication Access Realtime Translation (CART) is provided in order to facilitate communication accessibility and may not be a totally verbatim record of the proceedings.

JASON: Hello, everyone, and welcome to another episode of Learn with Jason. Today on the show we are gonna be digging into native apps. Which native apps have gotten a little bit of love on is show, but we haven't given them their proper due. To be quite honest, I'm intimidated by them. We are going to be learning today about how to build native apps... but... I don't necessarily want to learn all the ins and outs of building for each platform. That's led me to reaching for something that will hit all the native platforms for me. And there's an exciting new one that I just learned about, they just had a big release. And to teach us all about it is Atila Fassina. Please welcome tot stage, Atila, how are you?

ATILA: Great, getting better by the second.

JASON: I have a lot of questions about what you're working on, but let's talk about you. Give everybody who is watching a bit of a background about yourself.

ATILA: First of all, I'm a long-time fan of this show, I'm pinching myself that I'm here. As I mentioned earlier, it's kind of a career landmark. So, yeah, that's awesome. So, I'm a developer. Originally from Brazil, but I live in Germany. And today I work as DevRel lead in a company called CrabNebula, it was created by the founders of Tauri. And we do a bunch of stuff with the ecosystem. We are a community partner and we are -- a community partner. And so, I -- myself and a few other of my colleagues are part of the Tauri working group. I already see a bunch of them there in the chat. So, thanks for coming. And besides that, I also work in the SolidJS team. So, I work in the DX team, more specifically. And I do love playing with all these frameworks. I like -- I have my favorites, as no secret to anyone, but I like playing with all of them. And that's one of the things that drew me towards Tauri is that it is completely agnostic from the frontend perspective so you can play with whatever you want. And yeah. That's pretty much me. And I talk a lot.

JASON: Good. We're gonna get along great, then. So, okay. So, let's talk a little bit about Tauri. And for somebody like me who is really only ever seen the name and maybe heard like a headline, can you give us the high-level on what is Tauri and what problem is it solving?

ATILA: Yep. So, Tauri is a Rust-based framework for building native applications. So, that's already up front kind of intimidates people because I say "Rust" and I say "Native." I felt just the way as you just mentioned in the opening. So, the reason why Tauri to me is so special is because it actually has two fundamental pieces. One, we call Tau, which is the window management system. It's essentially your backend, that's in Rust. That's the part that connects with the native layer. And it has a very thin wrapper on top of the native web view of whatever system you're running on.

JASON: Okay.

ATILA: So, that's called Ri. That's why Tauri -- that's how it comes.

JASON: Ah, okay, okay.

ATILA: And so, both of them are built with Rust. So, that makes -- that makes the IPC connection with the native layer very fast and good. And also, it allows us to have security by default. So, Tauri is a framework built from the perspective of having something safe and efficient from the get go. And we can go a little bit deeper into that. Especially with the v2 launch, things got a little bit safer.

JASON: Cool.

ATILA: Even if you compare with the v1. As you mentioned in the beginning and I just said, yesterday we launched the v2. Until v1, it was possible to build the three platforms, Linux, Windows, and macOS. And after v2, we added Android and IOS to the mix.

JASON: Nice. Very cool. Let's talk a little bit about -- I think maybe the biggest question that I always have when I start talking about web apps versus native apps, versus desktop versus mobile is how -- like why would somebody build a native app, right? When you can build a web app that will play on any browser? Right? It always sounds -- and this is kind of me teeing you up to tell me why I'm wrong. It sounds to me like when you were looking at building an app that the highest leverage thing to do is build it once for the web. It's sort of one codebase that I know is more or less the same on every device, whether it's a computer, a mobile phone, or a TV, right? Whereas what intimidates me about native apps, I have to build an iOS version, but on an AppleTV, it's an AppleTV version, Android phone, Android version. Desktop app, now I'm looking at five, six, seven varieties of app and I still have to build a website. How do you think about this? Where do you make the decision to take on -- or am I wrong? Is it not extra work?

ATILA: I think that there are a few things that need to be taken into consideration if you decide to build a native app to an app that you already got. Which is if you're going -- you need to leverage like using the native language, per se. And that would mean a lot of things. That would mean a bigger team. That would mean a bigger effort to make -- to keep feature parity and so on. We have all been there. Like if we worked in like companies that had this offering. And I think what Tauri allows you to do, and it's something that we do at CrabNebula, actually, is from that very same codebase, you can build for all the platforms. And that means we have right now an app called CrabNebula DevTools that the open source version is a Solid app. SPA, deploy to Netlify, works great on the browser. But then we want to have some functionality that connect to the native APIs. So, it uses your system or it connects -- it works also as a Tauri plugin in this case. So, for that, you need a Tauri app in this case. You can use like the system tray, you can use a safer IPC, like we're going to see in the -- when we get to the coding, we're going to see that like Tauri even exposes like an HTTP client where you can use fetch calls that go through Rust. Which --

JASON: Okay.

ATILA: -- makes it a little bit safer than throwing from the web view in this case. There are a few things that becoming like Tauri makes it easy. And allow you to do that.

JASON: Cool. Very cool. And so, I guess, then, if I rephrase that, what the incentive would be is it if the thing I want to build needs to take advantage of like the native capabilities that I don't get access to from the web, or if I want to make sure that my app has really good security and doesn't have any like exposure to sort of like web-based attack vectors, then the --

ATILA: Yeah.

JASON: -- the approach is better?

ATILA: On top of that, you also have like the being able to install it in your system. Sometimes it's good. Like if you have something -- an app like Spotify or something like that you might want to use. And I think -- yeah. That's a good rule of thumb in this case. Yeah.

JASON: Okay. I get it. And so, I think you've already said this, but fuzzy's asking, is it still a web view?

ATILA: Yes, it's still a web view.

JASON: It is still a web view.

ATILA: It is a web view. The difference is with Tauri from most of the other hybrid apps is that it doesn't ship the web view. That makes a ton of difference in terms of bundle size, in terms of performance, and also in security. Because if you're bundling your whole chrome with the app, then suddenly your app is the size of the entire Chrome plus whatever code you write. And that leads you to a Hello World being like 200 megabytes. And with Tauri, because you're using the native web view, it's just a very thin wrapper so your code is basically the size of the image in most cases. The image is bigger than your code in this sense. So, a Hello World can go to like 200 kilobytes, 300 kilobytes in this case.

JASON: Awesome.

ATILA: It's the size on the bundle. And on top of that, we can talk about inheriting security updates from the system versus needing to re-bundle your whole app to ship the updated Chrome image.

JASON: Oh, that's actually a really interesting point. So, when I download like the latest update to my OS, it's like the native apps are all accessing native APIs. But if I'm exporting a bundled web view, that code isn't touched by anything Native so the only way I would get updates if I were to install the latest version of that app specifically.

ATILA: Absolutely. And then what happens is once a CV goes public, like a report of a vulnerability, most of the exploits happen between the window of a zero day and a one day. If your user is downloading the updated system, that means your app remains secure. But if you're -- if you need to re-bundle your whole app, then it depends on you inheriting the update, you shipping the app and your user finding the update.

JASON: Right. No -- okay. I'm seeing some -- I'm seeing some good -- some good reasoning here. There's a -- I -- I'm starting to see why this is compelling. So, then let's talk about a couple of the things that then further freak me out. Which is, one, writing native code has always -- like I have no doubt I can learn it. I just have no time to learn it, right? And then Rust has been the same. I think Rust is so cool. Every time I've looked at it, I've thought, dang, this is really great. And also, I have no time to learn it. And so far I haven't had like a compelling enough reason to really dig in and do a project with it. So, with Tauri, am I -- you mentioned that there's like the sort of thin Rust wrapper around native APIs which I think means I don't have to write any native code.

ATILA: No, you don't.

JASON: How much Rust code do I have to write to build an app with Tauri?

ATILA: So, I've given already workshops where ten to 20 people have shipped an app in about two or three hours from zero shipping an app. And we haven't written a single line of code -- of Rust.

JASON: And what are you writing?

ATILA: We are writing JavaScript and TypeScript from the web view.

JASON: Okay.

ATILA: So, what happens is Rust takes all the native APIs and expose it to TypeScript. So, what you can do is just like import, whatever code you want. And invoke Rust code from the TypeScript. So, it's essentially just a promise. It's like any fetch call you're doing. And what's going to happen is that Tauri under-the-hood is going to go through the IPC bridge, runs the native code, and brings you back the response that you need.

JASON: Got it. Okay. All right. You're getting me really interested in this. Let's see... I'm not seeing any other -- there's a couple questions in the chat. Let me see. Danilo asks: Is it WebView 2 or WebView? I'm snot sure what that question means, that's how much I know about Native apps.

ATILA: Yeah. So, the WebView that we're using, it depends on the system. I'm not entirely sure what he means either.

JASON: Okay, okay.

ATILA: In this case, what we're using is the native WebView from the system. We have this Rust called Rye, which is wrapping it. If you're in macOS, it's going to run on -- essentially behaves as Safari. If you're on Windows, it's going to be Edge, or Chromium in this case. And so on. And Linux is the Web 2 GTK so far. Amr is here, he's a member of the Tauri working group. And that's what he's saying.

JASON: Okay. So, it is WebView 2 on Windows.

ATILA: WebView 2.

JASON: And there was a question about if it works with Ubuntu Snaps. Again, I have no idea what those are.

ATILA: I'm not entirely sure about that one as well. But yes. I would say it works because we have so far we have shipped to desktop since like View 1. And the only -- the only small issues that we get are a little bit quirks with the Web 2GTK.

JASON: Okay. Cool.

ATILA: So, Jacob is mentioning about some compatibilities on the Linux ecosystem. He's also a member of the Tauri working group, as I said, there's a bunch of us around here. And when -- I haven't mentioned yet, but I don't fancy myself as a Rust developer. I still get that rush every time the compiler doesn't -- it slaps me on the face. So, every time my Rust code compiles, I'm happy. So, that's -- so, that's why they're here to rescue me on the more Rust-specific issues.

JASON: Got it. And then a good question from Jose here: So, we don't need to write Rust to make a Tauri app. Are there situations where we would want to? Like if we wanted to build advanced functionality or something, we end up writing Rust? Or is it more the entire goal is to only write TypeScript?

ATILA: So, the Native APIs are going to be exposed to you in JavaScript. And you're just as good using them from JavaScript as from Rust. But then if you want to leverage Rust to do some more complex commands, yes. Then you can jump into Rust and you can write your own logic. I have gone through it like created a little app that was supposed to scan all my projects and measure the size of my Node modules and offer me to delete them. And as you can imagine, like recursively going through Node modules is a little bit too heavy for JavaScript.

JASON: Sure.

ATILA: So, we did that from the Rust side. On top. But for this, we also have -- even if you're more a JavaScript developer like I am. There's a crate, Tauri-specta, and that's a wrapper from Tauri. And creates Rust commands and creates TypeScript bindings for it. So, once you write your command on Rust side, you can expose it again as an invocation method to your JavaScript side and up the types that are required. In this case, I'm essentially using Tauri to leverage my TypeScript into learning Rust because I write some code in Rust and then see the types that are there, if they make sense or not.

JASON: Got it, got it, got it. Cool. All right. And then yeah, Snap is a package manager for Ubuntu. Got it, got it, got it. Cool. I have a bunch more questions. But it would probably be easier to look at code than to keep talking about these in the abstract. So, why don't I take us over into the pair programming mode here? I'm gonna turn on a couple banners. First and foremost, this show, like every show, is being live captioned. We've got Amanda here from White Coat Captioning. Thank you so much, Amanda, for being here. And thank you to Netlify for sponsoring that. Also, today, Atila and I are using Tuple. He can draw on the screen, copy/paste, send me links, to make pair programming a little bit easier. To do the confetti. And that is thanks to Tuple sponsoring the show. Thank you, Tuple, for making this show more -- even more possible. We are talking today to Atila. Make sure you go and get on that -- get on that Twitter list, y'all. Here I'm also -- I don't know why I don't do this. Throw The Links in here so people can check out the wonderful responsers that we have. Click that link and tell them I sent ya. It's a lot of fun. We are talking about Tauri today. Let's make sure we drop a Tauri link in here. And that -- that's gonna be the links I got. So, Atila, if I want to get started, what should I do first?

ATILA: So, the first thing you need to have is Rust. It's a requirement to compile. So, I don't know if you already have in your system.

JASON: What a great question. How does one -- I'm in the wrong -- just a second...

ATILA: So, Rust link. There is a --

JASON: Sorry, give me a second to switch profiles. Now we can read. What was the command to check Rust?

ATILA: In this case, cargo-v, let's see if you have it.

JASON: No.

ATILA: Let me find you the link.

JASON: Oh, we can try the thing. You can just send me a link.

ATILA: Yeah. So, Rust link... -- so, to install Rust, let's see... how do I do the... beam? Yeah. Does that work?

JASON: That works. I could have sworn I had Rust. All right. This is gonna be fine. I just copy/paste this?

ATILA: Yeah, you know. Always trust like Chrome commands on the Internet, right?

JASON: Standard... there we go. Doing all the -- doing all the things and hopefully this goes nice and fast for us.

ATILA: Yeah. So, usually like as a non-Rust developer, if you're going to use Rust

JASON: Probably going to resource my -- what's going on? There we go... I bet... I bet... this is usually -- wait, wait -- to configure a current shell, you need to source the corresponding end file over home... one of the following. Do I just do this? Hey! There it is.

ATILA: Hey, hey.

JASON: When in doubt, read the instructions.

ATILA: Awesome. Okay. So, let's say you're a JavaScript developer. You just picked up. You had Rust in your code for a while. You can just do Rust up and that will check if you have the latest version. No, no, it's all together.

JASON: Got it.

ATILA: Rustup as a single word.

JASON: This says 1.27.1.

ATILA: You just installed.

JASON: Should be correct.

ATILA: That's all you need to get started with Tauri. Just like any JavaScript app, you can npm create Tauri, or PNPM create or something like that. And that's gonna offer you a few templates.

JASON: Okay.

ATILA: But I have that repository that I suggested as we use to start.

JASON: Yes.

ATILA: Which is more or less the same setup that you would get from the template, but then it's something we are going to be working on top of. And has a little bit of more frontend code because the point of this stream is Tauri. It's not SolidJS. You already had Ryan like a week ago or so. So, why would I be here talking about Solid, right? So, yeah. And now we can just have a look at the directory structure, I guess, right?

JASON: Yeah. Why don't I clone this down? I will... let's see... I'm gonna GitHub... what's the easiest -- you added me to this one, right?

ATILA: Yeah.

JASON: I'm just gonna create a new directory. And what was it? You were at... and then I can GitHub repo... clone.

ATILA: Awesome. So, while you're doing this, there is a question from the chat about running different languages. Where was it? Yeah. So, Danilo asked: Can we use other programming languages like Python? Yes. So, you can -- Tauri has a way of having embedded binaries so you can bring other runtimes if you see fit. So --

JASON: Got it.

ATILA: What's happened in this situation, we have some recommended extensions. One of them is the Tauri extension. The other one suggesting to you is the Rust analyzer. It's gonna give you some nice -- as you can see, it's running wild over there in the whole thing. And I think in this repository, I also added a Tailwind. But it seems you already had it.

JASON: Naw, it definitely installed that for me. There it is.

ATILA: Yep. So, just because it was easier for me to get some styles happening there. But it's like -- frontend-wise, it's a mix of stuff that I copied and used in this case.

JASON: Got it.

ATILA: So, looking at the architecture. If you ignore that source Tauri over there -- like let me go to graffiti mode. Yeah. If you ignore the source Tauri there, it's basically a Vite tap. Vite config, Tailwind, and inside source, you'll see it's a single page application as most you already know.

JASON: And can we use any web framework with this?

ATILA: Any web framework. Vanilla JS you can even not use a framework at all.

JASON: Cool. Okay.

ATILA: Even jQuery is allowed here. Anything that runs in the browser is gonna work there.

JASON: Got it. Okay. And so, we've got like looking at the -- looking at the app here, we're --

ATILA: Yep.

JASON: SolidJS stuff and then I see this invoke command.

ATILA: Yeah.

JASON: Let's poke around a little bit. We have got an app. The app looks pretty straightforward. My TypeScript config doesn't like it. Probably because I didn't install.

ATILA: It doesn't small. If you run npm install. I think, yeah.

JASON: I don't have PM PN -- teach me about it. I'm bearing too much psychological damage from making the switch to Yarn back in the day. Now I don't want anybody to change my stuff. Okay. Okay. So, we've got our app here now that we've got the dependencies, it's not yelling at me as much. And so, we can talk a about what that does later, but where does this invoke come from?

ATILA: So, the invoke comes from the Tauri JavaScript package. And it's essentially like that -- in the line 20, like right below here. So, here you're calling the invoke and that's the name of a function that's of a command from Rust. So, what this is doing, the invoke, is going from JavaScript, crossing the IPC bridge and hitting your native code in this case.

JASON: Very cool.

ATILA: Now if you go in npm run Tauri Dev, this is going to start your Vite local server and it's going to start the Tauri app.

JASON: You said it was npm Tauri Dev?

ATILA: Tauri Dev, yes. So, Tauri is the namespace within the npm script. No, no. Just a space, yeah. And Dev.

JASON: Oh, hold on, wait. What? Now this is -- I'm going down a rabbit hole. Hold on for one second. How did you --

ATILA: The Tauri CLI exists in your Node modules.

JASON: Oh! Oh! I understand. So, you're letting -- like we use npm run Tauri to escape into the CLI so that we can then do whatever the CLI commands are.

ATILA: Exactly.

JASON: Cool. That's something I've seen done before, and I haven't really thought about it. That's super-clever.

ATILA: Now naturally like the first time you compile Rust, it takes a little while because it's downloading other dependencies. It's like from a JavaScript perspective is like npm install, npm start. All together.

JASON: Got it, okay.

ATILA: And then once it happens, it's going to pop up the desktop app and on Dev mode. So, if you -- while this is happening, if you can open in source Tauri, the Tauri config -- oh, there you go.

JASON: That happened delightfully fast.

ATILA: So, now if you type your name there and click on the "Greet" button...

JASON: Cool...

ATILA: So, this was what the invoke call did. It went all the way through Rust and responded with something from you. So, as you can see, we're already running Rust commands without even opening the Rust file.

JASON: Okay.

ATILA: And that's essentially all you get whether you run npm create Tauri app. That's what you get. It doesn't look like this. But it's like you come with this -- this command already written for you. And this greet button. That's what we get. Cool?

JASON: Okay.

ATILA: So, now I guess we can jump into the code and go into what source Tauri has for us.

JASON: Yeah. Let's -- I'm just gonna close this down.

ATILA: Yeah.

JASON: So, I'm closing the source and I'm opening source Tauri.

ATILA: Yeah. So, the first one, the most important one, I think, is the Tauri config JSON. So, we can understand what's happening. So, you can see here, there's a before Dev command.

JASON: Okay.

ATILA: So, this happens when we run -- when we call Tauri Dev. It's going to tell, oh, first you need to build my frontend. And then we are locking Vite into the -- this Dev URL. So, it's locking the local host because that's the local host that Tauri is gonna be looking at. So, what we want is in our Vite config, we're actually saying if that part is taken, you don't pick the next one. You just fail because I need to change the config otherwise it's not gonna be opening the right app in my WebView.

JASON: Gotcha, gotcha, gotcha.

ATILA: So, once this is done, then it's going to -- it kick starts your development, frontend configuration. And then it runs the cargo build and stuff under-the-hood for us to do the things that we need to do.

JASON: Got it, okay.

ATILA: Besides that, there are a few things that we can do like we have this identifier.

JASON: Sorry, I'm moving around too much.

ATILA: Every app needs a unique identifier. And it's just this reverse domain annotation. But it can be like anything. It's similar to what you're going to need for the site to ship your app to a store in the end. That's like a whole other can of worms. You don't need to open that box yet. And then you have some nice things that you can control on your app. So, you can define the size of the window, you can define the title of the window. At this very point, you can even pass like a remote window or something. You can pass a user agent.

JASON: Okay.

ATILA: There. You can pass content security policy. And then there are a few quirks and stuff that I skipped for us.

JASON: Okay.

ATILA: So, this is something that doesn't come from the default, like the create updater artifacts and the macOS bundle configuration. So, this one is something for once we decide to have an autoupdater.

JASON: Okay.

ATILA: And the signing identity is that ad hoc signing. Because like to ship a Native app on Apple or on Play Store, you need to have a developer certificate account or something like that. And they charge about a hundred Euros or dollars per year.

JASON: Okay.

ATILA: And you don't want that if you're just doing a hobby project or figuring the stuff out. What I'm doing here, passing the dash, which means ad hoc signing. Which is the thing that once you click to open the app, Apple is going it say, oh. That's kind of weird. Maybe you should not open that. It could be a malware. And then just alt command click and then it opens.

JASON: Got it, got it, yeah.

ATILA: So, then after that you have the icons that I have some surprises for you on this one in a minute. And then the updater configuration for you to push updates to your thing. So, this one, I got a little bit setup here because I am using -- I deployed this app. So, this app is already built and shipped on CrabNebula, which is the company I work for. And we create autoupdates. So, I'm using that one. Just so you can see it working. And I'm passing the public key that I already did because I don't want to make you like create the keys and then copy the keys. There's a private one, there's a password and so on. I didn't to want make you go through this while livestreaming.

JASON: And this is all stuff that like we just go to the Tauri docs and it's -- we just follow the steps to get these keys and stuff?

ATILA: We can run the commands right now and you see how they go. If you just pop the terminal, I can show you. So, the first one, before you stopped -- okay.

JASON: I opened another terminal.

ATILA: Okay. Awesome. The first one that we can do, if you look at your Docker, you have your icon is not -- doesn't look like your brand if you look at your app that's running right there in your -- yeah. There's a Tauri one, right? So, what we can do is use the Tauri CLI. So, npm run Tauri. And okay. Now I can see. Just took a little bit of lag. So, you can run the Tauri and its icon. And you can pass dot slash, and then slash, dot icon-PHP.

JASON: That was weird, I don't know why it did that. Npm run Tauri icon.

ATILA: And then it's dot/on the root of your project.

JASON: App-icon- png.

ATILA: I have this saved for you, and Tauri is going to create all your icons for you.

JASON: Now it's rebuilding automatically.

ATILA: When I was trying this one, I had to do a cargo clean. Let's see how it goes in your -- yep.

JASON: Look at it go!

ATILA: So, now you have an icon. If you go into a story, icons are created all the formats, all the sizes you needed to do. So, yeah.

JASON: Oh, cool. Yeah. So, we get like all of them.

ATILA: That's the first thing we got to do. And in the same way, the CLI has a helper for you to sign your app. Because what we did for the updater, we have a Pub key and we also have a code signing key, which is a private key. So, if you're doing a Tauri app, this one's a little bit more complicated. It's Tauri signer -- so, yeah. And then you have to do generate. And then minus W. So, that's a right flag.

JASON: Okay.

ATILA: And then you pass the path you want to. So, you can just put it in a temp folder or something like that. And then you just pass a name.key. You need to put like the name of the file. Like -- no, no. Just any name. So, /jason.key. Yeah, something like that.

JASON: Okay. Like this.

ATILA: Yep. And now this is going to create the Pubkey. The private key -- what?

JASON: No workspaces found... it's treating -- W as a workspace.

ATILA: Need the double dash before passing the flag?

JASON: Let's try.

ATILA: That's it. Now it asks you for a password, yeah, put it twice. Creates the file for you. If you scroll up, you're going to see there's a path where the files got created and recommending down below that you need to pass those to your build. So, Tauri signing private key. Those are the things that I did before the stream. And I put those in the repository as my secrets.

JASON: Got it.

ATILA: So now whenever our CLI is going to run Tauri build, this is passing straight on. Because I didn't want you to copy this private key and so on.

JASON: Right, right. No, I think that's the right choice. Because I am notorious for leaking secrets. Yeah. Here's the key. Here's the public one.

ATILA: Yeah.

JASON: And so, these -- I won't actually use these so I can just delete this.

ATILA: Exactly.

JASON: Okay. So, cool. All right. So, this is all -- I'm following. It's making sense. I copy/pasted in into there is why that went wrong. Cool. So, we've got it --

ATILA: Okay, so --

JASON: We've got our app running, calling into Rust, and I don't see anything that looks like a web app to me yet which is pretty exciting.

ATILA: Yep. What we can do is basically bring your episode list, right? So, we can just uncomment that line 14 with the schedule.

JASON: 14. Got it.

ATILA: Yeah. And then on top of that, we have get schedule that I have already written.

JASON: Okay.

ATILA: And it's fetching the API from your website. And now if you go below there is a suspense call in your JSX that I commented out. So, basically this is --

JASON: Whoops.

ATILA: This has a suspense from your gets, from your API request.

JASON: Why is it not working? Uncomment... oh. Because it doesn't like this for some reason. Fine. I'll do it the hard way. Thanks for all your help.

ATILA: Awesome.

JASON: Okay. This is going well. It's missing the episode.

ATILA: Episode preview is just a component you need to import. It's already created.

JASON: Okay.

ATILA: Yep. So, now this is a regular fetch call coming straight from your browser. And if you run Tauri, you should be able to see the list that's coming back from this scheduled API endpoint. There you go.

JASON: There it is. Okay. Already very -- okay. So, what we're doing here is we're making a call, and this is through the WebView.

ATILA: Yep.

JASON: Okay. And that means because we're using suspense, whenever makes a request and load the page, just like on a regular website. And from a Native app standpoint, we are -- we're basically giving somebody like a button they can push to check the current schedule.

ATILA: Yep, exactly.

JASON: Got it.

ATILA: And right now, because it's a Native app, it's a web app, you can inspect source. If you right click on the Dev mode, the DevTools is available. If you right click there, you can pop up the hood, mess up with it and file requests from there.

JASON: Okay. Cool. All right.

ATILA: Okay. So, now what we can do is push this request to go through Rust, maybe.

JASON: Yeah.

ATILA: In this case, what we can do is stop the server and I know you like Astro so I think you're gonna like this one. You can run npm run Tauri, and you can say: Add HTTP.

JASON: I do like that. Okay.

ATILA: Okay. What this is going to do is this is going to add your dependency to the cargo TOML and add a dependency to your package JSON. And if you open up the source Tauri, if you run on lib... where is it? Where is it? So, yeah. On the source first and then lib. You're going to see here like this is like what -- what makes Tauri tick. So, if you can see, here's our Tauri command that we ran in the first time.

JASON: All right. So, this is greet.

ATILA: Yeah. And then we are passing it down to like the invoke handlers over here. So, we are passing greet over there.

JASON: Got it. And now I see here is the HTTP...

ATILA: We are already appended the plugin for you.

JASON: Cool, okay.

ATILA: As long as you're using the Native APIs, you don't need to touch Rust. You can run that thing for any official plugin and it's just gonna work.

JASON: Cool. Somebody is asks, with the WebView open Safari DevTools on Mac?

ATILA: Yep.

JASON: It will. Yes. Very cool.

ATILA: Yep. So, awesome. So, that's it. So, now we have the HTTP. The other thing that's gonna happen right now that's going to break us is if you look at here we have now a capabilities folder.

JASON: Capabilities. Default.

ATILA: Yep. Right here.

JASON: Sorry, I keep scrolling before you --

ATILA: No worries, no worries. Now we got like the capabilities, the permission. So, we're seeing the default permissions for the HTTP. You see we didn't allow any URL whatsoever. So, now if we just trigger it in on our fetch, this thing is not gonna let the request go through. Right? Because we need to -- we need to allow list the URLs.

JASON: Oh, right. Okay. And so, this is part of that security posture where like you can't just make arbitrary calls. You have to as a developer say: I am allowed to call this endpoint.

ATILA: Yep. So, you can, for example, if you try to add to this array, you're going see that there is some autocomplete over here. And it's going to suggest you a few of them. Yep. There you go. So, these are all the permissions that are there for you. As you can see, since in v2 we also added deny. So, not only you need to allow list the ones you want to use, you can also explicitly deny some of them.

JASON: Okay.

ATILA: So if your app is going to do something with the filesystem, you can explicitly say, no, I don't allow this app to delete files.

JASON: Oh, interesting. Okay.

ATILA: Yeah. The filesystem is -- it's the most tricky one because even like that you can also restrain the scope of it. So, you can say, oh, you're not allowed to go. So, the filesystem is one that we're particularly careful with. But yeah. So --

JASON: This is cool.

ATILA: Do you want to see how the error message looks like when we do something we can't do on Tauri?

JASON: Let's do it.

ATILA: So, let's go back to your JavaScript. And --

JASON: Back to my JavaScript it here.

ATILA: And the only thing we need to do now is import fetch from something else on our get schedule. So, I think if you command click, it should offer you something. Otherwise we can type. Nope.

JASON: Doesn't look like it's got one of those.

ATILA: Okay. So, sometimes VSCode takes a little longer to --

JASON: Oh, wait. That's not what I meant to do. Yeah, I think it's... it's believing this is from MDN.

ATILA: Yeah. It's a named -- it's a named import. Yeah. So, from @tauri-apps.

JASON: This one?

ATILA: Yep. Perfect.

JASON: Okay. We changed it and now this is from Tauri.

ATILA: Syntax is absolutely the same.

JASON: Cool. No functional or like code changes.

ATILA: Nope. And then if you run it again, we are not gonna have a list. As you can see, it's re-compiling because we added something to the cargo TOML. Every time you change something in the cargo TOML, it needs to recompile things again.

JASON: Okay. And we can see that it's broken.

ATILA: Yep. So, this thing is never gonna -- so, if you pop the DevTools and check the logs... you see here. So, promise rejection. Because we didn't pass the URL to the scope. And then it suggests you.

JASON: Oh, boy. Accidently clicking stuff. URL not allowed on the configured scope.

ATILA: URL not allowed, and these are probably the permissions that you want.

JASON: Got it. Oh, that's an internal DevTools. So, I'm --

ATILA: Yeah. So, that one is also -- that's something else.

JASON: Got it.

ATILA: But it does suggest the scope and so on. So, now we can go back to -- you don't need to stop the server or anything. We can just go back to the capabilities.

JASON: Okay. So, back to capabilities.

ATILA: And then if you add -- now we're going to instead of adding a string, we can add an object. And I think this one I can try to pass over to you.

JASON: Oh, yeah. You can. You have the ability to just copy-paste if you click into the window.

ATILA: Okay. Wait. I need to switch this and then enable keyboard. Okay. Let's try again. There you go.

JASON: Okay. I might have just double -- double wrapped that. I did.

ATILA: Yeah.

JASON: Let me get rid of my extra wrapping. We're saying for the identifier HTTP default, we want to allow anything from my API.

ATILA: Yeah. And then because we changed capabilities, it just -- the server stopped, recompiled and now things work. And now this request is going through Rust.

JASON: Got it. And then Amr says the other error is because core: Default is not -- here?

ATILA: Yeah.

JASON: And that should solve that DevTools problem.

ATILA: Yeah.

JASON: Okay. Perfect. So, we will do that. And then this should open up again. It opened in my wrong -- or my wrong monitor, but here it is. It's working. And if I pop open the DevTools again, we got nothing. Hey!

ATILA: Yeah.

JASON: All right. So, that's pretty -- that's pretty cool.

ATILA: Yep.

JASON: This is great. I'm feeling good about this because we haven't done anything that confuses me yet.

ATILA: So we can try now to send a Native push notification. How do you feel about that?

JASON: I feel very good about that. I have been thinking about ways that I should try to be more annoying. And I think having a way to send everybody push notifications is -- that would work nicely.

ATILA: Yep. Awesome. So, let's do that. So, if you go back to your JavaScript file, I wrote some in the helpers, you see there is a little notification, TS, waiting for you.

JASON: Got it.

ATILA: So, we can go about see how it goes. You see there's already some things that we're importing. And it has this asynchronous function. That's JavaScript. You can just -- the way I wrote this is that you can just put it on whatever framework you have. And this should work. And then what we're going to do is just do the wirings on whatever our Solid app starts. It's going to check if there is a permission to send notifications from that app. If the permission is granted, then it's going to send the notification.

JASON: Right.

ATILA: And if the permission is not granted, we can check if it is. So, if there's no permission, we ask for permission. And then once it's granted, we send it. If it already has permission, we say, oh, we already got it so then we send it anyways.

JASON: Got it.

ATILA: And if the permission is denied, we do nothing. We don't want to be that person, right?

JASON: Yeah. And so, with this one, you're exporting a function. If I come out here and I say... we could probably just attach it here so that I could do it on a click. Or it was handle notifications?

ATILA: Yeah. So, yeah. It's handle notifications, sorry. So, this is just like a --

JASON: I want to --

ATILA: -- yeah.

JASON: Now when I click that greet button, we should get a greeting and also it should send a notification.

ATILA: Yeah. The thing is I don't know if you have notifications allowed for your terminal that's running Tauri. Usually the way that I do for testing this is actually building it. That's actually we can see how it goes about building your app in this case.

JASON: Okay.

ATILA: So now you can just pop the hood, stop this instead of --

JASON: Panicked.

ATILA: Oh! We didn't add the notification create. That's something they always forget.

JASON: Oh. Right. And that crate is the one that we -- where was it? In notifications...

ATILA: That was the JavaScript. The JavaScript dependency is actually that we let Rust knows that it has it.

JASON: Okay.

ATILA: It's not in your tunnel, you add the npm run Tauri add notification.

JASON: Oh. Easypeasy.

ATILA: So, again, it installs the plugin. It has the capabilities. So, now let's go to the capabilities and check if something changed.

JASON: Down to capabilities. I need more window space. Capabilities.

ATILA: There you go. So, as you can see down there, it appended for you the notification default.

JASON: Got it, okay. So, then if I make an educated guess here, I'm gonna do run Tauri build?

ATILA: Go for it.

JASON: Okay. And so, this is going to kind of bundle everything. We're compiling -- and we would have to compile anyways because we just added a new crate. If you have been running Dev and you don't add new crates in between Dev, does it compile again when you build?

ATILA: Yeah. That's something that we haven't talked about. But usually what you want to do is have a release profile defining your cargo TOML. Because you can have a smaller one because by default if you build the app, Rust is going to make a bunch of things to make a decent stack trace, but you don't need to have that in a production app.

JASON: True.

ATILA: And also we can even instruct the Rust compiler to do things more sequentially so that optimizes more the connection between the dependencies. So, that takes a little bit more time to build than you would want in Dev mode. But it leads to a smaller bundle in most cases.

JASON: Got it. Okay.

ATILA: And all that is available in the docs. It's just like a group of six -- six keys that you can pass. Configuration keys that you can pass to the TOML and it's gonna work in pretty much every app.

JASON: Got it. Okay. Looks like we're getting pretty close here.

ATILA: So now --

JASON: make a --

ATILA: There you go. So, now you have your app.

JASON: Neat.

ATILA: And if you open it up...

JASON: Neat. Now if I greet, we should get our notification.

ATILA: Did you get it? Oh, there you go.

JASON: We allow... and then... let's see... so, that...

ATILA: It went?

JASON: Try that again now that I've granted the permissions. Am I in do not disturb?

ATILA: Ah-ha, yeah. Oh.

JASON: How do I... -- what is the... I forget how this all work. Hey! There it is. Look at 'em go.

ATILA: Nice, nice.

JASON: Cool. Extremely cool.

ATILA: You see, no Rust involved. And that's the kind of stuff that we can do. So, now we already talked about some of the two Native APIs. We talked about signing the code. And the ad hoc signing. So, but so far what you -- one of the biggest issues about using the Native binaries in the Native web view is that you have to have a VM if you want to distribute to other platforms, right?

JASON: Uh-huh.

ATILA: So, the last thing that I wanted to show you is GitHub Action that I mentioned to you that I'm terrible writing YAML, but I got one about -- with a bunch of typos right now. So, this release YAML over here is actually going on -- it works on dispatch. What it's doing, creating a matrix. And you can build for desktop, Windows and Mac. So, if you scroll down, I'm pushing it to CrabNebula. I have an org there and I'm pushing your app over there. And then what happens is that I draft the release. And if you just keep scrolling down a little bit... then we have like that matrix. So, you can see there's a -- the draft runs on the matrix. And if it -- it doesn't fail in the -- in this one, it fails on the build. But then we have all the images. And for macOS and Linux, I'm building on the latest. For Ubuntu, v2, we recommend 22.4 -- 04. And if you just keep going. We then install, in this case, pnpm. And we have all the cache set up and then we install the Rust tool chain. In this case I'm not using cache for some reason. And then once you're on Linux, you need to install the WebView that we're going to use. And make sure the system is up to date.

JASON: The conditionals there --

ATILA: Yep.

JASON: I'm definitely not a GitHub Actions expert.

ATILA: Yeah.

JASON: But whenever I see these, ah, this is clever. But whenever I try to write one, I don't understand how any of this works.

ATILA: I'm right there with you. Jacob and I had a hard time writing a GitHub Action from scratch on his livestream. I make all the typos and all the intention errors. And it's always death by a thousand cuts when I'm writing a YAML file by hand. But then again, this is the thing that makes -- starts making things interesting. Where we can pass a target for the Tauri build and then Tauri knows the -- what we want to build for. And here is the moment we are signing our code. So, as you can see, those secrets are coming from the --

JASON: And these are the keys that I -- I generated these, right?

ATILA: Yep.

JASON: So, if we were using mine, I would have had to go into GitHub and set up secrets.

ATILA: Exactly.

JASON: Got it.

ATILA: And then once that is done, then it becomes your release part. This has the CrabNebula action that just passes -- uses our CLI to push those binaries and those artifacts and then publish the release to make it available to everyone.

JASON: This is extremely cool. I -- and so, when -- like how does this work if from a practical standpoint? Because, you know, you work at CrabNebula. so it makes sense that you would release on the CrabNebula cloud.

ATILA: Yep.

JASON: If I want to release on the CrabNebula cloud, what does that mean for me as a -- like an individual? Am I -- is there like a free tier? Is it, you know, where does it -- I guess what does it cost me if I want to publish my Tauri app? I need my $100 a year Apple developer certificate.

ATILA: Oh, yeah. So, you need -- if you're going to publish to the stores, then there is some stuff about like having the certificates. So, I think Apple in Europe is at 99 Euros a year. I think Android for the Play Store has something very similar.

JASON: Okay.

ATILA: I'm not entirely sure about the, like, how much it is right now.

JASON: Sure.

ATILA: And then CrabNebula, we have a two week trial. And the first fee is 7.50 right now a month. And then there is a metered threshold. But it's pretty generous in the beginning.

JASON: Got it.

ATILA: Oh, Android is 25, Amr just said.

JASON: If I want to publish my app, it's $100 a year with Apple, $25 one time for Android. Got to check -- I imagine there's not for Linux. That would feel very against the spirit of Linux.

ATILA: Yeah.

JASON: And then you pay 7.50, that's $7.50?

ATILA: I'm counting Euros. But yeah --

JASON: 7 Euros 50?

ATILA: 7 Euros 50 per month. That allows you to do a bunch of releases and the autoupdater. The releases in this case is just for you to version your stuff and make the binaries distributable. The autoupdater, in my opinion, is the biggest game changer. But we didn't get to that part yet. Because like creating autoupdater service is kind of annoying. We can go check the Tauri config and see what it would entail.

JASON: Okay.

ATILA: If you want to. So, it's source Tauri...

JASON: Tauri config. Here it is.

ATILA: If you see endpoints, it's connecting to our CDN. So, what happens in this case is you have the org and the app number and then you can see there is a target, an architecture, and the current version. So, this means that every time you hit that endpoint, Tauri is going to replace those template strings with the architecture and the current version of it. But also, you need to send a public key. Your service needs to be able to check the public key against the private key because you don't want any other app being able to, like, tap into that service or fetching updates and stuff like that. So, once you have -- once you send a version on the pass parameters, your service is going to reply either with a JSON, with the path of the update and so on. Or with no. And then Tauri can then figure out to ask if it's going to -- to prompt the user for an update or if it's going to automatically download and then refresh and so on.

JASON: Cool. Okay. So, and what this -- like let's talk about what this means to make sure that I've got my head around it. So, what this means is, if I'm using Tauri to build my app, and then I set up the autoupdater as I'm distributing through CrabNebula, then when I make changes to my app, I don't have to wait for people to download the latest version of the app. They'll be getting that automatically through CrabNebula? Or maybe I'm misunderstanding.

ATILA: So, what's going to happen is depending on how you write the logic, your app is going to hit that endpoint and automatically know if you are -- if you have an update for your app. So, if you -- you can go to your JavaScript file, again, in that helper folder. There's an updater.ts. That's where I put some logic for us. So, yes. So, this is basically like if you're going to do like -- if you are going to use push up dates in your Tauri app, that's more or less the logic you're going to write. So, you have the updater create --

JASON: Oh, okay.

ATILA: Yeah.

JASON: All right. So, I understand. What I'm doing, then, is I'm basically able to automatically show users that there's a new version and then prompt them to hit the button to update.

ATILA: Yeah. And then with that --

JASON: Got it.

ATILA: -- you can send like the release notes. You can send what is the version. So, in this case, you can -- perhaps you can even add some other information on the release notes. And then if there's a security update, you can decide -- Tauri allows you to have an API that silently updates and force refreshes the app. If it is a huge exploit, a huge leak and you just fixed it, you can make, okay, I want everybody to get this update as soon as possible. Or if it is like just a live quality feature, you can just prompt them and they download whenever they see fit.

JASON: Got it.

ATILA: These are the logic you have full control on. What CrabNebula does is help you manage those release leases so you can push release, you can do all the stuff that you can also do manually on other things. Like essentially like a -- it's a better UX in this case. And then it connects that to the autoupdater so you have -- you have the -- you have the whole like experience connected in this case. So, it's kind of a server -- like the way I say to people when I'm out and stuff, it's like Netlify, but for packaged apps in this case.

JASON: Gotcha.

ATILA: That's what they're aiming for.

JASON: Okay. I understand. I mean, this is cool. This is very cool. And I like the -- I like that it's sort of stuff that I want from Native apps. I like the idea of knowing that there's something new, you know, I know that my phone doesn't always download the latest version of things without me going into the app store and like checking for updates. So, knowing that there's something available and not just waiting for whatever the next time out is, is great. From the standpoint of like, wanting to be able to access Native features of the phone, or the desktop or whatever device I'm on, that's also really interesting because there's stuff that I would be interested in doing to make optional for people. Like, for example, when I go live. It takes a while, if it ever updates, for the Discord thing to time out and check the YouTube API and finally send the notification. A lot of times it will be 20 minutes before people get the notification that we're live. And then like, you know, it would be neat if there was a native app that could just buzz your phone, hey, it's about to start. If you wanted to watch this, this one is going. And I could think of a few other things that are cool, if you want to deep link into another app. Some make that easy.

ATILA: Yep.

JASON: You could deep link into Spotify or whatever. But Native apps tend to feel better about moving between different parts of a phone or a device because they -- you know, that's what it was designed to do. It's not the web sort of like hopping out of a web link and into another thing. So, yeah, okay. You're kind of -- kind of getting -- you're making a good case here for why there are solid reasons for reaching for a tool like this.

ATILA: I mean, there's also like -- you can go into even deeper like native APIs. Like you can have system tray, for example. You can have a tray icon that pops up and lets people know -- like you know that those next meeting stuff, you can say, Jason's about to go live. This kind of stuff. That's run on the background. You can have like -- we have also like for mobile, you have the NFC stuff. So, you can be at a conference and just by NFC you can just tap someone and invite them for a calendar or something like that. And so on. People can send each other like their -- the stream that they want to watch. And this kind of stuff. Because you mentioned Solid, yeah.

JASON: But no, I like -- yeah, I like that. And I think there's also, you know, there's -- there's a certain element of like fun. Even if it's not necessarily the most practical thing, right? Where you can build an app that's just fun to play with, it's fun to use. And, you know, I remember years and years ago like when NFC was new, right? There was an app did or I don't know if it was new. It was the first time I had seen it. It was called bump. It was at SXSW. And everyone was running around doing bump to share contact info. That's now become sort of a standard feature where iPhones do it. Put your iPhones on top of each other, it will prompt you to send the contact info across and give somebody the phone number just by touching phones. Which is great. But with bump, this is so cool. Was it practical? Absolutely not. Did it only make sense when you were at a conference and were around dozens and dozens of new people and needed to trade information? Yeah. Holy crap. It was so much fun. It was this moment that everybody was doing it. And I don't think any of us at that conference ever used it again, but it was so much fun for that moment. And I love that idea of even if you don't necessarily want to build and maintain a Native app forever, if you're going to a conference, if you're going to a -- some kind of special event, you can do fun stuff like that. That has notifications. It's got the NFC, like the ability to interact with people around you through the Native -- the Native capability to the phone. I really like that kind of stuff. Like it makes me really happy. And finding ways to lower the barrier to building an app that's just kind of just for fun. I really -- I really like that.

ATILA: Yeah. Yeah. Me too. That's one of the things that really impressed me on the first times I wrote Tauri. And right now Vite Conf it happening. And I have a talk there that we're talking about Taurify. That's Daniel, that's one of the creators of Tauri. So, yeah. And we created the CLI called Taurify which you can run with one command and turn any single page application into a Tauri app. And with that, I -- it's Taurify.app. No, that's -- wow.

JASON: Taurify.app. This one?

ATILA: So, this one, yeah.

JASON: Got it.

ATILA: This one is like we're -- it's still like very early stages. But what happens with this is if you run this command like Taurify in the root of your project, in your single page application or any wide application, it's going wrap it inside a Tauri app and put your app inside. And with that, I didn't tell you that, but Tauri can expose the Tauri to the window or inject that into your API. You can use the JavaScript APIs from your app. You can have your app checking if they are in the context of Tauri and then use the Native APIs.

JASON: Oh, interesting. Okay. So -- something like --

ATILA: In that case, you have one build.

JASON: Yeah. I could have my website and on my website, I could check to see if I'm in the Tauri environment. And if so, I could show additional capabilities like the NFC or something like that. And otherwise run it like a Web app. That's really interesting.

ATILA: Yep. It just opens up for like a bunch of different opportunities. And I mean, and then there are some stuff because Taurify is also kind of a service. There is some stuff that allows you to do that. To even have something that feels very web to me. When you have a build like for a website, you have builds that go super-fast. It's like takes -- I don't know. 30 seconds, 40 seconds. If it goes a minute, it's too much for a website. And let me show you in our little -- this little app that we just created.

JASON: Yeah.

ATILA: I'm gonna beam you a link --

JASON: Okay.

ATILA: -- for the latest action that I ran and then you can see for how long it ran. So, this is what happens if you go like show all jobs over here. Yeah. It ran for 15 minutes because macOS latest goes for 3, Linux goes 11, and Windows goes 14. Like from a web developer standpoint, that's an eternity. Like if you have like a 15 minute cycle for CI/CD.

JASON: Right.

ATILA: And because Taurify knows that you're not like recompiling Rust, it can skip that and then we use something called over the air updates. Which allow us to just yank out your JavaScript frontend and put the new one in. So, then the builds go as fast as the web. And that to me is kind of mind blowing. Because in a monorepo, you have an Nx plugin or something like that. From the CI, building this website into all these other platforms as well. And you don't need to know about it. It's really cool. To me at least.

JASON: That's very cool. And I think, you know, it's definitely one of those things that as you build out a company, as you, you know, you start building out a service, there are gonna be reasons that it would be nice to have a Native app. And you know there's business reasons like, you know, Native apps have -- like you can get somebody to come and do a Native app. It's really good from a next investor deck update. But also from a utility standpoint. When you are building something and getting people faster access. Like it works offline. It works -- you know, you can do NFC stuff where you have access to the Native -- I guess the web is getting better and better at Native stuff like cameras and gyroscope and stuff like that. But it is nice to have. You get the deep links, you get the integrations. All that stuff is really interesting to me. And if it's not like hire ten more people to build that app, to build the Native apps, you know? That --

ATILA: Yeah.

JASON: That sort of gets interesting. Where now I'm not as stressed about it. Maybe it is worth considering if all it takes is being thoughtful about which of these features we want to add. Adding to the frontend, if we're in a Tauri frontend, expose this extra stuff. That's interesting. And knowing I can update without having to have somebody whose entire job is deal with the Apple store submission process. Stuff like that is -- it changes the math for me. Because prior to talking to you about this, if you had asked me about Native apps, my answer would have been an immediate like it was not possible for me. Right? And now, seeing this, I don't know that it's -- I don't know that I have a good enough reason to build an app, but I don't think I would hard nope it out of like fear of being able to ship consistently.

ATILA: Yeah.

JASON: Which I think that's cool.

ATILA: I -- yeah. I'm 100% there with you. Like, is it -- is it like something as easy as shipping a website? No. It still has its difficulties. It still has its challenges. There's stillings you need to learn like code signing and like some concerns about security and like permissions and so opinion. But the entry barrier is way lower with something like that. And I think that's very appealing if you have like an early product or a startup. Where you don't need to hire a whole team for it. At some point you can just find your market fit. Find like your audience. And see if that works. So, that's one of the things that excites me a lot about it.

JASON: Yeah. I agree. And I think, you know, that's -- that's always the magic of this space. Is can we lower the barrier to entry for somebody to show up and try? Be competitive.

ATILA: Yeah.

JASON: The thing that I've always loved about the web is you don't have to have a million dollar budget to build something that can be really successful.

ATILA: Yeah.

JASON: And so, applying that similar democratization of leverage, I guess, to building Native apps feels good. It feels like something that -- it opens a lot of doors. I'm excited to learn about this. I'm excited that this is available to folks. And I don't know, what do you think, chat? Are you gonna go build some Native apps? What do you got in mind? I think they're too busy having a pun-off in the comments. [ Laughter ]

ATILA: Yeah. People -- yeah. So, the thing is, another thing about Tauri that you might have noticed from your chat is that the Community is not only like super-open, but they are also very, very passionate. As you can see, they just jumped in and they're answering questions and stuff like that. That's usually how it goes down whether somebody comes into Discord and wants some help. So, yeah, if any of you are watching the chat and want to get started with Tauri, you're very much welcome. You definitely belong in the -- in our Discord. If you're not a Rust developer, more so. Come in. Everybody can help. I'm not a Rust developer. They have tons of patience with me. They answer all my questions. Yeah. And every now and then I'm stressing the limits and I'm trying to get -- to get my web brain to work in Tauri. And they haven't kicked me out yet.

JASON: I love it, I love it. No, I mean, I think that's -- it's good -- it's good, I think, to have team members who aren't necessarily experts, right? Like I always thought that one of the major strength of having people on teams is you want people who bring in different perspectives and, you know, bringing in a web developer into a team that is Rust experts trying to make something that's friendly to web developers, like that seems like a good call. Because if I already knew how Rust works, I wouldn't need the web development framework -- you know what I mean? Like I would just be writing the Rust. So, no, I think it's -- I love the approach. I love the mindset and I'm happy to see that it's, you know, it does feel like something that is approachable for me who is historically had a hard time actually getting through any Rust learning. Just through time limitations, you know?

ATILA: Yeah.

JASON: So, okay. We're coming up on time here. So, why don't I ask -- while we're in the browser here, where should people go if they want to learn more? Like we've shared the Tauri site. I'll throw that up again.

ATILA: Uh-huh.

JASON: I've shared your Twitter, I'll share that again.

ATILA: Thanks.

JASON: Where else? Where else should people be going if they want to take next steps here?

ATILA: The Tauri Discord is always very active. I think it's Discord.gg/tauri. Over there, yeah.

JASON: Got the link there.

ATILA: That one is very active. And everybody is there pretty much all the time. We make a few jokes about one or two of our folks over there. Like Fabian Lars, he's a beast answering support questions and any kind of things from people. There's also this repository called awesome-tauri, which is maintained by the Tauri folks as well. So -- yeah. This first one. So, this one has a list of awesome resources, apps examples and things like that if you -- if you're looking for something that you might want. If you're looking for a previous -- previous work that has been done with Tauri. That's a nice place to be at. And yeah. I think those two places and the docs are definitely the places to go. Give that a scroll...

JASON: This is great. So, yeah, we've got a few tutorials here. We've got a ton of templates which is -- I like seeing lots of templates.

ATILA: Even I created my own template. I just shipped the CLI. All the bells and whistles about Tauri there. I plugged it in. If you like solid start and if you want to get your feet wet with Tauri, you can use that one. It brings like the profile release, it connects the debugger, everything like that's open source and free. And so on. And then you can get started. You can leverage it to write web apps and then go deeper into Rust in this case.

JASON: Very cool. And these are the example apps. This is all very cool. Yeah.

ATILA: Yeah.

JASON: This is exciting. I like this a lot. I think this is really fun. I always appreciate a good list like this, just to help me get my head around what people are doing, what's possible. And you flagged the ones that are closed source, I'm not going to look on that one. I'm going to look on one of these ones. This is super-helpful. This is a longer list than I expected, to be completely honest. So, that's super-cool. It's great to see that there's so much out there, so many examples out there. And very cool to see that you have over 200 contributors just to the resources list. Like that's -- that's pretty -- that's pretty awesome. Really points to what you were saying earlier about having a very active and sort of welcoming community.

ATILA: Yeah. It is active and it's on a very fast growth curve. Like if you look at the previous state of JS survey. I think it was like five months ago, three months ago. It had a bunch of like interest. It had a bunch of like user satisfaction and so on. And what I feel like I started like I went like -- I did a nose dive in Tauri about a year or so ago. And I see things getting more and more agitated on our Discord. I did a few streams there on my YouTube channel and so on. I like to play around with that, recording some videos. And the feedback that I get from people getting curious about it is amazing. So, it is a good moment. Especially with the v2 release.

JASON: Yeah.

ATILA: So --

JASON: Well, very cool. Yeah.

ATILA: It is an exciting time.

JASON: Super-exciting. Thank you very much for spending some time here. Let me do a quick shoutout again to our captioner and our sponsors. We've had Amanda here from White Coat Captioning taking down all the words that we've said today. And it's, you know, human captioning -- just great. It's so much better than the robo captions that make up new words for what the names of tools are and stuff. That is made possible by Netlify. So, let's drop a link to Netlify in the chat. Thank you, Netlify. Click that link to let them know that I sent you. And then we have been pair programming with Tuple all day. And that's how Atila has been drawing on the screen, shared copy-paste buffers, give it a try. Click on that link and let them know I've sent you. I've linked to Attila. What do we want to do here? Do you have any parting words before we start sending everybody on their way?

ATILA: Man, what I have to tell you is I just need to thank you for being this awesome host. I knew it would be an amazing experience, I knew I would have a blast. But you exceeded my expectations. So, thanks a lot. You're such a nice guy to work with and to talk to.

JASON: Well, I appreciate that very much. And, you know, like wise, thank you so much for coming on. I think you did an amazing job here. And thanks, everybody, on the chat for asking great questions and hanging out today. We do have one question because ViteConf is going on, when is your ViteConf talk?

ATILA: My ViteConf talk must have gone online a few minutes ago. There's two cycles. It went live the first time and then 12 hours later it goes again, it premiers again.

JASON: Okay.

ATILA: So, mine was towards the end of the schedule on the Native apps. So, I think I'm the only one that's talking about Tauri. In this case, yeah. That's me.

JASON: So, looks like that is gonna happen in about two hours.

ATILA: Oh, okay.

JASON: I don't know if that's the replay or the first play. But yeah, looks like this will be live in about two hours. It is going now if you're not already signed up. Go sign up and get in. It looks like there's all sorts of good stuff. Look at the list of names. All star lineup, so much cool stuff happening in the Vite space. We have had Vite on the show in multiple iterations. It's powering most of the frameworks. And the last holdout, the only framework left, is Next that's not using Vite under-the-hood in some capacity. This is a good way to see what's happening in that Community and really kind of the underlying power that's driving the whole JavaScript ecosystem at this point. So, yeah. With that, I think we're gonna call this one a wonderful success. I had a great time, I hope you had a great time and do make sure you go check out the schedule because we've got great stuff coming up. Matt Pocock next week, Bree coming on the week after. And I'm gonna do a quick shoutout to the Sanity team. We're doing a whole wild thing where I'm going to be doing a live version of the Webdev challenge. If you're in San Francisco on October 23rd and you want to build something silly with me and take the web Dev challenge, we're gonna be doing it. We've got room for I think 50 people, maybe a hundred people. So, seats are limited. Make sure you register for the event. Hanging out with me, and others. Building and having a good time. Having a good time. food and drinks, there's a party afterward. Meet the Sanity team. Have a good time. Head on out there. Thank you, all. Atila thank you again for spending time with us tonight. Last chance, anything to say to the chat before I end this thing?

ATILA: Thanks for coming and very helping me out with your questions and answering your own questions because that was awesome. And yeah. See you around! And yeah, you guys were also awesome!

JASON: Awesome. All right, y'all. Thank you so much. We will see you next time.

Learn With Jason is made possible by our sponsors: