The Laravel Podcast

Fortify, Breeze, Jetstream, & Spark, with Taylor Otwell

Episode Summary

In the first episode of season 5, Taylor Otwell joins us to talk about the packages Fortify, Breeze, Jetstream, and Spark. We discuss the differences between each one and which package is a great place to start.

Episode Notes

Episode Transcription

Matt Stauffer:
Hey, welcome back to The Laravel Podcast, season five. And this season, every single episode is going to be about a single package-ish. Most of them will be a single package, but especially when I'm talking with Taylor, who we have here today. We're going to be joining together some of the packages in the Laravel world that also just makes sense to connect to each other. So our first one, first of all, of course, we got to get Taylor because we're going to be talking about some of Laravel's kind of like third-party packages, even though they're really first-party. And so we're going to jump together Fortify and Breeze and Jetstream and Spark, really just kind of all the author-related stuff. So to get started, of course, everybody knows who you are anyway, but I just got to put you through this one more time. Taylor, can you tell everybody who you are and say hi real quick?

Taylor Otwell:
Hey, I'm Taylor Otwell. I created the Laravel framework.

Matt Stauffer:
There we go. So we have a pretty rigid schedule and agenda for this one, and we're just going to kind of try it for this first episode and see how it flows. So let's just get some started with it. So obviously a lot of these questions are defined around the concept of it being a single package, but this is not just one package. But you and I agreed that like Fortify, Breeze, Jetstream and Spark do make sense to kind of be joined together. So could be one or the other, or could be kind of all of them, but can you start by just giving the elevator pitch for all the packages and then maybe each individually and kind of what are the main jobs that they do?

Taylor Otwell:
Yeah. So the elevator pitch for basically all of the packages is they're all essentially starter kits for getting started quickly, building a new Laravel application. They're usually installed when you first start a fresh Laravel application. They're rarely installed on an existing application. And they just kind of get you a head start in terms of mainly authentication functionality, logging people in, registering users, resetting passwords, forgotten passwords, and even I think email verification. And they're all basically existing to serve that purpose. Spark sort of augments that basic story with also adding subscription billing plans and downloading invoices and updating credit card details and stuff like that. But they're all essentially starter kits.

Matt Stauffer:
Yeah. So before I actually ask you to dive into each of them individually, I want to talk really quickly about the background. If somebody has used Laravel where make:auth was a thing, you do the Laravel, space, make, colon, auth on the command line, it would just automatically scaffold all this kind of stuff, can you tell us real quick which piece of this new system kind of replaces that? And kind of what was your goal in extracting it out to a separate package/packages?

Taylor Otwell:
Yeah, so Laravel Breeze is basically the spiritual successor to the old make:auth command, which is still available on GitHub and is still currently working with the latest Laravel 8, but definitely Laravel Breeze is the successor to that. And we can kind of get into the history of that because Laravel Breeze actually came out, I think, a few months after Laravel Jetstream. Yeah. And Jetstream and Spark are sort of tied together also, once we get into the history of kind of why these packages were built and how they were built and things like that.

Matt Stauffer:
Yeah. Okay. And then the other question was Spark... And you know what? If we're going to get the histories, I was going to say because Spark used to be something different than what it is.

Taylor Otwell:
Yeah, yeah. I think we should probably start with Spark and Jetstream and how those things came about. And I think that will lead into Breeze.

Matt Stauffer:
Yeah, you know what? I think this is the perfect time for it. So let's kind of just walk through, because I think in talking through what each of them is, we can also just kind of come to it through where did they come from? So would you just kind of tell us the history, starting from maybe when you decided to get rid of make:auth and extract things to where we are today?

Taylor Otwell:
Right. So let me actually start with Spark. So I put out Spark in 2016. And as you said, it looked pretty different than how it looks today. And originally it actually looked a lot more like Jetstream looks today, where it scaffolded out your applications, login, registration, team management, in addition to all the billing stuff that people think of when they think of Spark probably. And the idea was for it to be sort of a SAS starter kit, because I had built Forge. I had built Envoyer by this point, and I really wanted to kind of extract out a lot of that boiler plate getting started code around subscriptions and users and teams and make a package for that so that if I ever wanted to build another sort of software as a service product like Forge or Envoyer, I would have a pretty good head start on getting that done. Okay, so I put that out in, I think, 2016. And then when we started thinking about the next major version of Spark, one thing that we really wanted to do was have it be frontend agnostic. So one of the problems with the original version of Spark is that you pretty much needed to be using Bootstrap. You pretty much needed to be using a certain way of setting up your Vue JS frontend. And if you weren't doing that, you were sort of going to have a bad time.

