Welcome to DejaVue, the Vue podcast you didn't know you needed until now! Join Michael Thiessen and Alexander Lichter on a thrilling journey through the world of Vue and Nuxt.
Get ready for weekly episodes packed with insights, updates, and deep dives into everything Vue-related. From component libraries to best practices, and beyond, they've got you covered.
Welcome to Deja View.
Alex:Your favorite View podcast, you just don't know it yet.
Michael:I am Michael, and I'm joined, here with Alex.
Alex:Hey. How's it going? Yes. I am a Nuxt team member. I also do some YouTube content about Vue.
Alex:Js, and I'm a web engineer consultant at bay. And, yeah, with me is Michael. Hi, Michael. How are you doing?
Michael:Pretty good. Just a quick intro for myself. I am a content creator, and I teach all about Vue with courses and my newsletter and this podcast, among other things. And today, we're gonna talk about Nitro, and how Nitro fits into this whole Vue and Nuxt ecosystem.
Alex:Absolutely. And I mean, I I think it would be fair to start with, like, everybody using Vue as, like, a single page application and maybe have their back end in something that's not JavaScript related might not even have heard necessarily from Nitro, mainly because it's used under the hood by Nuxt. Js or when you want to set up your own JavaScript, like, back end or or server, then you can also use it as as a server framework.
Michael:Yeah. And it powers a lot of the different functionality that Nuxt has. And what's interesting is that it's part of this un JS, package or I get I don't know what you would call it. Group of group of things.
Alex:Ecosystem. Yeah. Yeah.
Michael:And and the whole goal of js, which I I really like, is that instead of just building out Nuxt and making it awesome, which it is, un JS is, well, what if we could take some of these awesome things we've done with Nuxt and package them up in a way that they can be used outside of Vue or in other places. Maybe you're not using Nuxt, but you can benefit from using Nitro. And so that's a part of how this all fits in together is instead of building this big monolith of Nuxt, let's break it into different pieces that we can, reuse in in different places and and help the entire web development community instead of just Nuxt.
Alex:Exactly. And also it makes some things easier, some things harder. Like, if you have separate packages, then they have a separate purpose, so it's easier to test them as well. Still remember in Nuxt 2, with lots of things in the core, it was sometimes pretty difficult to test certain functionalities. And, of course, the other point is, as I said, like, it's also about contribution.
Alex:So Nitro itself, and we'll go in into a bit what exactly it is, is not only used by Nuxt under the hood, but also by Analogue, which is a meta framework of the Angular universe, by SolidStart, so Solid's meta framework, and by the new 10stack start framework by Taneli, who also wrote, like, 10stack router, 10stack query, and so on. You might know him, especially if you also heard about, the React, ecosystem a little bit. So it's really nice to see that the plan of helping the broader ecosystem, it surprisingly happens quite often in the Vue ecosystems, like Veed, Volar, and, yeah, also, on JS. This really works. And, also, people don't say, oh, we didn't build it, so we don't use it.
Alex:Instead, let's join forces and figure out how that works while still having, I don't know, our our own, like, USPs or our own, like, paradigms and and believes in that. So just because, let's say, SolidStart is using that, doesn't mean it will be the same as as a Nuxt, for example.
Michael:Yeah. And so we have a lot of benefits from that because we get, a broader base of contributions and all that kind of stuff, which ultimately end up making Nuxt better as well.
Alex:Yeah. Every every framework using it. Right? Like, more eyes, also more people with, more time hopefully to contribute and saying, oh, we we might need that functionality that can be used in in various different scenarios as well, or we need to make it a bit more extensible to realize our goals. That helps also to, yeah, make sure, every everybody using it can can benefit.
Michael:One of the things that that's tricky to understand about Nitro is, like, the separation or that line between where Nuxt ends and where Nitro begins. Like, how much of Nuxt and what Nuxt is and what it does is Nitro? And, I think you've covered this in a video that you did. And in mastering Nuxt 3, I've also covered this because it is one of these, like, fundamental important things to understand what what is next, what is Nitro, and how can we, understand that that difference.
Alex:And I think it's a very common misunderstanding as well. Like, people don't know necessarily the same when people start learning about service side rendering, and they're like, oh, okay. Now every request is rendered on the server, which is not the case. It's only the initial one.
Michael:Mhmm.
Alex:So, figuring that out early is is key, of course. So, yeah, Nitro, as mentioned before, is a server framework, so it runs only on the server. Meaning, everything in the client, it's purely an Nuxt and Vue, not related to Nitro at all. What Nitro gives, especially when being used by Nuxt but also standalone, is the option to create some kind of API endpoints, like server routes, to have some caching. We go into a few of these features in a bit and lots of server related things.
Alex:So if you have if you have a Nuxt instance, for example, and you create a server folder, then everything in there is handled by Nitro. And that's pretty cool, first of all, because Nitro itself, you might have used it already in, like, a standalone project or the other way around. So it it integrates seamlessly. And also, Nitro provides some types because Nitro knows, okay, I have a server out. In the end, I might respond with some data or some JSON.
Alex:And based on these types, Nuxt can infer then when hitting, like, API slash test, let's say, and that's an endpoint defined by Nitro. It knows because type Nitro emits the types, what kind of types come back. So you have end to end type safety in a way or 2.
Michael:There are some other features that go beyond what you might think of as just being a part of Nuxt, such as, there's this key value storage that comes with with Nitro, which is based on another package that's part of this whole on JS ecosystem. And it's really cool because it makes it easy to to to store simple things and simple data. One, you can make it more than simple. You can make it really complex, but you don't always necessarily want to add a whole database table, and, you know, update your schema and, like, do that whole dance. And so having this key value storage is pretty nice to have in in that in your server.
Alex:Absolutely. And, yeah, that that's powered by Unstorage, as you said, once again, another package from the Anjs collective and organization. And this key value storage, it there are a few things to to denote on that. Like, you can use it by just using your file system or an in memory KAV store, or you can use one of the tons of adapters, and that applies the same idea applies to Nitro. So on storage basically says you can integrate with almost any kind of k value story that you want.
Alex:You can even say, hey. I write my own driver for it because my certain interesting old legacy thing is not supported. And you can even use it to use any kind of HTTP server as KBI stores saying, okay. I can define a get request. I can define a post request and so on and so on.
Alex:But, of course, you can use, I don't know, clouds like kvStore, for example, Vercel's kvStore, Netlify, most of the things out there like Azure's kvStore and so on and so on, which means that once again, you are not really vendor locked. You can choose whatever you want. And the beauty is that you say with Nitro, you have the same thing with deployment. Like, you can deploy on any kind of platform. If there's no adapter, it's not that difficult to write one.
Alex:It's called presets in Mhmm. In Nitro. And that means you can even say, okay, let me deploy on, I don't know, let's say, Azure, but I want to use the Cloudflarek WeStore for whatever reason. You can do that without changing logic, just by reconfiguring. That's that's the best part.
Alex:You don't have to change your code. Most of the things are 0 config, so Nitro will just detect, oh, you want to deploy to Azure because this process is starting an Azure environment. Or you set the preset to Azure and that's it. You don't have to set up anything else.
Michael:Yeah. So one of the the benefits is is that that abstraction of all of that that stuff behind the scenes there. One one way that I've used this is for handling a lot flow, where you you need to store, like, basically, like this temporary key between between requests. And it's not something that like, you could put it in a database, and I think lots of implementations do it that way. But since this is like a short lived, it's gonna gonna live in your your system for like a minute or 2 minutes while this, you know, whole OAuth flow completes, then it's really just like a temporary value.
Michael:And so, for my own projects, I've done this where just put it into this key value storage and, have it in memory. And because I'm only running a single instance and I'm not, like, you know, all distributed and all this stuff, I don't have to worry about that complexity, and it's just a nice, easy, simple solution. Don't have to hit the database if I don't want to. And so all that, that flexibility is is really nice there.
Alex:Absolutely. And as you said, it's, it's great that you have the choice of of doing these things as it fits your needs while not increasing complexity. But you also mentioned database, and I think that's also one good thing to highlight that you can even now use DB0. That's once again yet another package that was released a little bit ago, to opt in to use a database layer, let's say, in Nitro, an SQL based database layer to be fair. And it's integrating with Drizzle as an ORM, or you can also just write plain SQL there to do some things.
Alex:So even if you want to connect to, like, an SQLite database or, I don't know, Postgres or whatever, you can do now very easily.
Michael:One of the other experimental features that has caught my eye recently is this tasks API. So this is something I actually implemented my own whole, like, task runner system a year ago for for some things that I was doing. And it's nice to have some of this stuff just baked right in. And so I haven't had a chance to to play around with this this API, but that is it it looks really nice.
Alex:Absolutely. And it's it's just the tip of the iceberg right now. Right? Like, it's great that you can define the tasks, and, like, further, you will be able to use them for Nuxt dev tools, for example. So there's someone, I think, also got a POC recently of, like, okay.
Alex:Let's add just a tab to dev tools there. But once again, these are, like, Nuxt independent, so you can even use them when you just have your own Nitro project if you don't want to use Express or similar. And, like, there are there are way more things to imagine. Like, okay, how would you can you, like, schedule them in the future? How to make sure you can maybe even have a CLI to execute them?
Alex:And I I think that's a really, really good point because very often, you have, like, some kind of scripts, be it migration scripts or whatever, that you want to run-in the context of Nuxt and Nitro, not with not, like, starting to parse all n variables again and maybe using utils again that you'd have to copy over or Right. To refactor. Ideally, you would have these scripts similar to other, like, bigger back end framework or full stack framework by just saying, okay, here's my script. I will just run it. And this is what Nitro is trying to accomplish with that.
Alex:As mentioned, it's still in in development. You can use it already, but more features are yet to come.
Michael:And these scheduled tasks or jobs as some other frameworks might call them, it's it's really like a core feature of any backend framework. Like you need to so often run a nightly job to process some analytics or clean up a database or, you know, whatever else it might be. And like, you don't want to necessarily rely on some other external service to hit your API end points or, you know, hook up a Zapier integration or something. Not again. No.
Michael:Yeah. Like at some point you want to just have control over this yourself and to kick these jobs off within your own system. And so, yeah, I, I think this is great because the more, the more things that we can do with just Nitro, I think the better because
Alex:It's all integrated.
Michael:It's all integrated and you don't have to, like, find some other ex extra solution and, like, roll your own task runner like like I had to do, which isn't, like, too complicated, but, you know, it it is work.
Alex:It's still overhead. It's still friction. Yeah. I I get that. And, also, then there there there might be another important point.
Alex:Like, all the things, like, that Nitro and and Anstor is on doing right there, as we mentioned before, they're, like, agnostic, more or less, ideally runtime agnostic. So it doesn't matter if you deploy to Edge or if you have a Node. Js server on your, like, on your VPS running. They should all behave similar, ideally the same. And that's another challenge of, like, let's say you have an application, and one time you wanna change the vendor because, I don't know, all Cloudflare workers are way way cheaper.
Alex:And then, okay, I have a task runner. Now I have to rewrite them to make it work with workers. And, well, Nitro is basically taking off that burden from you by just saying, hey. We have something that works in, let's say, most of the systems. Some experimental features, of course, don't work everywhere yet.
Alex:There are also issues to track where it works and where not. Or for some scenarios, like WebSockets, well, if if you only have a short living function, you can't have a a long running connection, so that will be difficult. But other than that, the idea is to to unify, the whole system with with one API back to, like, let's say, how Jake very did it with the browsers, but now just with runtimes.
Michael:Yeah. I think this is a great vision for this, and I hope we get more adoption on this. Like you mentioned WebSockets, that's an experimental feature. There's also all of these things that you might expect or some a lot lot of things that you might expect from a back end framework, like handling a cache. There are like asset management stuff.
Michael:There are, there are plugins. So one thing to keep in mind if you're developing with Nuxt is that there are Nitro plugins that, that specifically plug into the Nitro framework, but then there's also Nuxt plugins that are that take advantage of Nuxt specific functionality. So that can be a source of confusion as well, because when we're when we're in the Nuxt world, there's plugins and then there's also plugins. And it can be confusing to to keep those 2 separate.
Alex:Same for middleware. Right? Yeah. Elastic also has Nuxt, middleware, Nitro, middleware. And maybe that's a good point to circle back to the whole part, what is Nuxt and what is Nitro?
Alex:Because we said, okay, everything in the server folder, you can set up plugins there, you can set a middleware there. That's all Nitro that will all run before the Nuxt instance is even a thing. So if if you think of a request coming to the server, Nitro has the first. And if it hits, like, an API endpoint, then there will be some data. Or if there's a middleware, then that will be the first thing.
Alex:And then at some point, the Nuxt. Js instance might boot up if you use Nuxt with Nitro, right, or if you use Nuxt in general. And then it will server render your Vue application or your Nuxt application on the server for you and then returning the HTML. That's more or less where Nitro and Nuxt work like hand in hand together, by saying, okay. Nice.
Alex:Nitro is basically used. There's a specific handler written. So, like, basically a specific function written that Nuxt then server renders the instance and returns the data. So there is really the main point where Nitro and Nuxt run together. And after that, once again, the client, everything is pure Vue and Nuxt again.
Alex:And then we have the key when, let's say, in the client, you request an API endpoint, of course. Then in the browser, it's still running Nuxtun Vue. But the server endpoint that's hit is once again, Nitro again.
Michael:And to to maybe, elaborate on this point and to to make it another time because it's it is hard. Tricky. It's tricky for me too because I often forget where where he's end. And even trying to find the docs, which like, do I go to Nuxt to figure this out? Or do I go to the on JS, like Nitro thing to figure this out?
Michael:The dollar sign fetch function that you might use in in Nitro or in in Nuxt is also part of this. And this, like, isometric fetching where, in, in Mastering Next, I talk about how, oh, if you call a fetch of another API endpoint from within your API endpoint, it actually just calls the function directly. That's not really Nuxt. It's like the it's the Nitro side of things. So Exactly.
Alex:And that that's also a really good one. Like, I I've I've seen it multiple times when people ask, oh, why does my proxy doesn't work on the server side of things? Yeah, because of exactly the feature. Like, if you call another API endpoint inside, let's say, your server render next application, there you want to call another Nitro API, This will be emulated. Exactly.
Alex:There there's no actual HTTP call happening because of speed. You know, it's the same instance. So why doing the whole call again? Basically, what happens is just that the Nitro function that, is dedicated to that endpoint and all the middleware that might come before is executed. So you save the round trip.
Alex:But, yeah, that's also a bit, complicated when people saying, oh, why doesn't that happen as before? But luckily, also for Nitro, there is a good proxy solution with the route rules or with setting up your own proxy for an API endpoint.
Michael:It's one of those features where when I first heard about it, I thought, oh, well, I guess, like, it seems so obvious that you would do that and just just call it directly. Like, why not? But, I had never heard of a framework doing that before.
Alex:But, like, these are these are the good optimizations you you can optimization can only do when you have, like, static analyzable routes, for example, because otherwise you have the problem of, like, you don't really know which function to execute. So that's the tricky part that Nitro solves nicely when you just use file system based routing or add them manually. Yeah. And I think are there any other features you want to have a closer look at? I'm just wondering I mean, we talked about so many things.
Alex:We talked about the API routes. We talked about caching, kvstorage, the task API. We briefly mentioned WebSockets, the DB0 database layer. Maybe to to wrap it up, there is there's one thing we should talk about. It's like, okay.
Alex:We now know the capabilities. We know Nitro as a server framework, but how does it compare to something like Express or to Hono, which is also very trending right now? How how do these look like? I think that would be good to somehow figure out where Nitro lies, let's say.
Michael:Yeah. So I've used Express before quite a bit. And I guess I would describe the difference between Nitro and Express as that. Nitro does all the things that Express can do, but it adds a whole layer of extra functionality on top of it that like, it handles your HTTP requests. Yeah.
Michael:But it also handles all of these other things that we have we've mentioned. Like, Express, out of the box, doesn't do, you know, key value storage or have a cache or all these things. So that's that's at least my off the off the top of my head, that's how I would describe the difference there.
Alex:I think that's a very fair one, and, I I'm more than sure most developers will be able to relate to that because, I mean, we all used Express at some point, I would say. I think also one one difference one more difference is the model because what Express mainly works with, like, request and response. And in you always have defined event handler. So it's about events, more or less, which also helps to abstract away the the the code that's not necessarily related to Node because in, let's say, a a work environment, you don't have a request and response. You have an event.
Alex:It's all based on the the fetch loop. So that's also something to get used to. And, also, it's a bit more about composing, more about the composables. Not the view composables is also a bit of tricky thing to keep in mind. So it's really about, okay, you define functions.
Alex:You can, for example, wrap your handler definitions to make sure like, oh, I have now defined authenticated tender. And there, it makes sure it always fetches the user and so on, so on. So it's really more about composing, and it's a bit different from the typical, structure other frameworks provide. But it will help a lot with not only performance, but also the mental model as soon as it clicks.
Michael:Yeah. That's that's a good point. I hadn't thought about that specifically, but it does make it easier because you just have this one thing instead of having to deal with these 2 things, essentially. Like, even just that is is a simplification.
Alex:Like, Nitro is based on h three, which is just a numonym for HTTP, which is, let's say, the the connect of Express. So it's like the low level HTTP framework just dealing with, like, requests and responses, or if you're not in node environment and with the fetch loop, let's say. And based on that, like, as you said, Nitro adds so much developer experience and features on top that it's really a full blown framework in that sense. Of course, there might be a few things like, oh, yeah. We don't have, like, a queuing system built into Nitro right now.
Alex:So it'll be like, okay. What is what is missing? We have lots of experimental things that are that will become stable at some point, that we can use with Nitro right now. And here, it's very important to mention experimental does not mean broken or doesn't work. Experimental can also mean the API might change in the future or not all platforms are supported.
Alex:So we want to work on that, without, making a new beta version, and let everybody suffer to update. But all in all, it's really important to note that Nitro is a a full blown framework you can surely use for any kind of a project as long as you need a Node. Js back end slash server.
Michael:Yeah. I don't think I have anything else to add on that.
Alex:Perfect. Yeah. I think that we covered it. Right? If if there are any questions, as usual, please, let us know.
Alex:Write us either in in the comments on social media. We're happy to to to deep, dive into them and answer them if you're like, oh, okay. But what's with this one feature? How about that Nitro? Or what exactly?
Alex:Let us know. We're happy to answer.
Michael:And we will see you all next week.
Alex:That's right. See you then. Bye, folks.