Brendan: Welcome to PodRocket. I'm Brendan, I'm on the engineering team here at LogRocket and with me today is Daniel Roe, framework architect and Nuxt core team member. Daniel is joining us today to talk about Nuxt 3 and what's going on at the cutting edge of the Vue world. Daniel, thanks for coming on PodRocket. How are you doing? Daniel: Hi, Brendan. I'm doing really well. Thank you. It's a real pleasure to be here. Brendan: Great. Well, maybe you could start by just telling us a little bit about yourself. Who are you, what you're currently doing at Nuxt, and maybe a little bit about how you got there. Daniel: So who am I? Well, I'm based in England to start with, which means that you can pretty much guarantee it's at gray skies and bit of a not very warm at the moment. I'm in the Northeast of the country. I have three cats and a dog. I live on the banks of a river, which is as romantic as it sounds. And how I got started at Nuxt. So before doing what I'm doing at the moment I ran a small creative agency and then I headed up a tech team for an HR tech, SAS startup. And we used Nuxt, it was part of our stack. We absolutely loved it. And I was involved as a maintainer and contributor with Nuxt, even whilst I was doing those things. So when the opportunity came up to work more, to spend more of my time on Nuxt, I was really delighted to take it. Brendan: And so is that now sort of officially your day job, you're working full time on Nuxt and that ecosystem? Daniel: So I'm a consultant and I split up my time in a number of different ways, but I am sponsored to work on Nuxt. So a preponderance of my time is taken up maintaining the framework and improving it. So I've been spending a lot of time in the last few months, particularly I think probably actually about a year now, focusing on Nuxt 3 and doing what I can to make that a success. Brendan: So within that, how do you sort of spend your time? Is it mostly heads down coding? Is it interacting with the community? Is it planning? What are the types of things that make up your daily schedule? Daniel: I really love the breadth of what I do. And I don't know how much detail you want in terms of my daily schedule, because- Brendan: 9:00 AM. 9:30. Go step by step. Daniel: So I guess probably the thing that happens first, which is, I don't know how healthy this is, but the first thing, my day pretty much starts with me checking on Discord. Finding out what's going on, and obviously the GitHub notifications that pop in and the emails too, and Twitter DMs, things like that. And I think I get a feeling in those first few minutes of what kind of a day it's going to be. When I see, are there regressions from the PRs we merged last night? How are things going? And I will say, I do stay in touch pretty much throughout the day throughout with Discord, checking in on the community and what's going on. I read every single message that goes in. I'm not always able to respond and there are often people who do a much better job are responding than I am, but the value is huge because people report issues they're experiencing or ideas for improvement. Daniel: Sometimes they don't even have the confidence to put this forward as this is what Nuxt should do, but they have great ideas all the same. And I'm always happy to steal them or put a quick PR in to improve, I should say with credit, but put a quick PR and to improve things. So the starting point of the day is really sort of touching base with the community, which I love. That's amazing. But then pretty quickly, I switch over to my baby son, Ned, he's two and a half. And I look after him until about nine. And pretty much, there's not a lot of time between the checking of the Discord and Ned waking up. Daniel: So I'm then running after a toddler who has a boundless energy. So that's a really lovely part of my day, but it does mean if you try and get me or message me or do anything like that after I've up, I'm probably not responding until bang on at nine o'clock UK time. And then I guess for the rest of the day, it's a bit of a mix. So I might be doing anything from touching base with one of our ambassadors or helping someone debug an issue. Fixing bugs, triaging bugs that come up on the framework. I absolutely love when I get a chance to build a new feature. That is a real highlight for me. And seeing people use it, too. Sometimes we get people send in links to sites they've built with Nuxt and that is a real delight. I'm sorry, I could go on and on, but I feel I'm totally in the weeds here. Brendan: No, this is great. I think there's one of the sort of consistent themes we hear when we talk to people working on open source projects is how consistent a part of their workflow in their day the community is and how important that community is usually on Discord to the sort of evolution of the project overall. I'm curious if there's sort of an overall community strategy that you have on the Nuxt team to sort of build and maintain and grow this community. Is that something that just kind of happens organically with people joining the Discord and just wanting to participate? How has that community built over time? Daniel: Well, I can say for sure that we are learning and getting better at this. And that's a number of things. I think we're getting better at communicating. So our roadmap, talking about where we're going in terms of the project. That's something we've not always got right in the past and I think we're getting better at it. I'm also really pleased to see that the documentation is really getting better, too, thanks to some amazing contributors. I think improvements to the documentation have a bit of a multiplying effect because people who want to be helpful and contribute often go to the docs first as their port of call. And if they're able to find information and get information out the docs, they can then pass on to other people. Having said that, we don't have a sort of a written down community strategy or anything like that. It is very organic, so people help out. Daniel: I mean, my own philosophy, I hope it doesn't sound too pretentious, but I feel I've benefited so much from other people giving. And I think giving is really key to, at least my experience of open source. People have given things they've given their time, their code, their resources. And I feel like that's what I get a chance to do as well, I get a chance to give. And I see the same thing taking place in Discord and elsewhere, where people are giving their time to debug issues for people. They are diving into projects, they are sharing repositories and code. They're taking the time to create issues and provide reproduction and things like that. And I think there's a degree to which genuineness breeds genuineness. So when I see people helping out of the goodness of their heart on Discord, that affects the quality of the community. It's nice to be a part of that community. I think I see people responding positively to that. I mean, it's not always the case in every community and I think we're really fortunate at Nuxt to have a great community. Brendan: There's kind of almost this Goldie Locks size or stage that communities get to where they're not so big that they need sort of formal structure and management and lots of documents around participating in the community, but they're big enough and they're self organizing enough that they can sort of solve problems and have their own personality. And that's sort of a stage that I think a lot of people who we talk to and who work on open source projects really value where it just feels like kind of people are coming together organically around an idea, or around a piece of software and making it better as a group. Daniel: Absolutely. I'm really grateful that we do have a code of conduct, for example, and I'm grateful that I don't have to go to it more frequently in terms of, but ... it's probably a feature of our size, but also I think the kind of people who are participating. Brendan: Yeah, well, let's talk about Nuxt. We had Alex Lichter on the podcast a couple of months ago who talked some of the lower level details of Nuxt, some nuts and bolts with Noel. So I'm going to try to not cover all of the same territory here. We'll link to that episode in the show notes, give it a listen if you're interested. But just to set the stage, would you mind giving us a quick rundown of what Nuxt is, what the problem it solves is and why I should want it in my next Vue project? Daniel: Well, where do I start? So Nuxt ... it's a progressive framework for building web apps. So I love it because it's zero config. You get best practices built in. It's really easy to start, but it allows you to configure and make it your own in any way you want to, as you go on. So it's uses Vue as the underlying technology. So if you've used something like Vue or React or Svelt, Nuxt will probably feel quite similar, it has a component driven approach. A lot of things are done for you. So the pages directory becomes a mirror of the roots of your site. So index.vue becomes just forward slash and about.vue becomes your about page and so on. Nuxt does a lot of other things in terms of developer experience, particularly that's true with Nuxt 3. Daniel: I'm happy to give some overview on that. One of the things that sets Nuxt apart, though, is its modules ecosystem. And it ties into this customization thing I was talking about. It's possible to create your own add-on package that adds an integration with a service or implements something, or even completely changes Nuxt behavior. We have one ambassador, created this amazing module that ties at your smart lights around your house into the status of your Nuxt project. So as your project is compiling or recompiling, or starting up or closing down the lights change, color to match. I think that's cool, but you can do lots of other things too. Brendan: I don't know what that like level of developer experience is, but that's clearly on another level from what I normally expect from my toolchain. So obviously the big news in Nuxt is Nuxt 3 at the end of April, we finally got our first official release candidate. I saw on the website, you're targeting June for a stable release. You've done a ton of work over, I think almost a year on this project, essentially sort of rebuilt from the ground up. What are some of the headline features and the sort of most exciting parts of this release for you? Daniel: I think I'm most excited about two things. I'm most excited about the server integration that we have for Nuxt 3. And I'm also hugely excited about the developer experience improvements we have, particularly around TypeScript. Happy to dive into those, if that would be good for you. So the server, as you said, we rebuilt it up from the ground up. Nuxt 2 was a clearly a Node plus browser set up. So there was ... at runtime that is, and we had a feature where you could output purely static files, but if there was ever a backend, it would always be Node. Daniel: With Nuxt 3, we've rethought that a little. So we've started from the perspective of what's new and different about the world we're living in at the moment. So yes, it's really important to render HTML, but we might not be wanting to have a long lived server sitting on a VPs somewhere, rendering those pages. What would it look like if we supported rendering in other targets like CloudFlare workers, V8 isolates? What if we supported rendering at the edge in Lambda, in serverless functions, in service workers actually inside your browser, maybe other locations, too. And a lot of the requirements that drove the creation of the server engine came from answering those questions. So for example, we couldn't depend on anything that was Node specific, or we would limit ourselves to Node only. Daniel: And we wanted to create something that was universal, could be used anywhere with any target. So that changes things. We had to create an HTTP frame up from scratch. We had to create a robust mocking system so that we could have virtual request and response objects that you could interact with, that would work in a purely in a browser and not just on the server side. We had to come up with ... we had to come up with lots and lots of different things. And then apart from that sort of the rebuilding, rethinking the code and mocking dependencies that do depend specifically on Node, we also had to optimize for cold starts and think about what a server looks like. So we use, for example, we dynamically import the code that is needed to respond to a particular request, which means that the only thing that actually starts when you start a nitro server. Daniel: So a Nuxt server and production is the code that's actually required to listen on that port, if it's listening to a port and respond with a request. So it's just the orchestrator. Everything else is dynamically imported as needed. And obviously it then persists in memory, but it means that we were able to go, I was running the numbers just the other day on my laptop, a bare bones, nothing added Nuxt 2 project took something like 300 milliseconds to start. That's not production infrastructure, that's just my laptop. A nitrous server takes three. That's the level of difference. It's not only about speed, though, it's also about size. So a Lambda or other serverless target often has a size limit and Nuxt 2 project and Node modules in production mode. So not the development dependencies like Webpack, took something like 50 meg when sort of installed. Daniel: A Nuxt 3 project, we use a really innovative library from Vercel NFT, stands for a Node file trace in this particular instance. And it actually looks through your dependencies and just traces what's used and removes the rest. So things like README files or even code that isn't actually touched and it gets excised from the bundle. So we actually then ... we create our own Node modules folder as part of the output, part of the build. By default that's 700 kilobytes with a Nuxt 3 project. So again, huge, huge performance improvements. And it basically means that we're able to do things like support zero config deployment pretty much conceivably anywhere. We have something like five zero config deployment targets at the moment, and the others just require fairly minimal config. Additional presets can be written by anybody, and you can have your own. We can always merge them back into the nitro project. But I think that is really exciting for me. So there's sort of zero dependency, universal JavaScript deployment. I love it. It really floats a lot of boats for me. Brendan: Something that may have sort of gone on and said there is that when you're dealing with serverless targets, the size of the package that you're building also has a big impact on cold start times. Because that code just has to get downloaded to every work or every VM that under the hood is running one of these serverless environments. And so you both have to contend with the time the code takes to start up and initialize and load as well as also the time it takes to download the whole package. And obviously if your Node modules folder has gotten chunky over the course of your development, that becomes one of the biggest bottlenecks to how fast you can respond to cold starts. Daniel: Even if you're not using that code. Brendan: You also mentioned developer experience was a big thing you were excited about and we touched on the zero config deployments. What else is sort of cool or innovative from a developer experience perspective in Nuxt 3? Daniel: So I mean, I think a lot of it is what you don't have to do. So with Nuxt 3, we have the concept, a lot of things are done for you. So your plugins are all imported by default. All the components you stick in your components directory are available anywhere in your app. All of the functions you put in your composable directory are also available anywhere. And those aren't available in the concept of just globally registered. We detect when you use them and import them where required, which means your whole app continues to be bundle split and the code is actually only imported where it's needed. But we use TypeScript to give you a lot of information about what's going on and what's usable. So it's all very well if something is universally available, if your editor draws an ugly red line under it saying, what is this and why you not imported it from somewhere? Daniel: So we've worked quite closely. We take control in some ways. We provide a generated tsconfig.json file which we fully configure to match the actual setup of the user. So all the aliases are genuinely the aliases that are relevant for that project. So if you have a custom source directory, or you have a module that declares its own aliases, whatever, everything just matches. None of the configuration that you might have had to do before with Nuxt 2 to set up your TS can take and make sure it's sort of matched your actual web pack config in that particular instance means we can give you type hinting for everything everywhere. And that type hinting isn't just limited to globally available components or functions. And by the way, that is pretty cool when you're typing in your Vue template and you actually get type hinting for the props of the component that you have auto imported, that is amazing. But we can also give you type hinting for things like the server roots. Daniel: So if you've created an API endpoint using nitro, and you have the response that it returns, we can actually give you type hinting for that throughout your whole project. So if you perform a fetch request to that endpoint, the type of that fetch request is ... the return type is a promise of the actual type that endpoint returns, which is amazing. And it all works when you type check as well. So you actually get the thing where if you go and change your API endpoint, but don't change the code that calls it, you will get type errors. And that's a really, really nice end to end kind of type safety, which previously, I guess, to get that kind of thing, you would've had to run some kind of cogen. Daniel: Maybe you would've had to use a custom library. There are some great ones out there that produce validated functions and things like that, but it's really nice to get out of the box. And I' such a fan of minimalism. The new Nuxt 3 project starts with just an App.vue file and an Nuxt config file, maybe a TS config as well. And that's it. Everything else just works when you create it and you shouldn't really need to configure your Nuxt config either. It just should just work. I don't get tired of that. Kate: Hey, this is Emily, one of the producers for PodRocket. I'm so glad you're enjoying this episode. You probably hear this from lots of other podcasts, but we really do appreciate our listeners. Without you, there would be no podcast. And because of that, it would really help if you could follow us on Apple Podcasts so we can continue to bring you conversations with great devs like Evan You and Rich Harris. In return, we'll send you some awesome PodRocket stickers. So check out the show notes on this episode and follow the link to claim your stickers as a small thanks for following us on Apple Podcasts. All right, back to the show. Brendan: Obviously the Nuxt 3 versioning is tracking Vue 3. Were there any things that changed in the Vue core that enabled some of the major features that you're now supporting in Nuxt 3 or any particularly sort of impactful changes to Vue for you? Daniel: So I think one of the significant things that's driving innovation in this space, not just in the Nuxt space, but in the Vue space is, and actually not just the Vue space is Vite and actually not just Vite but roll up. Because obviously Vite is built on rollup. And the fact that you can write roll up plugins so simply makes a huge difference, I think. So having written both web pack and Vite plugins, I know which one is easier to write, and it's going to be a roll up or of Vite plugin. A lot of what you end up doing to transform the code or process is just it's powered by Redjacks. It's quite straightforward. You do also have potential downsides of that, but it does mean you can iterate quite quickly. You can release new features. Daniel: We've built something called unplugin as part of work on Nuxt 3, which is actually used much more widely than Nuxt 3. Which allows you to write a plugin that works in roll up Vite or web pack. So it's a sort of universal plugin architecture. But even apart from that, I would say that the move to use roll up as the base has really accelerated the sort of development of some of the features that we're talking about. Things like auto imports or others. I think another change in Vue itself that's maybe made a difference is ... so obviously the move to the composition API. And that concept means that we're talking about functions that you can call anywhere. Whereas previously, the only way to get that kind of reusability across your project would be to use something like a Vue mix in which one, didn't have type support, and two, would've been a lot more complicated to apply. Daniel: In Nuxt 2 we were configuring a lot of things with component options. Whereas now we're talking a lot more about methods, which itself then leads to another improvement. We can tree shake everything, because if you don't use a composable, then we can statically analyze that. So it's actually, it's not in the build now. We don't need that functionality. Whereas when everything is in an option and you're enabling something based on whether an object has a property, you can't really tree shake that out. So it was very difficult to optimize 2 two for that kind of performance. I want to be in complete control of my code. I want to know what's happening. I would turn flags individually off, even if it would only save small amounts of JavaScript. Daniel: There was a largely undocumented feature of Nuxt 2 that allowed you to do this, but you don't need to do that with Nuxt 3. It just works without you having to think about it, but it's driven by this composition API move. And then built on top of the composition API move is a move towards script setup. So composition API, these compostables all run in a setup function. And the script setup concept is, instead of a script block in your Vue, single file components, one have a setup block effectively where everything in that block is exposed to the template if it's needed to be. Vue then does a lot of compiler optimizations on that. So it's able to tell what things need to be exposed to the template and which don't. It's able to tell what things can be hoisted out of the actual render function and just sort of capped at the higher level sort of persisted across instances of the component. Daniel: And it's also able to do other interesting things like setting and restoring an asynchronous context. It only works in script setup, but you can basically set the Vue context, run your async function, restore your Vue context afterwards, and it's powered by a transformer function. And that kind of thing, in fact, we've written very similar concept of restoring a Nuxt context. We've done something very, very similar in Nuxt 3. So I think in all of those instances, you can see a direction of travel that's been established by Vue three or by Vite by the ecosystem. And I think Nuxt has taken that sort to take that further sort to go in line with that. Brendan: So as you're working on the sort of Nuxt core, are you in close communication or collaborating with Evan and the Vue core team? Or what's the relationship generally between the two projects? Daniel: So really positive. So yes, the relationship is quite close. The Teams chat, I think we are always grateful because we're quite interrelated in lots of ways. So we might face an issue in Nuxt which is resolved by a change in Vue router, or we might produce something in Nuxt that gets adopted into the core Vue as well. And that's a delight, that's really great when we're able to collaborate like that. Brendan: Yeah. I would imagine in some ways that you are kind of stress testing the API decisions and the design decisions of Vue in a way that not a lot of other projects are capable of. Daniel: Well, I don't know that I'm capable of, but we certainly are doing a lot of stress testing of features. So for example, suspense is currently a bit of an experimental feature in Vue itself. We've actually used suspense to build a lot of really interesting things on top of it, including this concept of the whole data fetching that powers Nuxt 3 is built on asynchronous setup functions, which only work in a suspense context. So we are both enjoying and benefiting from that and also uncovering any potential issues that they may be and doing our very best to raise issues upstream and resolve those. Brendan: Another thing that I think you've alluded to a couple times and definitely seems like a big focus of Nuxt 3 in general, is composability and the plugin ecosystem around the project. Can you talk a little bit more about that? Both from a design perspective of how you approached building Nuxt 2 to be this plugable and maybe what are some great examples you've seen of people contributing to the ecosystem? Daniel: There's been a move from Nuxt 2 to Nuxt 3. So in Nuxt 3, so again, plugability for Nuxt is often through modules. In Nuxt 2, there was something called a module container. It was an object, well, this context, which modules could access helper functions from. They could add templates, they could insert plugins or layouts. You do various things. In Nuxt 3 we still have a compatibility container that matches Nuxt 2, but we've exposed these helper utilities in a different way. So we're exposing them as an SDK. So you depend when you're writing a module, you depend on the version of the SDK that you want. And then that SDK, that copy of Nuxt kit is responsible for interacting with Nuxt itself. And instead of passing some kind of instance of Nuxt around, we've actually adopted the composition API for the Nuxt internals. Daniel: So we have the concept of a Nuxt instance, which is accessible by calling use Nuxt anywhere throughout your server side bear in mind, this is not Vue, this is purely Node code. And so we're able to write utility functions that can be used anywhere, that can be composed, that can be extracted from the actual Nuxt instance, which they're operating on. And that makes hopefully a really big difference in terms of developer experience for module authors and also compatibility going forward. We're doing our best to make things compatible with modules that were written for Nuxt 2, but really the compatibility that kit offers is modules that are written today that use it going forward to Nuxt 50 should still work because the way that those SDK functions are exposed should mean that they still. Don't hold me to that when Nuxt 50 comes out. Brendan: I'll be back for Nuxt 50. Another thing that I wanted to come back to was this sort of universal JS, I think it's the unjs project that a lot of these sort of components like nitro, I think, Nuxt kit sort of fall under that umbrella. Can you talk a little bit more about what that is and what the goals are, and maybe where that came from? Daniel: So it's always been the case that the Nuxt project has spun out libraries that are used elsewhere. And until we started working on Nuxt 3, they were in, for example, the Nuxt contrib organization on GitHub. We have a couple of others as well, the Nuxt community which is where often module authors collaborate. But we felt we wanted to move away from the Nuxt name space because the concept isn't that we are trying to grow Nuxt. I mean, obviously we're trying to grow. I think it's great, I'm delighted when anyone tries it out. But we're not oppositional in the sense that we want Nuxt to grow at the expense of others. And we're not trying to ... this is a positive thing that we're doing all of us in the open source community. Daniel: We want to make the web better. We want to make people's lives better. And our small part of that is, how can we release and expose the code that we're using in ways that are useful to other people in other projects? So unjs stands for universal JavaScript and that applies at a number of different levels. So it's universal in the sense that it runs anywhere. So we often have projects in there that are to do with abstracting away Node, that kind of distinction. We have a fetch client for example called, oh my fetch that works anywhere. And it's often about abstracting away that kind of distinction. Daniel: It's also about abstracting way deployment targets so you don't have to be locked into a particular ecosystem. Anything works anywhere. But it's also universal in a sense that it's not even about any one framework. So it's not just about Nuxt, it's about anyone who wants to use the code. And so I'd be really delighted for anyone to contribute or get involved in any of those projects. Helpers definitely wanted, and I would be really thrilled to hear of anyone using them as well in other projects, even if they're competing with Nuxt. Would be absolutely fine for me. Brendan: So I would imagine the next couple of months for you are going to be pretty focused on getting that stable release of Nuxt 3 out, but once you've sort of hit that milestone, what's next? What are you sort of looking forward to in the future for the Nuxt project beyond this next release? Daniel: So there are a lot of significant improvements that we have in mind. I think maybe some we've talked about before. And some of those improvements aren't likely going to be in the stable release or there might be partially there. So there are a lot of things that we have planned, including things like a IDE extension browser extension. Significant improvements to the CLI. Ideally, I would love it if people didn't really have to interact with their configuration. So it's there, but it's not this kind of dark art of figuring out what you need to do. and I think there's some things we can do to really, really improve that in terms of developer experience and that would primarily be mediated through the CLI and the dev tools. So I'm looking forward to those in the future. Brendan: Great. Well, I'm going to stay tuned. Daniel, thanks so much for being with us. Before we go, is there anything you would like to plug or point our listeners to? Daniel: I'm very conscious of the fact that we're sort of emerging into a slightly different world post pandemic, as things start feeling a little bit more normal. And I guess my own, a truth that I'm sort of wrestling with and coming to terms with myself is just how important it is to take time to be kind. To look after myself, other people. Nothing was ever easy. We're not going back to a place where no effort or care are required. I don't know, that's more me telling that to myself than anyone else, but those are words I'll be seeking to by that solution. Brendan: Plug for kindness may be the most wholesome way we've ever closed the show. Daniel, thanks so much for your time. It's a pleasure to talk to you. We'll see you online. Daniel: Pleasure. Talk to you later. Kate: Thanks for listening to PodRocket. You can find us at PodRocket Pod on Twitter. And don't forget to subscribe, rate and review on Apple Podcasts. Thanks.