Taylor Otwell:
And we really wanted to get away from that. And at the same time, we also really wanted to focus Spark only on billing and get rid of all of the authentication, the registration, the team management, and to pull that out into a separate package that we would just release for free. We also wanted to move away from Bootstrap to Tailwind, things like that. And so kind of how we tackled this is we extracted all of the user registration, the login, the team management, into a free package, which we called Laravel Jetstream. And we converted that to Tailwind and sort of modernized the whole thing, gave it a fresh design and stuff like that. And then the billing part we extracted into a new version of Laravel Spark that only was this sort of isolated billing panel that was a whole separate part of the application that had its own front end assets that did not interfere with your application at all, so that your application could actually be built in React. And our Spark billing portal is actually built using Inertia.js Vue, but you would never know that because it just fits so seamlessly into your app, because it has its own assets already compiled that ships with the package.

Taylor Otwell:
And so that was sort of how Jetstream and spark got split from what used to be this sort of monolithic Spark package. And now Fortify kind of comes into this because when I was writing Jetstream and we needed to write all of this authentication logic around login and registration, some of the feedback we had from the previous version of that scaffolding was that some people are just authenticating single-page applications or SPAs, and they don't really need redirects or Vues or anything like that in their authentication scaffolding. So I thought, okay, I have a great idea. I'll extract all the authentication scaffolding out into sort of a headless package called Laravel Fortify that doesn't have any frontend implementation at all. And then Jetstream will just consume that package to sort of handle all of that authentication logic. And so that's how we kind of ended up with three initial packages, which were Jetstream, Fortify, and Spark. And some of the response to that is what led to Breeze, which we can talk about next, I guess.

Matt Stauffer:
Yeah. So I imagine with the laugh that you just had, the response was I think a little bit of just this is overwhelming, right? It went from-

Taylor Otwell:
Yeah.

Matt Stauffer:
Make:auth to figuring out how the pieces work together. And I think your response was, well, it's so that people can do so many more things, right? But you also said-

Taylor Otwell:
Right.

Matt Stauffer:
I do want it to be simpler from the beginning. So can you talk through kind of when you hear that response, what was the process of deciding to make Breeze kind of like for you?

Taylor Otwell:
So the response was definitely mixed, as you said. I think the response to Spark was actually really good-

Matt Stauffer:
Yes, fantastic.

Taylor Otwell:
Because it had a lot of improvements and fixed a lot of things, but the response to Jetstream and how you customize Jetstream, it was more complicated in the sense that it had more features, like team management, two-factor authentication. The response to that was all pretty mixed. And so some people love it. It actually has more downloads than Breeze, even today.

Matt Stauffer:
Yeah, I believe that.

Taylor Otwell:
So my thinking was, okay, at first I was pretty resistant to tackling another starter kit on top of what I had just released, but I was getting so much sort of mixed feedback about it, I decided just to bite the bullet and go ahead and do it and created the this thing called Laravel Breeze, Breeze being sort of a small Jetstream, so to speak-

Matt Stauffer:
That's awesome.

Taylor Otwell:
Is where that name comes from. And it very much worked like the old make:auth command, where there wasn't a lot of hidden or magic functionality behind it. It basically just copied controllers into your app, copied Vues directly into your resources Vues director, and everything was just there in the open for you to edit after that. So there's basically no code hidden in Breeze. It's basically just a command line package that exports files into your applications.

Matt Stauffer:
Right, like takes stubs and then puts them in your application, and then it's done with its job.

Taylor Otwell:
Yeah, exactly. Yeah, it puts stubs out there. And it doesn't have the same amount of features. It only has login registration, password reset, and email verification. It doesn't have any team management. It doesn't have any two-factor authentication or user profile screen built in. You're kind of responsible for building it from there, which is the same situation we had with make:auth. And I think that really sort of resolved a lot of people's complaints and fears that getting started with the scaffolding feels too complicated now.

