Kent C. Dodds
And finally, Codecov.io is code coverage done right. Red uce technical debt by visualizing test performance and faster code review. Codecov is highly integrated with GitHub and provides browser extensions. Learn more Codecov.io. And I should mention that Codecov integrates well with GitHub, but it also integrates with other Git-hosting services, I think like GitLab and a couple others, so check them out. They're awesome.
Cool. So we don't have any panelists on the show yet, maybe some will show up a little bit later and we'll say hi to them, but we do have some awesome guests. And so first we have Taylor Otwell.
KENT: And Evan You.
KENT: Awesome, and let's go ahead and give each of you a chance to introduce yourselves and what you all have to do with Vue. So Taylor, why don't we go with you first?
KENT: That's super awesome. Thank you for coming on the show. This is a podcast about the web in general, the whole web platform, so we're happy to have a PHP guy on to chat with us. And thank you for your work on Laravel. I'm sure that there are tons of people who have greatly benefited from that framework, so thanks. Cool, now Evan, why don't we have you go next?
EVAN: Yeah, I'm busy with the baby for now, while figuring out what to do next. Yup.
KENT: Awesome. And we were just joined by Dan. Hi, Dan.
DAN: Hey there!
Cool, so let's get into Vue. Why don't we just start out with what is Vue?
EVAN: Well, that's an interesting question 'cause I think the definition of Vue has somewhat evolved along the way. So it started out as a really humble experiment -- I think like most open source projects. So at that time I was working at Creative Lab and we used Angular to build a few things, but at that time I thought Angular just brought in too much stuff that I didn't actually need. And I was really interested in how data binding worked, so I set out to build a small prototype and it turned into Vue over the time. So for probably the first one and a half years, I basically positioned Vue.js as a really thin view layer that just gives you the most basic data binding and a way to compose these components together.
But lately, as I started to use Vue to build more complex stuff and also, you know, greatly inspired by the things happening in the React community, actually, I'm starting to expand what's available to Vue, not just to Vue.js core, but surrounding ecosystem with tools that sort of constitutes a more framework-like thing, which gives you the ability to sort of, you know, it gives you the router, it gives you the state management patterns and stuff and build tools to allow you to build full-scale, single page applications. So, today I would call Vue a progressive framework, which, by that I mean Vue.js core is still this really simple, lightweight view layer, which you can just strap onto a page and just use. But if you want to, you can go deeper into the Vue ecosystem and pick the parts that you need, which they just work together to give you this more framework-like experience.
KENT: Cool. So Taylor, what does Vue, like what are your use cases for Vue?
And if we want to go into more specifics, compared to Angular, Vue definitely takes a lot of inspiration from Angular 1, where the data binding syntax is obviously very Angular-ish. But there's also this important design decision to make it more approachable, so I basically threw away anything in Angular one that I felt wasn't a necessity for you to get something working on the page. So that was sort of the initial design process. The focus on simplicity and approachability is one of the most important thing that I kept in mind when I was working on Vue. And compared to React, I guess it's a really interesting comparison because both are... the Vue.js core and React core both are this like thin view layer that just allows you to, just gives you declarated views and a way to compose them, right? That's basically all they do.
The interesting thing is how this implementation difference led to different sort of development paradigms where Vue is still more or less centered around being able to manage your state as mutable object, where React is going full on with functional programming and mutability, which I think is interesting because there are a lot of great ideas that I see in React right now, but I'm also, it's a pity that a lot of, I see a lot of beginners sort of stumble on these concepts when they get started. They're like, "Oh, I'm overwhelmed by all these things I don't know yet." And sometimes I just see that the two projects attack different target services, where cater to different needs, where, when some people, they don't necessarily want to become a functional programmer to be able to fully master React, but they still want to be able to build something for the web as fast as possible, yes. So that's something I've been talking about where I think the web is huge and versatile, so different people have different use cases, and it's important to pick the tool that boosts your productivity most. And you have to just try it for yourself to see which one fits your mental model better.
KENT: Cool, yeah lots of good information in there. There's actually a question here on Twitter that is applicable to our current subject. So I'll go ahead and ask it now. It's from Reinier Kaper and his tweet to #jsAirQuestion was, "Are there any features you have planned for Vue that will set it apart from other frameworks like React or Angular?" So anything that currently doesn't exist in Vue that you're planning on to make Vue even better?
In terms of pure features, so currently the Vue team really consists of just a loose group of people, but we're talking about server-side rendering to see if it would be feasible. The implementation details would be rather different. So we're exploring a lot of different ways to tackle the problem. And on the native front, so there is a company called Alibaba in China, I don't know if people know about it, but they're pretty big. They're the Amazon of China. And they're working on a native implementation called, well, I probably shouldn't talk about its name in too much details at the moment, but they're working on the uh...
KENT: Cool, yeah. I wanted to actually ask you about that one file for everything thing that you were talking about. Can you expand on that a little bit?
So, all of these are really focused on just making these features as accessible as possible. You don't have to do extra research to bringing 10 other dependencies into your project just to use them. And you can also use preprocessors in the single file. So say you can use Jade for your templates, you can use SASS for your styles. You can even use LESS and SASS in the same file and you can mix scoped and unscoped CSS in the same file. Yeah, basically it's really flexible. It's somewhat inspired by web components because web components are great. You have the single HTML file and you have everything in there. The problem I have with that is you need a polyfill and we don't have a standardized build pipeline to crunch all the web components into a single thing. Before we have HTTP/2 inversely available before we have HTML imports actually standardized and implemented in every browser, web components still seem a bit premature for me to rely on, I guess. So I feel like implementing a similar mechanism on top of webpack seems to be a really good route because see, webpack is powerful, webpack has this ecosystem with all the loaders you can use. It has all these great features, but if we can have web-component-like syntax powered by webpack, so that's how Vue's single components came about.
KENT: Well, we've actually got a relevant question that's good for Taylor on Twitter. So, from Henrique Bremenkanp, yeah, sorry, I cannot pronounce your name. (laughs) But the question is, "What is the best way to get that hot reloading in all Vue goodness on a Laravel project?" So I don't know whether you use the hot reloading stuff, but I did want to ask you what your favorite features of Vue were, so.
TAYLOR: I haven't used the hot reloading myself. The best way to use sort of that single file stuff in a Laravel project is to use, we actually have a project called Laravel Elixir, not to be confused with the Elixir programming language, which we kind of have a little confusion there sometimes--
KENT: Unfortunate namespacing there. (laughs)
TAYLOR: (laughs) Yeah, anyway, with Laravel Elixir, it's basically a layer on top of Gulp that, you know, Gulp files can get a little complicated at times, and they sort of get copy and pasted around over every project you do it seems like, but with Laravel Elixir, it sort of has really simple syntax where you can just say like mix dot sass, dot less, dot browserify, or whatever. But it actually has a vueify extension that Jeffrey Way, who wrote Elixir, has provided that basically just lets you drop that right in to your Laravel project and start using the single file Vue stuff right out of the box, basically with just one or two lines of code in your Gulp file. So definitely check that out. That's documented on laravel.com under the Elixir documentation. But I haven't gotten too much into the hot reloading yet, but that would definitely be where to start. I think it's all sort of baked into Elixir to set that all up, so it should be pretty easy to get going.
EVAN: So I just, yeah. I just want to add about the hot reloading in Laravel thing. I remember seeing a post on the Laracasts forum of someone getting to work. The thing is browserify doesn't come with hot reload out of the box, so you need a plugin called browserify-hmr. You need to add that plugin to your browserify compilation and you also need to use watchify, which is this file watching, auto rerunning browserify version. But I haven't really implemented, like tried a hot reloading with Laravel myself. But I definitely remember seeing someone doing it on the Laracasts forum, so it should provide some guidelines, yeah.
KENT: Sweet. So we do have another couple of questions on Twitter, so I'll just jump into some of those. These are good questions. Besides, oh, and this is from Egoist? Yup. "Besides SSR, so it's server-side rendering, what does React do that Vue cannot do well?" So what are some of the things that you're hoping to improve on?
KENT: Cool. So I'm actually just, we're getting a lot of questions on Twitter, so unless there's something else that you wanna make sure that we talk about, I think that I'll probably just keep going through these. Actually, you know, I just had a good question before I go through these. I want to ask a little bit about the technical details of Vue and how, yeah, like when I hand Vue a component, what does Vue do with that component? So if you can just kind of walk us through the technical details. And also how the, as the user interacts with that component, what happens in those scenarios?
EVAN: So, okay. Every Vue application starts with a route instance, right? Similar to how you do like React to Render, ReactDOM dot render a route component, and that route component contains all the other components on the page. So, when the route component is mounted, Vue walks through its template. Vue actually, similar to Angular 1, Vue uses DOM-based templating, so it parses the temp, so you can actually just write your templating in real HTML and let Vue compile it or you can just use a string and Vue will convert it to a real DOM template. So walks that DOM structure and look for directives and custom components. So the compilation pipeline is really similar to what Angular does. It just walks the template, find temp directives and components. Well, in Vue, components are actually directives too, but they have special syntax. So, it collects all these directives, sort them being priority, and attach them to the DOM nodes. So that's the compile, compile, link, process. So it's really similar to Angular in that sense, but it's really low-level details where the user never actually had to touch upon.
And when Vue encounters a custom component, it invokes the constructor of that component to create an instance of it. So when you create a Vue component instance, you call vue.extend and give it an object, which contains all the options about that component. So Vue will essentially create a constructor that has these options predefined within it, so that when you create an instance of that component, it already knows, oh, this is my template, this is my initial state. It's just like a React component I guess, except it uses a template. Then it, when it encounters a child component, an instance uses the template, constructs the actual DOM for that component, and replaces the mounting point, which is the custom element on the page with that constructed DOM piece. So, sort of gradually filling out these custom components with real DOM pieces and eventually filling up the page. So I think, so the difference between this approach and React is we are keeping references to these actual DOM nodes and we have data bindings or these directives instances attached to those DOM nodes. So, each directive is responsible for watching some reactive property for changes. So whenever the expression associated with a directive changes, it is responsible for updating that DOM nodes that it's currently managing. That's basically what happens.
I guess the other interesting part is the reactivity part where because you can pass initial state to these components and when the component bootstraps, it will walk these data objects and convert them into ES5 getters and setters. And inside those getters and setters, we have a mechanism for dependency tracking, which, it's sort of like pops up because each property essentially becomes a dependency and each directive has an associated watcher. In Angular, a watcher is purely for dirty checking, so every time something changes in scope, Angular just runs every single watcher, re-evaluate all the expressions to compare if the new results and the old results is different. But in Vue, each watcher actually keeps tracks its dependencies every time it evaluates. So say, when you evaluate an expression, like A plus B, it knows that it depends on the A dependency and the B dependency. So it would only re-evaluate if either A or B changed. So say you have 10,000 watchers on the page and all of them depend on different dependencies, then when you change one dependency, only one of them would re-evaluate and all the other ones just do nothing. So this sort of gives you a better runtime performance and you don't really need to worry about optimizing it because it just works that way by default. So this similar type of dependency tracking is also found in Knockouts and Meteor's original view layer called Blaze. Took a few page from there as well. Yeah, I think I covered probably most of it. I'm sure it's still pretty confusing, but let me know if I can explain it better. (laughs)
KENT: No, no, I think that makes sense. Let me try and compare this a little bit to React for those of our viewers and listeners who are familiar with React. So React's solution is any time you want to make a change to a property, a relevant property used in say, setState, and React will say, "Okay, let me re-render everything and just see what the difference is," whereas yours is a little bit more specific, where you say, "okay, this property depends on, like I'm gonna track the dependencies of this property and any time, because I have a hook into the getters and setters of, specifically the setters, any time somebody sets this property, then I can find all of that property's dependents and update those things." And it cascades from there, and then you have something to update the view. So what's the piece that, like I guess you have a hook into when all these things are set, and so you can say, "oh, like this property in the template is dependent on this property in the model and so I need to update that." So do you go through and update every piece of the DOM that's dependent on these different data properties?
EVAN: Yeah. We should probably go through a very simple example of say you have a text binding. You have a text node and it's bound to a property on your model, which is like message, so when the Vue component starts, it converts the dot message accessor so that whenever you access dot message, it will say, "hey, I'm depending on the message property, I'm depending on this depth object, which is inside the closure for that accessor." And then you have this directive, which is just a text directive on this text node that says, "I am bound to the message property and whenever it changes I should set the text content of this text node."
So it will run for the first time and when it runs, because in order to set the message it has to access the message, so in that process it knows, "hey, I have this dependency in my dependency list." And basically the dependency also keeps track of a list of subscribers, which are these directives. So next time that we set it, the def will notify all its subscribers, saying, "hey, I have changed." So the subscriber directive says, "Okay, you have changed. I have to re-evaluate my expression, and if the result is different, I will just update the DOM." So that process, so I don't want to compare to say the Virtual DOM approach, which I actually prefer to convert the DOM, sort of like dirty checking on the Vue structure layer.
So there are ways you can optimize the Virtual DOM diff then by implementing should component update to make it more efficient, but the default runtime cost is relatively large because you have to render the whole subcomponent tree and then compare the whole DOM structure to make sure everything has changed is updated, but even if it only change a single node, you still have to do the whole comparison. Whereas in a dependency-tracking scenario, you pay a higher upfront cost because converting these objects to have getters and setters, and also because all these extra closures and dependency objects that we're creating, there's a bit more upfront work to do. It also has a bit more upfront memory cost. But the benefit is no matter how big your application is, the amount of computation and DOM updates triggered is always proportional to the amount of data that has actually changed. So if you change a single property, then only the things affected by that property will change.
DAN: I'd like to make the notes here. So, one of the notes I want to make is that there's library called MobX. I think it's been renamed lately. It was Mobservable before, but everybody was confused, like how does that relate to observables? So he just renamed it to MobX, which kind of implements, I think a similar model, like React model of updates dependent on other updates and computed properties, so it can work with React. React is not fully opinionated about how you kind of do that, which can be a bit of a pain for new adopters, but you can adopt similar React dependent in React if you really want to.
And I guess another one note I wanted to make is that you don't really, like this picture of always re-rendering from the top is, in React, is a little bit simplified. So this is what we say to people when we teach them React, just to kind of give the picture simple. But it's important that if you have a tree of components and you call setState somewhere here in the tree, only the pieces below this tree are actually going to be diffed. And any time should component, the data returns false, so this part of the tree's going to bail out. So if you set state somewhere in the middle, it doesn't actually re-render everything from the top. So this is not what happens.
And this is what we use, like in Redux, we have React-Redux bindings, which is a library that connects React to Redux in an opinionated way, and it uses React's setState under the hood. But what happens is that if you dispatch an action, the changes, some parts of your state tree, they have different references to different objects. So what happens is that we don't actually re-render from the top in Redux either because that would not be performant in real apps. So what we do is when it wants some components to care about the global state in Redux, you subscribe these components with connect component enhancer and specify which parts of the tree they care about. So what happens is that if you dispatch an action, and this action changes some parts of the state tree, only the components that are connected are actually going to receive that new state. And it's going to be, we're going to compare the reference right away. So those connected components that don't care about this update are going to skip it.
So again, it's not as granular as the approach that you described. And in fact, if the viewers are interested, there is a pull request in React repo, I think this pull request is closed. (laughs) I closed a bunch of old pull requests a little while ago, but it's still easy to find. I think it's called expose React data tracker as an add-on. So, this is an implementation of pretty much similar approach where you track everything that render accesses, so you know what to subscribe to. And I'm not sure we actually reached any consensus on this, so this didn't get merged, but we still have discussions about it. There are plans to have more granular updates for really like weak use cases, where you can't really go the whole React way. So this is still being considered and it's really cool that you're kind of showing how it can be done in a performant way in an alternative framework, so props to you for doing that.
KENT: Cool, yeah. Thanks for that, Dan. That was good. Sorry Evan, did you have something you wanted to add?
EVAN: No, I'm good.
KENT: Cool, so there's a question here that I think Taylor could probably speak to a little bit. It is, "How should I be architecting my apps with Vue based on feature, all profile functions in one component?" And so, yeah, like actual use cases. What's a good way to structure and architect an app?
TAYLOR: (laughs) This actually might be better for Evan, but it sort of depends, I guess, how you're using Vue because I actually don't use it with the router or as a single page app, so I structure my app a little bit differently, where each page has its own Vue component and it's pretty simple. But I'll kind of defer to Evan on that because I think he'll be able to give a better in-depth answer on Vue's structure.
EVAN: Yeah, like Taylor said, I think it really depends on your use case. Similar to, if you're using Laravel and depending on what your app does, you would have to consider the trade-offs in whether you should make it a full single-page application. Does it have complex UI states that you really want to do all the rendering client-side, or do you just want to keep it mostly backend rendered and just add touches of interactivity on top of those pages? So, it really depends on the actual user experience need of your app. So for a lot of apps that doesn't really have complex interactivity, then you would probably be more productive going with the way that you already know how to do. You just render things from the server and then where you actually need interactivity, you just drop Vue on the page and have a Vue instance on each page.
On the other hand, if you are actually going to build a really complex single page application, then you should probably look into the whole suite of doing client-side routing with the vue-router and it maps your URLs into a nested component tree. And also, if the app gets real big, you want to manage your client-side state with vuex, which is the Flux implementation for Vue. Basically what it does is similar to all the Flux implementation. It extracts the state, essentializes management of your state into stores, so that your components no longer hold the state in different places and try to communicate each other, trying to synchronize them. Instead, all the state is kept external to the components. They just get updates from the store and when they want to change something, they just have to make a notification to the store, say, "hey, I want to change this piece of state," so that it forms this unidirectional data flow where it ensures all your changes to your global state is explicit and manageable.
So as you can see, there are trade-offs in making your... introducing these concepts into your app because it may be an overkill for simple scenarios. So I think it's important to sort of understand what each of these pieces do and then find the balance point for a use case and pick the right tool for your thing, I guess. I guess the good news is because you can pick as much as you want in terms of Vue because it's just designed to work that way.
KENT: Cool. We are coming close down to our time now and so, we'll definitely cover some more of these Twitter questions, I think, but I just wanted to make sure that I give Evan and Taylor and Dan, everybody, I guess, an opportunity to bring up anything else that you wanted to before we wrap the show up.
EVAN: I'm good, I guess.
EVAN: Interestingly, I, so far I haven't really been working on Vue full time. But it does takes up a lot of time, including a lot of personal time. I think I definitely sacrifice a lot of time, say with my wife, for this project because I have to work on it during, after work, late at night, and all that. Sometimes I feel it's really... I was able to do it because I didn't feel like it was work, right? Because I really liked it, I enjoyed working on it. I'm passionate about the idea. I feel great that my project is helping a lot of people build awesome things in the world. So that's the motivation, right? Like you know you're building something that makes people happier. You know, you're doing something meaningful.
But of course you should definitely try to do it in a sustainable way, right? We don't want open source maintainers to burn out. I think, for me, personally, I've been taking an interesting pattern. Like I didn't intentionally do it, but I discovered the pattern is that I would take a break from Vue like for maybe, after a three month commit peak, I guess, like a commit spike, I would then say, "Okay, I think it's in a good shape right now. I'm just gonna leave it there, take a break from it for maybe one or two months." If you look at my GitHub commits record, like every year, in January, there is like maybe 10 to 15 days, there's no commit at all. Which I think it's great because it does multiple great things to you because first you get to recharge, personally.
Second, when you walk away from your project for a while, you get a whole new fresh perspective on it. You would come up with a lot of new ideas about, hey, why didn't I think about this before? Because when you were deep into the project, you're just like hands down fixing bugs, implementing features, you would sometimes get lost and you're too committed to a single direction. But when you take a step back, it gives you more perspective. It gives you more ideas on, "Hey, maybe I could have done it this way." I think it's important to take breaks from your project even if you're working on it full time. And other than that, I feel like I'm actually pretty bad at managing my day-to-day productivity. I usually work in a very irregular pattern and I think I want to improve that, but yeah, that's what I have to share.
KENT: Cool, yeah. Those are some good pro tips. I think actually, I'd like to hear some managing life and open source pro tips from both Dan and Taylor, because you both are also working on significant open source projects. So Taylor, what do you have to say?
TAYLOR: So before I started working full time, I had a lot of late nights doing open source. I would usually wait until like 9:30 when my wife went to bed, and then I would work like 9:30 to midnight or 9:30 to 1:00 sometimes. And I would do that like three or four days a week at least. But ever since I went full time, I sort of do have a regular schedule. And I've been full time for a year and three months now, where I work eight to five, but the first hour or so, I answer emails and stuff, and then probably the next hour, I strictly do GitHub pull requests and issues and stuff like that. And then for the remaining six hours is whatever I have planned for the day, which lately is this Laravel Spark project that I've been working on. But it could be anything else. You know, maintaining Laravel Forge or Enjoy or something like that.
But I sort of have that same routine every day and then I use Trello and Wunderlist quite a bit as well. In Trello, I actually keep a column for each day of the week, like Monday, Tuesday Wednesday, Thursday, blah, blah, blah. And then whatever I want to do that day during the week. And I find that works a little bit better than like me keeping one big to-do list that's sort of a 300-item backlog because I'm sort of forced to allocate the task onto different days and spread it out a little bit. And then for just really simple to-do lists, I'll use Wunderlist. But that's sort of like the nuts and bolts of the practical ways I use to get things done.
The hardest part of maintaining an open source project for me has just been learning when to say no, you know, to feature requests. That's always a really hard thing for me, when I get a PR and someone's obviously put quite a bit of time into the pull request and it's just not a right fit for the project at the time for whatever reason, even if it's a decent idea. That's been one of the challenging aspects of open source for me.
KENT: Yeah, totally. That happened to me today and it was kind of sad. Totally makes sense. And I respect the author or the maintainer of the project for scoping down their project, but yeah, it can be kind of sad for a contributor to get rejected. So, cool. Dan, did you have any pro tips about managing life and open source?
DAN: I don't really think I'm the right person to ask it 'cause I've been sucking at it pretty badly lately, especially, like I switched from working remotely small projects and doing open source like in free time to having a full time job doing open source, but a specific project. So I'm working on React right now. And this means I don't really, like I'm still settling down, still figuring out how to allocate the time. Right now, I just do it randomly, and I'm procrastinating on a lot of things like email and direct messages and all this kind of stuff that I used to handle just fine. Right now, like I haven't visited Redux repo for like two weeks because I'm just afraid of all these pile of notifications.
But like, a good part about it is that I think I did fairly well scoping down my project. Like in case of Redux, there is a blog post called Finish Your Stuff, which was one of the inspirations behind Redux. Like at the very beginning, one of my goals was to create a project that has very specific scope and that is possible to actually get done and like move on. And I think in case of Redux, it does what I wanted it to do and right now it's like issues and pull requests are about documentation, examples, like loop infrastructure, but nothing that really is too important. We don't get changes to the source much, so I'm pretty happy just letting it live its own life and coming back once in a while I guess.
KENT: Well, I think that actually is a good pro tip. Just figure out what it means for a project to be done and then get to that point and then, you know, then it's done. And if somebody wants it to do something cooler, then they can build something else. I think that's okay and that's what open source is all about. Cool, Evan, I think that you wanted to address Reinier's question a little bit more directly.
EVAN: Yeah, sorry I misunderstood the question because it was asking the plans to extend the Vue team. And in fact, I'm already doing that. I had an open call for contributors a while ago and I got like 50 applications. Unfortunately, I can't take all of them. So I have to, you know. We currently have maybe seven to eight people that... so I added them all into the Vue.js organization. They're helping out on triaging issues, and answering questions, and working on feature requests, working on bug fixes. So it's great. Previously, I was really doing this all alone and now when I have a bug, next day I see a pull request trying to fix it. I'm like, "Wow, open source is working, so this is great."
KENT: Cool. Yeah, good stuff. All right, I think we're gonna move ourselves into tips and picks and wrap up the show. So there are remaining questions in Twitter, and so if you all could just really briefly, at the end of the show, go to the hashtag #jsAirQuestion and look at those, I'm sure that people would be really appreciative. So great, I'll go ahead and let's have Dan go first, and then I'll go, and then we'll have our guests go. So go ahead, Dan.
DAN: I don't really have any tips this time. I'm sorry. (laughs)
TAYLOR: Okay, so my tip is don't be the smartest person in the room. And that kind of just comes from, throughout my programming career, I feel like I've made the most progress where I was around people that were a lot smarter than me at programming. So whether it's at your day job or at a meet up or something like that, I think it's really beneficial if you can sort of meet someone and befriend someone that knows a lot more about a given topic than you do. And of course, you're gonna know more about something than they know about some other topic that you can share too, but I just think it's really helpful to grow really quickly in your programming career that way. And it seems to help me grow a lot faster than just trying to learn it all on my own.
And then my pick was this album I listened to this morning called Star Wars Headspace on Spotify, which is kind of this electronic album that had Star Wars quotes mixed in, which was pretty cool. (laughs)
KENT: That sounds amazing. (laughs) Cool, Evan, we'll have you go next.
EVAN: Okay, sure. So my tips, I kind of mentioned it before, is take a break from your project from time to time just to recharge and get fresh perspectives on your project. And are we doing picks as well? Okay.
EVAN: So, my picks. There's a book, CSS Secrets by Lea Verou. I'm not sure if I pronounced her name right, but the book is awesome. It's probably the best CSS book out there, so get it. And then I've been obsessed with a game, Dark Souls. I don't actually have Dark Souls 3, it's just out. I don't think it's even released in the US yet, but I don't have much time to play it, but it just is an awesome game.
KENT: We'll see you all next week!