Creating a new Vue-based meta-framework from scratch with live coding.
Building for the Edge - Crafting a Next-Gen Framework
AI Generated Video Summary
NUXT is a framework for building web apps that has undergone significant changes with the introduction of Nitro, a new server. The Talk covers topics such as building a framework with Nitro, rendering a view app, configuring Nitro and Vite, and integrating Nuxt with an existing Vue 2 project. The collaboration between Nuxt and Chrome has resulted in performance improvements, and the future of Nuxt and Nitro looks promising with new ideas and extensions being developed.
1. Introduction to NUXT and Nitro
I am a member of the NUXT Core Team and have worked on projects like Magic Regex and Fontane. I helped build Nuxt, a framework for building web apps. We had an opportunity to rethink Nuxt and made significant changes. I want to show off Nitro, our new server, and demonstrate building Nuxt from scratch on top of it.
♪♪ Can move on. So I am a member of the NUXT Core Team, along with a number of other folk here. You've already heard from Lucy. Sebastien's going to speak in a moment, Alex as well. I'm also involved in a number of other projects like Magic Regex, Fontane, which makes your layout shift disappear if you have custom web fonts. Elk, which is a client for Mastodon, and I have a website as well. So feel free to check out any of those that may interest you.
This is my milieu. If you ever message me on Twitter or Discord or whatever, I'm probably sitting at this desk. One of my three cats is probably stopping me from working. I don't know if you've ever experienced that you have changed your priorities for the day based on what your pet is doing, because I 100% have. Like, there are times when I just cannot code because I actually have a cat here. So, the only thing I can do is read through GitHub issues or something like that, but sorry, I'm losing track.
So I helped build Nuxt, which is a framework for building web apps, and it's built on top of Vue, of course. Can I have a show of hands, who here has used Nuxt? Okay. Well, that will skip the next ten slides. So, recently, we had a – well, a couple of years ago. We had a significant opportunity to rethink what Nuxt was about, what we would do with it. I mean, the core philosophy, the idea that you would be able to get started with best practice built in and customize as you went, that was still there, but a lot of things were changing.
So, the move from Vue 2 to Vue 3, there was a breaking change in PostCSS, huge breaking changes in Webpack, at the same time, just as we were about to be all ready to go with Webpack, Evan, for goodness' sake, releases Vite. What was that about? But I'm a big fan, but lots of opportunities to rethink. And alongside those, we had philosophical changes, like moving from a sort of singleton approach where you sort of have everything defined centrally and available to you, to a composable approach where you can actually pull in features that you want and need and actually only those get included in the bundle, an idea that you can actually share logic between components, lots of stuff that really made us think about what we wanted Nuxt to do. And I'm not going to talk about a lot of that, actually. I'm going to focus on the next piece, which we did, which was actually, we think, the server and how it was that we could write a server that would be designed for the serverless world, for a world of edge computing, for a world where you don't necessarily have a Docker container just always on or a server that's just constantly ready to return responses, but maybe you might need to fire something up. We moved, by the way, in Nuxt 2 from 300 milliseconds called Start to five in Nuxt 3, and we moved from 52 meg of bundle size to three in server node modules in Nuxt 2 to Nuxt 3. So there are huge changes we made, but in particular what I want to talk about today is I want to show off Nitro, which is the name we've given to our new server. We've released it so anyone can build on it, and I want to show you what it would look like to build Nuxt from scratch in a few minutes. I want to really very much try and do this, and I apologize as possible I might go into my cue. I'm going to build Nuxt from scratch on top of Nitro, powered by lots and lots of tools, which I'll show you as we go. So here we go.
2. Building a Framework with Nitro
Let's dive in and build a framework powered by Nitro. We install Nitro and H3, a server framework like Express. We create a web server that returns a JSON response. We provide type safety on fetches across the app and make it performant. In NUX, the fetch call works isomorphically.
Let's dive in and build a framework powered by Nitro. So the first thing to do, this is an empty repository, basically, nothing much there. I'm going to install Nitro and H3, which is the server framework, a little bit like Express that we built on top of that, and start it.
Okay, so off the top of our head we have a web server that's running. Let's go to local host 3000, nothing there. Let's create a root, foo. Nitro and Nuxt, we have very much the idea that we want to be as minimal as possible and as intuitive as possible. So we can do something like this. And actually, if we hit that endpoint, I'll hit it actually just in this terminal here, which seems to be tiny. If I hit local host, what was that, foo, I get back a JSON response. I've just returned an object. We also as much as possible try and auto-import things, and we do that in a pattern that we started with Nuxt. We provide our own TS config to let your editor know, your IDE know what's available both in terms of, well, in terms of everything that we make available, whether that's type aliases, buffer paths, or making your editor know about what is auto-importable and what isn't. We can also do really cool things like this. Say I, let's see, duplicate this, as another, another handler. I can actually get type safety on fetches across my app, so it knows the routes that exist, it knows the return types for that data, and so I could do something like this and actually get full type safety, and it's quite fun. And what you'll also notice, might not, is that this dollar sign fetch thing, when used in a server context, actually doesn't hit the network layer, it just makes a function call. So it's as much as possible, we're trying to make it as performant as we can. In NUX, as it happens, when you run that fetch call, it will make a request to the server, so it works isomorphically.
3. Rendering a View App
We've set up a server that hot reloads as we make changes. Let's handle non-server routes and render a view app. We'll install Vue and a plugin, create a view app, and import and render it to a string. Finally, we'll return the rendered HTML.
Okay, so we've got a server up and running, that's just sort of hot reloading in the background as we make changes. I have deployed websites that are purely server-focused and using just Nitro and it works nicely, but let's do something view-related.
So let's add a handler that's going to handle all non-server routes. So we have maybe some server routes like bar info, but maybe we also want to sort of render a view app, some HTML. And so we might do something like this, we're going to render some HTML. And if we hit that, some other page, you'll see HTML comes back. But that would be really time consuming if I just typed everything out. Let's do this with view. So let's install view. And a V plug-in for it. And let's create a view app.
Okay. So this will just say... I'll actually import something to make it a little bit more beautiful. And just say, hi, Vue.js London. Okay. And so really what we want to be able to do is import that and render it to string and return it. So we'll do that. So we'll get create app from view. We need to be able to render it to a string. So we'll do render to string. And we also need to import the app itself. And basically, oops. What we want to be able to do is create the app. We want to be able to render it to string. Oh yes, compile it. When it hits, when it's working well, right, it's really good. Okay, and then we want to return that. So we basically want to return it here. And then we've got a bit of HTML going on.
4. Configuring Nitro and Rendering a Whole Page
It's not gonna work because Nitrode won't understand View, so we need to add some configuration. We're gonna use a V-plugin. We have a template now, and we want to render more than just the view app. So we're going to use a feature of Nitro called the storage layer. We're gonna pull in this index.html file from here, use storage, and we're going to get root index.html. And that we can just return, template replace. And that should render me a whole page.
It's not gonna work because Nitrode won't understand View, so we need to add some configuration. And we can do that like this. Oh, TypeScript can help us here. We want rollup-config, and we're gonna pass a plugin. And I'm cheating, this is not really what you should probably do, but we're gonna use a V-plugin. Just pass it in like that. Let's try that. Yay, it's working. We've got some HTML coming back. How about that?
Welcome. Whoo! Thank you. Thank you. Thank you. Thank you. Thank you. You're all like, hey, come on, Daniel. We do this all the time.
Okay, so we probably need a template to put that in. So we'll say, hey London. And we'll grab that text here, just a basic thing. Put that in as our... There we go. So we have a template now, and really we want to render more than just the view app is going to render back, because all it's gonna render is the little, the components. We want a whole webpage.
So we're going to use a feature of Nitro called the storage layer. Now the Nitro storage layer is a KV store that is vendor agnostic, so it works with Redis, with memory, it works with VSL KV, it works with databases on the edge, like PlanetScale, CloudFlare, KV Storage, lots of other things, but it also works with the file system. So we're gonna pull in this index.html file from here, use storage, and we're going to get root index.html. And that we can just return, template replace. And what did I put in there? This. Okay, so that should render me a whole page.
5. Client-Side Rendering with Vite
It's still the same thing, but it's actually running a full HTML site. We want it to work on the client side too, so you can have interactivity. We need to add Vite and change the Nitro Config. We're going to use something called a DevHandler, which initializes Vite on the server. We're going to create a dev server, make it a custom app type, and use a utility from H3 to get our middlewares. We should be able to hit Vite Client.
Great. So it doesn't look any different, right. It's still the same thing, but it's actually running a full HTML site, which is great.
Now, what we would really like to do is have this not just be server rendered. We want it to work on the client side too, so you can have interactivity, so things can actually work well for you there too.
So let's do that. We're gonna need to add Vite. There we go. So let's... We're gonna need to change the Nitro Config a little bit here. We're gonna use something called a DevHandler, and that is, we're going to... We're going to basically need to initialize Vite to run on the server as well. So we're gonna give it a path, which will be __vite. So we know it's meant for Vite and not anything else. And we're going to give it a handler. We're going to use something called a lazy event handler, which means that the first time it's hit, it will initialize, but it won't initialize before that. There are a lot of really useful helpers like this added by Nitro throughout your app. So if you're using Vue, Nuxt, you can do the same.
And... You were telling me I've been talking for 15 minutes. Unbelievable, unbelievable. Okay, so we're gonna create a dev server here. We'll create it, we'll make it a custom app type. We need to import this. We'll make it a custom app type. And it will need to have middleware mode, middleware mode, and I think we'll need to pass a base as well. Great. And we'll use another utility here from H3 to get our middlewares. Okay, seems about right. Let's see, is that going to work? We should be able to hit Vite Client.
6. Configuring Nitro and Vite
We have Vite working, but what we don't have is any kind of hot reload or anything, it's not really connected. So let's move this into a different place called App, the server endpoint. We need a Client 1 2 to handle the client side. We'll use create SSR App to hydrate the view rendered on the server side. We'll create the App and mount it, and configure Nitro to capture everything with the handler in app client. We just need to tell VIT to process view as well.
Okay, and it's returning us something. So, thank you. So I think we should be able to add a script here. And Vite Client, and I think that should load us up.
So let's move this out into a different place. Let's move this into, we'll call it App, and call this the server endpoint. We need a Client 1 2, which will handle whatever's gonna happen on the client side. We're gonna use create SSR App, which will hydrate a view rendered on the server side. And we'll do the same thing. We'll create the App, but then we'll just mount it like this. What's going on there? Okay, seems good. And we'll have to add the same to our script, so now we have this. Okay. No. Not working. Let's try that again. Oh, why isn't it working? Because I moved into some other folder. Let's configure that.
So we'll need to tell Nitro that this exists. So we have this new handler called, we want it to capture everything. And the handler is going to be in app client. Our server on the Nitro side. It's saving as I type, so it dies. Oh, error. That's fine actually. We just need to tell VIT that it should process view as well.
7. Building Nuxt with Nitro
We've built Nuxt in a few minutes. The whole thing is powered by Nitro under the hood. Nitro can be used to build frameworks like AnalogJS and Nuxt. It provides all the necessary primitives.
Goodness sake. Okay, there we go. Let's see. Is it really working or does it just look like it is? We do. It seems. Amazing. So, there you go. We've built Nuxt in a few minutes. And tragically, I don't have time to show you any of the, well, I'll show you a few things, show you a few things. But I'm aware we probably do need to wrap up. And basically we have Vites set up, and the whole thing is powered by Nitro under the hood. If you're wanting to explore Nitro, it is possible to build a framework on top of it, so AnalogJS, which is a framework for Angular, is built on top of Nitro as well. Obviously Nuxt is too, and we would really welcome other frameworks to do the same kind of things. It provides all the primitives that you might need.
8. Authentication, Deployment, and Conclusion
NUXT has authentication, storage support, and the ability to deploy to various targets. You can define root rules per endpoint, specifying ISR or server-side rendering. Follow up and contact me for code examples. Check out nux.com for NUX and nitro.andreas.org for Nitro docs. Stay updated with NUXT on Twitter. A minor release of 3.5 is coming soon with exciting features. Thank you for the opportunity to be here in London. Building frameworks and exploring the building blocks is fun with NUXT.
So we have authentication, for example. You can use use session to create a persistent session stored across requests via cookies. I mentioned obviously storage, the KV support. It has support for deploying to any serverless or non-serverless target you might think of from Docker to Basel to Netlify with zero config, to Cloudflare, to Lagon, a new runtime. And you can define root rules individually per end point. So you can specify certain ones to be ISR, certain ones to be server-side rendered, and some not to be. Whatever you can think of, it's possible to do.
Please do follow up. Do contact me if you'd like. I'll push up this code and maybe a little bit more if I have time, to Daniel Rowe of Vue.js Live, so you can take a look at what it might look like to build a serverless framework on Nitro. And if you do want to try out NUX, which I would very much hope you do, and try out Nitro in a full production framework environment, check out nux.com. And the docs for Nitro are on nitro.andreas.org. And do follow the NUXT Twitter account, and we have a release, a minor release of 3.5 with some amazing features including typed root rules, which Eduardo demoed earlier today, coming out today or tomorrow. That should be pretty fun to see. But that's all for now, and please ask me questions in a moment.
It's been a real pleasure and a delight to be here in London. Thank you so much. Thank you. Thank you, Daniel. This was awesome. I don't know what's going on here today, but people are building frameworks live, building virtual doms live. I don't know. What is that a new trend or something? Feel free. Well, I think it's fun. Right? It's just to explore the building blocks. Because I think often you just don't see what goes on under the hood with something like NUXT. So NUXT, you get started. It clones itself into your working directory, and basically you just have a single app.vue file. So you can't really see. And it should just work.
9. NUXT for Non-SSR Apps and Learning Curve
NUXT is a good choice for building non-server-side rendered apps. The learning curve for Vue developers transitioning to NUXT is not steep, as most of the code can be reused. The Discord community is a great resource for any questions or support.
All of this. There's sort of types and everything. So I do think it's sometimes fun to peel back the curtain and see what's going on.
100% agree. Let's now dive into some questions. The first one is, should we use NUXT if we don't need server-side rendering? Yes, absolutely. By the way, I think the most important thing to say is use the right tool for the job. So I'm not a one tool kind of person. And hopefully if we are craftspeople, we're basically all of us carpenters. We're making things. So use the tool that will make you most productive, and make you best able to make the thing that you're making. But there's no reason NUXT isn't a really good choice for building a non-server-side rendered app. So things like auto-importable components, the type safety of NUXT, a lot of the utilities it provides. So from built-in components to arrow handling to how to configure and set up suspense and routing and all of that is something you just don't need to think about whether or not you're rendering on the server.
What would you say about learning curve for NUXT in case, I don't know, I'm a Vue developer. I know Vue pretty well, but I want to start using NUXT. If you take a Vue app that you've built and you want to convert it to a NUXT app, most of what you'll do is delete code. So it should just work. You should just be able to drag it across and your app.vue from your non-NUXT app becomes the app.vue in your NUXT app, and it should work. So the learning curve, everything you know is relevant, but you might not need to do as much as you had to do before. It should just do it for you. The best thing, of course, if you have questions is come to the Discord, which is discord.nuxtjs.org. I'm always there. You can ask me anything. And there's a huge community of people who are really helpful. So the learning curve shouldn't be too bad. But if it is, there's a lot of people there to help. Okay, perfect. So, we have the support. Let's dive deep into the next question.
10. Nuxt Free as a Full-Stack Framework
Nuxt Free can provide a fully featured back-end experience for authentication and working with external dependencies. It is not limited to being a supporting back-end for front-end applications. The Nuxt core team, with a background in Laravel, aims to provide all the necessary utilities for authentication modules and is open to building any missing features.
Is Nuxt Free capable of providing a fully featured back-end experience regarding authentication, working with external dependencies, and multi-threading, like for example Django. Or is it meant as a supporting back-end for mainly front-end applications? I think it's no accident that quite a lot of the Nuxt core team came from a Laravel background. So we've experienced something of a full-stack framework with that. I think we absolutely want Nuxt to have everything you need, and not that you have to use it as a full-stack framework. So our focus on KVStore, on database, on database layer, we are providing the base utilities like SessionSupport, that authentication modules need. There's a great authentication module at the moment by Sidebase that has adapters for hundreds of different... I would say yes, and if there's anything that's lacking, let us know, because we'd love to build it.
11. Using Webpack with Nuxt Free
I wouldn't say it's unwise to use Webpack with Nuxt free. The majority of devs using Nuxt are using VEET, which reflects the frontend ecosystem's love for VEET. If you're more productive on Webpack or have tooling that only works on Webpack, Nuxt provides a builder for it. VEET is fast and offers a great developer experience, but there are still many legacy Webpack projects. Evan's creation of VEET delayed NUXT 3, but it was worth it in the end.
Okay, I was asking Discord. Cool. The next question is, is it unwise to use Webpack with Nuxt free? I wouldn't say it's unwise. I use the tool that you like, it makes you most productive. I would say that the vast majority of devs using Nuxt are using VEET. It's something like 95% of all downloads of Nuxt are with the VEET Builder, and only about 5% are with the Webpack Builder. But I think that likely reflects the fact that the frontend ecosystem right now loves VEET. There's so much development happening there, lots of plugins being built for VEET. You get a lot of support there. I think most people starting a new project are thinking, I want to build on VEET. If you're more productive on Webpack, if you've got tooling that only works on Webpack, we do provide a builder so that you can use it. It's up to you. 100% agree about VEET. When I tried it out for the first time, I couldn't believe it. Yes. It's so fast, the developer experience. But probably, yeah, there's a lot of legacy Webpack projects. I know if you have a custom Webpack configuration, you cannot change anything. You can't let go of it. It's like the One Ring. This Webpack config is my own. We do forgive Evan for making VEET, even though it made NUXT 3 take longer, but it was worth it in the end.
12. VueX vs Pinia with NUXT
I prefer using Pinia as it is VueX's natural successor in the Vue 3 ecosystem. It has great DevTools and offers a straightforward state management solution. While Nuxt provides utilities like useState for simple state systems, Pinia is a reliable choice for more complex state management.
Okay. So we have the next one. Do you prefer VueX or Pinia with NUXT? I would use Pinia. I think Pinia is VueX's natural successor in the Vue 3 ecosystem, so I would use Pinia. It's got great DevTools. The guy who wrote it's not bad either, but yeah, it's good. I love that we don't have a lot of choices here, just one state management library. Not like React and a new library every month. You might not need Pinia, I should say. Nuxt does provide utilities like useState which enable moving state from server to client without re-initializing it, and allow sharing state between components. So if you have a really simple state system, you might not need to add any external dependencies, but when you do, make it Pinia. Cool.
13. Integrating Nuxt with an Existing Vue 2 Project
If you inherited a Vue 2 project, integrating Nuxt should be driven by business needs. Consider your team's capacity, the value the app will drive for your company, and how long you plan to maintain it. If the app is working fine and doesn't require changes, it may not be worth the investment of time. However, if you have the time and resources, it can be a beneficial decision.
The next one is, if you inherited a Vue 2 project, is it worth the effort to integrate Nuxt? So, this kind of question is always, it should be driven by business needs, so what is your capacity in terms of your team? What is the value the app is going to drive for you as a company? How long do you plan to maintain it? So for example, if you just have to keep an app ticking over and it doesn't need, it's working fine, you don't really see any problems with it, you might not benefit from spending the investment of your time to make changes to it. That said, if it's me and it's my, and I have the time to put into it, I would absolutely do it, but that doesn't mean that it's always the right decision. You really have to, but I mean, it's a business call for any tech adoption, for any migration, like rewriting anything, migrating anything, these are not decisions without cost. So.
14. Nuxt's Collaboration with Chrome
Nuxt is collaborating with Chrome to boost performance. They have shipped some things that have benefited Nuxt, such as improved source mapping support and solving common issues with async stack traces. The Chrome DevTools team, specifically the Aurora team, is working with Nuxt.js and other frameworks to ensure best practices are applied. The collaboration has led to the development of Fontaine, a solution to calculate metrics for fonts and improve web font loading.
Yep, yep, definitely. Okay. The next one is, I've seen from the Google I.O. conference that Nuxt is collaborating with Chrome to boost performance. Can you tell us what's going on? That makes it sound like a sort of secret cabal. Well, yes, we gather together in a dark room. Yeah, the Chrome team have been great. We've shipped some things that have benefited Nuxt, I think, that have also benefited more broadly as well. So doing some interesting things with source maps, for example. This is on the DX side, Chrome DevTools. You'll see better source mapping support with Nuxt and Vite and the latest Chrome. In terms of more accurate information, you'll see your code, you'll see better context. So there's a common issue with async stack traces that you lose previous context. We can actually solve that, and we've done some great stuff with them for that. They have a team, the Aurora team, within the Chrome DevTools team, and they're seeking to ensure that best practices around things like script loading and font loading are applied sort of to key frameworks. So they're working with us, they're working with Angular, they're working with Nuxt.js, and they are honestly a pleasure to work with. So it's always nice to have people who challenge you, come up with interesting and new and different ideas. Fontaine came out of a conversation there. I by the way, if you check out the readme, I'll give credit because it wasn't me who came up with the idea. It was Katie Hempenius, her work, basically to calculate metrics for fonts to enable less of that junk when your custom web font loads. And so there's lots of opportunities like that to bring in good ideas because, I guess, yeah, they've got some good people working there.
15. Future of Nuxt and Nitro
The future is bright for Nuxt and Nitro. There are a lot of good ideas coming, including three new RFCs related to Nuxt Script, Nuxt Font, and Nuxt Assets. The community has developed new VS Code extensions like Nuxta for Nuxt, which allows you to add modules and modify the Nuxt config from the VSCode sidebar. The future holds exciting possibilities.
Nice, glad you're doing all that. Especially for source maps because, yeah, the better the source maps are, the easier it is to debug everything, so, yeah. I'm sure you don't have any bugs. Never. Me neither. Cool.
The next one is a personal question. What are the VS Code extensions you use? I can share my VS Code config with anyone who wants, so let me know. But I probably have quite a few. But obviously you have to get Vola, you know. Yeah, yeah, I'm sure you have a lot of them, so I don't know. Maybe some are in that same GitHub. I would. In README. Yeah, some I would recommend. There's a new BetaTSErrors extension, that's pretty nice. Console Ninja is pretty fun. It lets you actually track, like, console logs from the browser in your IDE. That's really nice. There's a new extension called Nuxta for Nuxt. N-U-X-T-R. Just made by some people in the community, but using tools like Magicast and others under the hood. That actually lets you add modules, modify your Nuxt config, all from the sidebar of VSCode. Honestly, there are so many.
And the last question is, what does the future hold for Nuxt and Nitro? I would like to say the future is bright. So we are... So what does the future hold? So I think I don't want to steal too much thunder from Sebastian, who is going to paint a bit of a vision of some cool things that you can do. But we've got a good team, and there are a lot of good ideas that are coming. So, in the next week or so, you'll probably see three new RFCs also related to the Aurora team and what we've been doing with them for Nuxt Script, Nuxt Font, and one which I think you'll find really interesting, Nuxt Assets, which is pretty cool. Yeah. Lots coming. Awesome. Thanks a lot, Daniel. So, the future is bright.