Matt Stauffer:
Yeah. So I'd love to talk real quick about helping people make a decision. Let's say that somebody says, "Which of these should I use in any given moment?" So I think it's clear that if you only need what the old make:auth has, which you just basically said is like user login, sign up, password reset, maybe email verification... I can't remember... Breeze is going to get you there. So especially if you're an old school Laravel programmer and you remember make:auth, Breeze is going to get you there. So Fortify, is anybody ever going to use Fortify on its own, other than for SPAs?

Taylor Otwell:
I really am trying to steer people away from that these days. And that ties in with something that was just released this week, actually, which is the whole purpose of Fortify, as I said earlier, was to sort of be able to authenticate both traditional backend web applications, like those built with Jetstream, and also single-page applications like you might build with a Vue SPA or Next.js or Nuxt.js or whatever other frontend framework you're using. But the problem is it's a little complicated to understand and use. It's well documented, but there's just a lot of pieces there to really grasp. And so what we did this week is actually release a new stack for Breeze. We call them stacks. So Breeze has a blade stack where it can scaffold out a purely blade implementation of the starter kit, or it has a Vue stack, which uses Vue and Inertia, a react stack, which uses React and Inertia. And now we have an API stack, which when you do Breeze install and you pass API to the command, it actually scaffolds out the backend controllers, but no frontend. And everything's set up so that you can authenticate an SPA. And we released a reference implementation of such an SPA in Next.js open source on GitHub.

Taylor Otwell:
So after that, after this past Tuesday, actually, no, I would try to steer people away from trying to use Fortify on its own, and just let it be something that Jetstream uses internally that you don't really care about or think about that much, because we sort of have this new, easier to grasp scaffold. And I think that's going to be a bit easier for people to understand. And so we've tried to emphasize this actually in the doc. So kind of getting back to your question of what should people use today if they're just getting started? When you go out to the Laravel docs and you click on starter kits, Laravel Breeze is the first thing you see. And then when you get down to Jetstream, there's sort of a smaller section about it. And we actually have in bold, "For those brand new to Laravel, we recommend learning the ropes with Laravel Breeze-

Matt Stauffer:
That's cool.

Taylor Otwell:
-before graduating to Laravel Jetstream. So definitely Breeze. If you're just getting into Laravel, Breeze is the way to go 100%, because nothing's going to be hidden from you, and you're going to be able to kind of browse through all the source code and understand how it works.

Matt Stauffer:
That's good. So Fortify we would just say at this point probably nobody needs to use Fortify on its own, unless you're really digging deep into something and you got to write your own custom thing. Breeze is where everybody gets started, and then Jetstream is where you go if you want to add... So you mentioned it's got some actual admin panels. It's got some team management. What's the criteria you would say for people to switch to Jetstream?

Taylor Otwell:
Team management is a pain to write and quite a bit of boiler plate code. So if you have that, if you need that, Jetstream is definitely worth looking at. The other stuff is a little bit easier to write on your own. I mean, two-factor authentication is definitely a little bit annoying to write. But team management is definitely the big bear there that, I think, if you have an app and you know you're going to need teams from the start, and if you even think you might need teams from the start, I would recommend looking at it, because adding teams to an app after you've already built the app-

Matt Stauffer:
Yes, it's miserable.

Taylor Otwell:
And it doesn't have teams is an even worse problem to have.

Matt Stauffer:
Yeah. It's funny because we often tell our clients things like, "We can just make changes later, but there's some things..." And we tell them this, "Well, there are some things that are a lot harder to do later," and that is high on the list because it's like a complete underlying architecture refactor of what your primary object is for authentication.

Taylor Otwell:
Yeah, it really is. And I saw a tweet from Ben Orenstein who runs Tuple, where he said that, "If you ever think your app needs more of one thing, you should just do that from the beginning." Like in a Forge context, we would never have let you hook up one server provider. Go ahead and let you hook up multiple server providers or have multiple teams. It's so hard to add those kind of things after the fact.

Matt Stauffer:
Yeah, because your initial implementation just makes all these assumptions about there being one of them. Yeah, totally. So Spark, is Spark just hey, if you need recurring subscription billing, add Spark basically?

Taylor Otwell:
At this point, yes. And that's where we wanted to get it. We wanted it to be a more focused thing that only focused on subscription billing. And by extracting it into its own sort of isolated billing panel, which is very much inspired by Stripe's own billing portal... I'm not sure if you've seen that, where customers can kind of manage their own subscriptions. Our design even looks similar to that in ways. It's so that we can update Spark and you don't have to update anything in your own application-

Matt Stauffer:
I love that.

Taylor Otwell:
Which was always a serious pain in previous versions of Spark.

Matt Stauffer:
Yeah. The previous Spark, for anybody who's never used it before, would basically assume that you had a Vue and Bootstrap-based admin panel that had your left nav set up a certain way, your structure, like you mentioned set up a certain way. And so if you didn't have it set up that way, it was either jarring to switch because it was not really designed in such a way where you'd think oh, this is a natural switch. And then like you said, it was a difficult maintenance burden. But it's cool because I expected the solution would be to make it more work to integrate it with your existing app, like it'd have to be more integrated with your existing app. And then Stripe came up with this idea of hey look, you can just go to a separate part of your site that does feel pretty distinct. And so when you built that way with Spark, it just makes so much sense, because the users can totally just comprehend that you're sliding into a different part of your application right here. It looks a little different, but it's very clearly... Because people are used to credit card modals and stuff like that that look a little different anyway. So I love the way you set that up.

Taylor Otwell:
Yeah. And we let you customize, of course, the basic color and primary color and font and stuff like that. So you can get it pretty close, but yeah, I really like it actually. We use it for every product we have now.

Matt Stauffer:
Nice.

Taylor Otwell:
We actually did not ever use the old Spark for anything, which always bothered me as well because we have this product that we honestly don't even use ourselves and can't use, to be honest, because-

Matt Stauffer:
Yeah. You can't add it to your existing app after the fact. Yeah, I love that.

Taylor Otwell:
But now Forge, Envoyer, and Vapor are all using the latest-

Matt Stauffer:
Very cool.

Taylor Otwell:
Version of Spark.

Matt Stauffer:
Okay. I didn't know that. So normally the next question we would be asking is how you install it. I don't think that that's something that's going to be reasonable to walk through for all four of these, and the docs are really good. So let's not worry about that one for this one. So we have talked about what every single one of them do and what their reasons are for existing. We've talked about what helps us decide which ones we're going to pull in. And just a quick recap on that, everybody, is just these are not absolutes, but the simplest answer is don't use Fortify. Just allow it to be pulled in by other things. Start with Breeze. And if you need teams, add Jetstream instead. And if you need billing, use Spark. That's really kind of the simplest form of it.

Taylor Otwell:
Yep, exactly.

Matt Stauffer:
Okay. So the next question I have for you is are there any lesser used features that are really cool in any of these or cool things you've seen people do that you don't think people are understanding? Are there any aspects of this that you think are hidden secrets or things you wish people would try more? Or do you feel like it's all pretty much out in the open?

Taylor Otwell:
No, I do feel like it's pretty out in the open. And I've seen people build pretty robust, cool-looking apps with Jetstream actually that you would not guess were Jetstream just by looking at them, because they've customized them to such an extent. So you can definitely do a lot with it. But no, I think for the most part, everything is pretty out in the open. There's not a lot of tips or tricks I could give for any of these packages.

Matt Stauffer:
Yeah. I'm definitely imagining that that question's going to be a little bit more relevant to the third-party packages, where maybe their documentation has not been like as obsessed over as your documentation has. So that totally makes sense. Okay, so the next question is do you have a development roadmap you'd like to share? And what I mean by that for you, because I think for a lot of other people, their roadmap is going to be a little bit more like we have this plan, we just don't have time and resources for it. You've got time and resources to do stuff. So obviously, if you had an immediate desire for these, you'd just do it. But I am curious, do you see... Especially because you did just build this API thing for Breeze for Nuxt and Next, and I know that you and Mohammed were both asking a lot of questions this past week about what's the future of single-page applications with these new kind of realm of things? Based on your experiences through those conversations, do we have a good sense of what the future of these packages are? Is it that Breeze API situation where all this stuff is moving into the frontend? Are we expecting that you're going to start building Next and Nuxt versions of the auth pages? And I'm not suggesting you should, but do you have a sense for kind of where the future is there?

Taylor Otwell:
Yeah, that's what we've been trying to kind of figure out over the last few weeks, and even few months for me, is it's more of just I want to position Laravel to be a sensible solution for the next 10 years, and that's going to look, I think, a little bit different than it did in the first 10 years, because just the landscape of web development is evolving and changing. A lot of people... I don't know about a lot. It's probably not the majority of Laravel users are using a frontend framework to build their frontend, either because their company wants them to, or they like the development environment, or maybe the people that work on their frontend don't even have server side programing experience. And so we want Laravel to be like hey, we're really great at traditional MVC, Rails style framework stuff, but we're also a really great choice if you need to off authenticate your Next, your Nuxt, your Remix, whatever frontend, or even you need to serve stuff to a mobile application, authenticating with that sort of situation.

Taylor Otwell:
And so building these starter kits is a way to sort of show Laravel is versatile and able to handle a lot of these situations going into the next few years, because I think, I mean, honestly, a lot of these sort of frontend ecosystems are in their infancy, I would say, in terms of what they can do on the server side in a productive way, compared to something like Laravel or Rails. They usually don't feel as cohesive in that way for the backend as much as they do for the frontend. And I think we're trying to be a like hey, we can do all of that backend, sending emails, talking to databases, queuing job stuff you need to do really easily, and here's a starter kit for authenticating your frontend, your frontend SPA to get you started really quickly, instead of just buckling down and focusing on no, we only serve blade views. Yeah, we don't want to kind of be locked in that mentality.

Matt Stauffer:
Yeah, I love that.

Taylor Otwell:
Anyway, so that's sort of my thinking. And then moving forward, the Breeze stuff this past week was a big step in terms of getting a canonical example out there of hey, how do I use Laravel with my Next.js app? And now we have a scaffolding kit out there that's officially maintained and a Next.js implementation of the entire Breeze frontend that's been written as an SPA and authenticates with that backend. And you can get it all set up in just a few minutes actually on your own local machine. So it's all really easy. I think that was a huge first step. I think we'll probably continue to explore ways we can position ourselves to be a viable contender for backend APIs and things like that. I don't know if that's through, like you say, Laravel new project name--API, or something like that, and certain Vue files are removed. So I think we'll continue to explore similar spaces in the future, and we'll just kind of see where that leads.

Matt Stauffer:
Yeah. I, haven't gotten a chance to look at the stuff you released last week, but I'm curious. So when I create a Next app, I'm not creating it in the context of a Laravel application at all. I'll build a Laravel application in a separate repo often to be an API or something like that. That sample thing that's basically Breeze built out, is that something that I go clone down? Or is that something that's actually generated in my local application when I use the Breeze starter kit?

Taylor Otwell:
So that frontend piece you actually clone down. So you clone down GitHub/laravel/breeze-next, and that is a Next.js application. There's no Laravel stuff in there at all.

Matt Stauffer:
Got it.

Taylor Otwell:
And it's a full implementation of all the Laravel Breeze features within Next.js 12.

Matt Stauffer:
That's awesome.

Taylor Otwell:
And It also includes a custom use:auth hook that handles all the authentication stuff, if you need to get-

Matt Stauffer:
Wow.

Taylor Otwell:
The current user, stuff like that. So you can just use:auth, and then you have the current user right there available to you. And that also exposes other functions like log out, log in, but all that's already-

Matt Stauffer:
That's amazing.

Taylor Otwell:
Implemented for you. And then the backend half is the part that's baked into Breeze, where, okay, I have the Next.js app, and now I need all the backend routes that it talks to to authenticate, to give me the current user, whatever, and wherever else I'm going to put my API stuff. That is baked into Breeze so that I can do Breeze:install API, and now I have a complimentary backend for that-

Matt Stauffer:
Love it.

Taylor Otwell:
Next.js frontend.

Matt Stauffer:
And so if somebody had an existing Next.js app, or if they had a Nuxt one, they could just look at that sample repo to figure out basically what that integration would look like?

Taylor Otwell:
Yeah, that's the idea. If someone wanted to do this in Nuxt or SvelteKit or whatever, or Remix, this implementation should be a really good reference point for how you would actually do that, because a lot of the concepts are the same between these frameworks in terms of pages and stuff like that. So this should provide a good starting point for pretty much any framework, but if you're using Next, it's pretty much already done for you.

Matt Stauffer:
Okay. And you know what? I just realized that you did the point that you don't think the majority of Laravel users are working this way, and I'm going to validate that 100% sure.

Taylor Otwell:
No, it's actually a small minority, I would imagine.

Matt Stauffer:
Yeah. So since that small minority is not the only people listening to this podcast, a real quick note, if any of you have not worked with these tools before, Next and Nuxt, and the others, they're essentially... So Next, we'll just talk about Next. It's a React app, but unlike traditional React apps, it's a little bit like Inertia almost in that, for example, you've got a pages directory, and in that pages directory, each JavaScript TypeScript file in there represents one of the individual pages. And you don't have to build out your own router. It just navigates to them. So in that way, it kind of... Well anyway, yeah, so you basically would say like I want to create pages slash about dot JS, and you just put the content in the React render function there, and it just is available at your domain name slash about. That's just it.

Matt Stauffer:
And it has other cool stuff that it can do. It has all the full functionality of React. And one of the things that Next has, I don't know about Nuxt, is it actually can spin up a tiny, little API server right there. It spins up own Node server. So it's very powerful for doing almost entirely frontend heavy things that you can just throw up on Vercel, Vercel or Vercel, and other just very frontend-focused hosts. But as Taylor mentioned, and as I've mentioned on podcasts multiple times, the moment you really need to do something much more significantly robust into these apps, you now have to get into building... You're probably not going to build an entire, very complex API in that kind of little API thing that they have there. And even if you did, you're going to be dealing with the shortcomings of Node in that there's just not the same ecosystem out there. There's not the same level of maturity out there that you have in the Laravel world.

Matt Stauffer:
And so for me, I've definitely fallen in love with Next. Every time I build in Next, it feels fast. It feels snappy. It has all these amazing optimizations built in, but I don't want to stop using Laravel at all. So the idea here, again, for those of you who aren't in that world, is keeping a Laravel programmer, but instead of putting React or Vue in front of your app, you can actually use the fullness of this kind of more robust and integrated React router situation that that is Next or Vue router situation that is Nuxt and still keep using Laravel as your backend. Okay. So that was your development roadmap. So again, this is a little bit weird one for you, but I'm just going to ask it anyway. Do you have any requests for help or support on any of these? And obviously you have people who are working for Laravel, and you've got yourself, so it's not like you probably need programming help, but is there any input or anything else like that that you would want? Or are you just kind of like hey, I'm pretty happy with where it is right now?

Taylor Otwell:
Yeah. Anyone that is a super Next expert or whatever and has any suggestions for the frontend implementation there, feel free to send them my way. I'm okay at React and stuff like that, but I'm definitely not a pro or an expert at it. I did enlist some help to actually create that reference-

Matt Stauffer:
Nice.

Taylor Otwell:
Implementation from Miguel, who's now heavy into the Web3 world. But he helped me actually build whole Next implementation. Also, if you wanted to fork that and build a Nuxt or Remix implementation for people, that's also a fun little project someone could have, but that's about all I can think of.

Matt Stauffer:
Yeah. Well, that totally makes sense. Well, again, I'm trying to keep this season shorter. So I think, at least for this first episode, we're just going to kind of call it there. But before we do, is there anything you want to talk about with Fortify, Breeze, Jetstream, Spark where you think we haven't had a chance to cover it? If somebody has never worked with them before and this podcast episode is their first introduction to them, is there anything else that comes to mind you want to cover?

Taylor Otwell:
No, I don't think so. I just think that Breeze would be your best starting point. So if you're new to these tools, try that out first, and then work your way out from there once you get comfortable with that.

Matt Stauffer:
I love it. Well, as always, thank you for the work you do for us in the community, especially with this auth stuff. I know that, for example, when you split out Jetstream, you split out Jetstream to address people's difficulties, right?

Taylor Otwell:
Mm-hmm (affirmative).

Matt Stauffer:
And you got some really positive responses and then also some negative ones. And I know that that wasn't an easy experience. And then you made Breeze, despite it being extra effort to try and kind of keep that simplicity available to us. So I just want to just say thank you for... Of course, I'm always grateful for the work you do, but especially in that particular moment. You're I'm trying to make it easier, and I'm getting all this flack about it. And then you did another level of work, and you made it easier, and now you're kind of responding to the Next stuff. So just in the auth situation, I've really seen your attentiveness to trying to make sure that everybody has a good experience. So thank you for your work there, and thanks for hanging out today too.

Taylor Otwell:
Yeah, thanks for having me.

Matt Stauffer:
All right, y'all. We'll see y'all next time.