Cashier vs. Spark, Pest vs. PHPUnit, and How We Manage Remote Teams

Matt Stauffer:
Hey everybody, welcome back to Laravel podcast season six. I'm Matt Stauffer, one of your co-hosts and Taylor, you want to say hi?

Taylor Otwell:
Hey everybody. How's it going?

Matt Stauffer:
Taylor Otwell, the man, the mystery, the myth, the legend, and so much more. Taylor, I saw a picture of you recently meeting Rasmus, the founder of PHP. Was that your first time meeting or have y'all hung out before?

Taylor Otwell:
No, it was our first time meeting, our first time speaking in any format, in person or online. Really the first time, you know, there's been any contact between us at all.

Matt Stauffer:
Wow. And I mean, he doesn't run PHP anymore, right? So it's not as if like he's in the day to day.

Taylor Otwell:
I don't really know honestly what I don't think you know it's his day-to-day thing. It's running PHP . Yeah, so we were at a Golden State Warriors game like a networking event for a lot of tech people. A lot of tech people were there actually like Rasmus was there, the web flow guys were there, flutter devs were there some for V ercel people were there and I was there. And so anyway, I go up to Rasmus, and I'm like you're the only person in this room I'm nervous to say hi to . And I was like I said "You're a living legend" and he laughed and he was like that was 30 years ago. Honestly after that we didn't talk about anything tech related we only talked about normal life stuff. We didn't talk about PHP at all.

Matt Stauffer:
That's awesome. Well, I know you don't know this history, but one day I'll probably have to ask somebody else. But for those of y'all who don't know, Rasmus created PHP as personal homepage language. But very soon afterwards, a group of folks who are not Rasmus took over and there was this Zend not Zen the framework, but like Zend the engine, and I know Zee was related, and there's all these other things. And now I don't know if any of them are still super involved. I think it's now more like the open source contributor people who are doing it. So it definitely does not have a primary person up top like Laravel does or anything like that. I think Ruby probably still, the guy who created Ruby, probably is still actually involved.

Taylor Otwell:
Yeah I know he for sure is still active because I just saw YouTube talk from him a few months ago. Yeah, I don't I kind of feel like it's maybe I don't know if it's a good or bad thing There's not someone at the top of PHP sort of calling the shots. You know with Laravel I think it's been actually a pretty big benefit to have sort of a BDFL at the top just to stop things from getting into too much bike shedding, or analysis paralysis, or... And eventually just move things along.

Matt Stauffer:
I couldn't agree more. I think that that's something we're missing at PHP a lot and I think that some of the lack of cohesion between the various groups of people who use PHP and their opinions about how PHP should be used is because of bike shedding and decision by committee and all that kind of stuff. It's just like sometimes you just need, even if it's a person who's really good at building bridges, you need a person to just say, nah, this is what we're doing. Even if it's not what they necessarily wanted, but they're able to just, you know what I mean? Just make it happen.

Taylor Otwell:
I mean a benevolent dictatorship is sort of the most efficient and best form of government just in the real world we can't guarantee the successors are as benevolent.

Matt Stauffer:
Yes 100%. Yeah, well, I know we've got a couple announcements I wanted to jump into. There's a lot of cool stuff going in the world of Laravel. So I figure we can jump to those first and so I'm just gonna go one after the other. First one is this new thing Franke nPHP was released as a another driver I guess you'd call them or base for Octane . For somebody who doesn't know anything about FrankenPHP or what it means to be able to use it for Octane, can you kind of give us like a real quick like what's what does this mean for the the world of people who don't live in Octane or really is this only meaningful for people who are like hyper-optimizing in the Octane world already and now it gives those kind of people who are really nerdy about that topic another option?

Taylor Otwell:
I think it's pretty cool for everyone actually and I'll try to explain a little bit about what it is. I wouldn't say I'm a super expert in Franke nPHP and the author of Franke nPHP is actually gonna give a talk at Laracon EU.

Matt Stauffer:
Oh fantastic!

Taylor Otwell:
Let's kind of start with how PHP works probably for most people today , which is they run Nginx and they run this thing called PHP FPM fast process manager I think it's what it stands for. And Nginx basically hands off request to FPM which then hands off I guess requests to PHP workers. So you've got like Nginx workers. You've got FPM workers, and it's a little bit more complicated than most other web languages in terms of how you run them. Where in a lot of other web environments you just start a single web server, and it handles everything you don't have two entities like you don't have Nginx and FPM. So what Franken php does is basically like imagine the built-in php web server you know like php Artisan Serve imagine it was like production grade and super fast and you know like I said production ready you could deploy it out onto actual web servers and just start one command and everything's running and you have one single configuration file, you're not configuring Nginx and FPM with different settings. Like you have one single configuration for your entire web server. That's essentially I think the the goal that Frank enPHP is trying to solve so that's one half of it . The other half of it is more related to Octane where what if we could keep your PHP app, your Laravel app, in memory once we boot it once, once we go through all the service providers, we execute all the framework bootstrapping and just keep that in memory and just feed it HTTP requests as they come in without having to reboot the framework on every single request. So FrankenPHP, that's one of its features as well. It's sort of the other half of the story. And that's why we built a driver for it in Octane, because that's what Octane is sort of built to help you with. So We have a Swoole driver, a Roadrunner driver, and now a FrankenPHP driver, and they all sort of accomplish the same goal of keeping your app in memory and feeding it requests. And what Octane does is add some Laravel-specific code that's necessary in terms of resetting global state, making sure your configuration is reset after each request, making sure your sessions don't leak over across each request, because it's a very different way of running PHP apps than, you know, historically we've run them. So Octane is sort of the Laravel layer, nicety layer to make sure everything works as expected when using these tools. And it's so much faster than using like the traditional N ginx and FPM setup because your apps in memory I mean, it's order. It's like multiple times faster in production, so it's a huge. huge speed boost. I can imagine a world where, in the next few years, I would actually like us to try to transition tools like Forge and stuff to just using stuff like this by default, because it's such a better way of running applications. It's such a faster way. It's a simpler way of running things. So that's the gist of it. And I'm sure there will be a lot more detail on it at Laracon EU when Kevin, the author of Franke nPHP, gives a talk on this topic.

Matt Stauffer:
Well, that sounds great. And for those who are interested, you can go to frankenphp.dev, where there's a pretty decent kind of overview of a lot of the ways it's working out. But I also think that Chris Fidao did an intro video to FrankenPHP, so we'll make sure we link that in the show notes as well. For those who are interested in a tiny little bit more nerdiness, the website kind of explains that it's actually built in Caddy, which is anybody who's done any nerding around servers has usually run into, I don't know if it's called, traffic or traefik or t-r-a-e-f-i-k. You usually run into the traffic and then Caddy. Those are kind of like two of the big servers you can do really custom stuff with that people deal with often. So like Taylor mentioned, phpfpm, which always has felt to me like this kind of magical, this is just what PHP running looks like thing. Until I learned that, like you said, it's just an Nginx plug-in, and it's a plug-in that makes Nginx and PHP play together nicely, which shows that it's not innative, it shows that it's not internal and integral. So it's cool hearing that FrankenPHP is really taking the ability to actually build it in at the core of its own server, but relying on Caddy so it doesn't have to create a server from scratch. The guy Kevin he made one other really interesting tool, and I'm trying to remember what it was but it's something about web sockets or something like that. Do you remember what that was?

Taylor Otwell:
Yeah, mercury? Yeah, he's also been involved in like API platform for symphony. Mercury which is kind of a I don't know if it even uses web sockets, but it's achieved similar goals. It's like real-time communication.

Matt Stauffer:
Yeah, he' s used some new technology to do it instead of websockets.

Taylor Otwell:
Yeah, he's worked on quite a few interesting projects. You know it's been around PHP a long time.

Matt Stauffer:
Yeah. Well, I'm really excited we're having him speak. I wish I was going to be there, but I'll be on my honeymoon, but I'm looking forward to, or getting married or something like that. But I'm looking forward to watching the video afterwards and learning from it. So. All right. So speaking of learning together, we also, uh, yesterday you announced, well, not yesterday, yesterday as of this recording, you announced the, the relaunch of the worldwide meetup. And in my memory, the worldwide Laravel meetup was something that Freek was doing originally, and then it's been on pause for a while and so this is kind of like season two of it . Am I, am I right in thinking about it that way?

Taylor Otwell:
Yeah. A Laracon speaker in the past and Laravel contributor over many years, Colin DeCarlo, reached out to me. He's like, hey, I'd really like to get the Laravel Worldwide Meetup going again. You know, is this something we could do? And I'll take care of like, you know, finding the speakers and make sure you don't really have to do anything. So yeah, I was like, OK, let me see what I can do and we eventually worked it out had a new website designed and yeah I'm pretty pumped to have that back because there's so many people around the world that don't really have access to like a local meetup, you know, and it's just not reason like like me for example in Arkansas. So it's just a cool thing we can do for the community and Caleb creator of Livewire will be the first speaker and yeah It's cool to have that back and I kind of a monthly meetup for people that don't have anything in you know the meet space to go to.

Matt Stauffer:
I love it. And that is just meetup.laravel.com. I'm trying to see one with January 30th. Okay, so this will be out before that comes. So very cool. All right, our next one. So you put out, you or Laravel put out a tweet recently about the Cashier quick start docs, and you kind of were telling us a little bit of story there. But rather than trying to retell your own tweet to you, can you just tell us a little bit of the story of what happened there?

Taylor Otwell:
Yeah, so Laravel has two kind of billing related things. You might say we have Cashier, which is sort of the lower level library for interacting with Stripe and Paddle. Let's you create subscriptions, you know deal with customers blah, blah, blah. Like I said, it's pretty low level. So we built a tool called Spark, which is basically a UI SAS billing starter kit built on top of Cashier that gives you all the UI stuff like plan selection, changing plans, cancelling, downloading invoices, and all of that. So here's kind of what has happened over the last, I would say, let's say four years is these billing platforms like Spark or Stripe and Paddle have started pushing towards more hosted no code checkout solutions. So, for example, Stripe has something called Stripe Checkout, where you can just redirect your users to Stripe Checkout and they host all of the plan selection once you define it in the Stripe dashboard. And then you can also redirect customers once they are subscribed to their Stripe customer billing portal, which lets them change plans, which lets them download invoices and all of that. So that all sounds exactly like what Laravel Spark is.

Matt Stauffer:
Yeah.

Taylor Otwell:
And so what's interesting is that over the last few years, I feel like Spark has become less valuable because these billing platforms have introduced their own no-code solutions. However, interestingly, Cashier has become more valuable because the webhooks you have to handle, the database structure you have to handle is becoming only more complex. So even though like Stripe hosts all these checkout pages, you still need to like keep the data somewhat in sync in your own database so that you know if someone's subscribed without making an API call to Stripe every time they call your application. So that led me to kind of be like, okay, what is, what do we want to do with Spark? G oing forward? I think there's part of me that would like to eventually just open source it at some point and have it not be a commercial product anymore. It's just something open source. But it also raised this idea in my mind. If I was starting a new layer of a project today, what would I actually recommend as far as a billing flow? And a big part of me was like, Oh, you should just use Stripe checkout and Stripe customer billing portal. That's really all you need and when I look at our docs for Cashier. I was like this is overwhelmingly complicated like dealing with customers , dealing with subscriptions, like let's just write a quick start. That's two sections I want to sell subscriptions, or I want to sell products like t-shirts or one-time purchases. So I gave that project to Dries and he kind of worked up the draft of it and then I came in and kind of massaged that a little and we put it out there on the docs as just like if you're starting a new Lar avel project today and you're using Stripe, for example, this is the quick start for how to get started selling subscriptions using Stripe checkout and Stripe customer billing portal and I think it's just like a much cleaner thing, a way to get started. I wanted to document it for a long time, so I'm glad it's out there and I think we'll probably do a similar thing for Paddle as well. So yeah, that's the gist of it, you know. Yeah, I love that. Does that make sense? Or is that too deep in the weeds?

Matt Stauffer:
No, that was the perfect level. And I love it personally because I would often be having conversations with people and then I'd be like, well, wait a minute, that's Spark classic. What about modern Spark? And then the question was always more complicated because of these, you know, the low code tools or whatever or no code. I love the idea of us being able to rely as much as possible on the tools that they're publishing for us to use, while knowing that we have everything synchronized. Because that's something I've seen happen in some of my older codebases when I would try to move to Stripe Checkout, is I wouldn't always be fully in sync with what was going on there. And I'd be like, oh yeah, they can change more things there than I was expecting, and keeping it in sync with my local is difficult. So just knowing that I can trust that they've built that UI so I don't have to build it in Spark or whatever else. And you have done the work to make sure that I've got all the data in sync. That's the most confident I can feel about the thing. So I love that there's a real quick, easy way to kind of know, here's the recommended options, prescriptions for purchases, call it a day.

Taylor Otwell:
Yeah, and when we first released you know Cashier and Spark which was probably 2015. Billing and checkout was way, way simpler than it is today with new international regulations like 3d secure 3d secure 2 Where when someone's entering their credit card sometimes you have to pop up like this confirmation box that's 3d secure and when you're using Stripe checkout. You know they're always, in theory, up-to-date on that doing the right thing but in Spark it was becoming such a maintenance nightmare to keep up with these international regulations in terms of how billing works that it's not super sustainable for us, and it doesn't even make sense. You know if Stripe checkout can do it for us

Matt Stauffer:
I hadn't even thought about that because I've seen those things before, but thankfully have not been in a place to have to deal with them lately. But again, I'm glad that I won't have to. So yeah, that makes sense. All right. Well, we got a couple more topics to cover today. So let's move on to the next one, which is there have been a couple of tweets lately between mainly Ian Landsman and Eric Barnes, although I swear somebody else had one where they were talking about when you're starting a new application, what do you put in your service providers boot method? And I was thinking, because last time we talked about what package do you put in every single time, and you said that you used the Once package that Spotsy wrapped up around your original code on everything. But I don't know if I put something in the service provider for every app ever. And I think most of what Ian and Eric's... Eric's was about the should be strict thing for your models, and so we could talk about that for a second.

Taylor Otwell:
I hate that feature. That's the worst feature in Laravel.

Matt Stauffer:
Tell me.

Taylor Otwell:
It's basically like In theory it wouldn't be a bad feature, but I'll explain why it's a bad feature or why it ends up being kind of a pain. So it's basically this feature in eloquent where you can say should be strict or something ID document It's not even in the docs anymore. But and basically if you try to access an attribute that wasn't pulled from the database like say you selected you select name and email instead of select asterisks and you try to access like birthday on the user model and If you have strict mode on it will just throw an exception you know hey you're trying to access something that doesn't exist. Whereas normal eloquent over the past 12 years it would just be null if you tried to access something that wasn't selected. So in theory this wouldn't really be a problem right you would you would think it would be a good thing . Like you have your app you select the right things if you see an exception you you didn't select the right data, you're always selecting only the data you need, more performance, blah, blah, blah. T he reason it becomes an issue is you start bringing in packages that now they have to sort of be aware of like is strict mode on? Is strict mode off? And like just the other day in Passport it was trying to access the grant types on the user model that weren't selected through an exception. Now we have to fix this in Passport It's honestly turned into such a headache from the package perspective that it makes me really soured on the whole feature.

Matt Stauffer:
Yeah.

Taylor Otwell:
So that's why I don't like it. I also you know I don't like it just from the maintenance burden It's sort of put on us from a package perspective of having to always be aware of what if they have strict mode on? what if they have lazy loading disabled? and like it's hard to build packages with all these caveats of how eloquent can behave very differently based on how the users configured it. A nyway .

Matt Stauffer:
I was going to ask about lazy loading next so it makes sense that that's also the same pain.

Taylor Otwell:
We have had less pain with lazy loading honestly, and it's still in the documentation you can still disable lazy loading we document that . There's one other thing we document because this Passport thing just happened the other day Let me look at this strict mode.

Matt Stauffer:
While you look that up for the listeners the the prevent lazy loading just says if you try to access a relationship on one of your Eloquent instances and you have not already loaded that, it's not going to be like, oh great, I'll go load it for you right now, which is what lazy loading would be. It'll throw an exception to make sure you've always eager loaded everything, which is beneficial from a performance perspective.

Taylor Otwell:
Mm-hmm. So the other thing we document is you can disable Eloquent behavior of silently discarding Non mass fillable attributes when you try to pass them to like the create method. So imagine you have a user model and your fillable array for your fillable attributes as name and email. You do user colon colon create you pass name email and birthday, which was not fillable typically Eloquent would just silently discard birthday and insert the data it can. You can make it so that if you pass something that's not fillable it actually throws a full-on exception. I haven't had any problems with this behavior actually this is I'm fine with this I think. I've never seen this cause any issues So it's probably a decent feature, but the whole accessing things that haven't been selected throwing exception has caused us quite a bit of headache. Which made me regret adding it. But that may just be that may just be from my maintainer perspective. You know m aybe it's a good thing at the end user perspective

Matt Stauffer:
Yeah, I mean, part of the issue is, you know, if it's making life difficult for the maintainers, then it's not great for the user. I'm definitely of the opinion that a lot of these tools are helpful because they help us discover ways we're accidentally making mistakes. Like the first time I turned on prevent lazy loading, it found a way where I didn't even realize I was lazy loading because it was such a complex web of relationships in this thing. I was doing one of those things where you have like a relationship that's, it's a one of many, or sorry, you're only selecting the most recent one of a many-to-many relationship. And because of the complexity of defining those, I was accidentally not eager loading it. So I learned some things from them, I like them. But none of those are ever worth the cost to, oh my gosh, everything's way more complex in our code, all the packages are gonna be more difficult, our maintainers, you know, like, to me, I'm like, there's other ways to solve this problem, right? We can understand when lazy loading is happening from a debugging and a debug bar perspective, and we can build tools for it without actually disabling it for the whole thing, you know?

Taylor Otwell:
Right, yeah.

Matt Stauffer:
Okay, well so yeah I so that was so Eric's had Eric talked about that Ian's had that and then he had a lot of very specific things to packages that he was using. You know he says he puts them in everything maybe uses those packages, but his were things like the the Guard package that he uses and some Livewire and Filament specific middlewares and stuff like that so. Again, I can't find myself saying that I do this and one person pointed out in one of those threads that Lambo which is a tool I built a long time ago that like allows you to do certain things after you run Laravel new every time. And one of the things you can do is have it run a bash script. And so some people have said, every single time I run Lambo to create a new project, it requires these particular packages and it also inserts these particular lines in the app service provider. And again, every time I've asked people, hey, what packages do you use in every project? What things do you insert? I've almost never been able to come up to something on my own where I'm like, every app I've ever built should have X. And I don't know if you feel like, do you have, is there anything you always put in a service provider?

Taylor Otwell:
So I actually pulled up our Forge service provider, and there's not much interesting here, I would say. We have a few container bindings where we make something like a singleton that we want to be a singleton. We register a couple authorization gates, closure-based authorization gates. Kind of the most interesting thing in here I would say, which may be a little bit uncommon, is we actually register. This is probably a relatively obscure feature of Laravel You can do Q colon colon create payload using where you can add something to the every Q jobs Payload . We add the user ID of the person that triggered the Qued job to every qued job. That's probably like 15 lines of code and other than that. There's really not much else that we have in a service provider and all the other projects I've worked on actually I don't feel like I put a lot of stuff in service providers.

Matt Stauffer:
Same. Yeah, and the things you're mentioning, and also now I'm looking at Ian's tweet, which I'll link in the show notes, I'm realizing almost all of this is contextual. It's stuff like morph maps in the relationship, you know, thing. So if you want to use the class name or you want to use a short string instead of the class name, okay, that makes sense. He's binding a new engine for a database, okay. He's adding some collection macros, like macros make sense, right? But none of those are universal, right? They are contextual and specific. He does have one where he says date colon colon use carbon immutable.

Taylor Otwell:
We were just talking about this at Laravel yesterday. Tim McDonald was like, I think carbon immutable should be the default. And I was kind of like, Hmm, it's sort of a big breaking change to ship to change everything to be carbon immutable. And I was like, people can just use date use carbon immutable. So it's funny that Ian had that in this project.

Matt Stauffer:
Yeah, I would say it's the sort of thing where I'm not burned if you guys don't add it or if you wait for the next major version or whatever to add it. I like the idea in general because I have been burned before when I forget to clone something. And for those who don't know, Carbon Immutable basically says if you've ever run into that thing where you do some work on a carbon instance and then you modify it for the next time, you don't realize that you're actually modifying the original instance and so sometimes that's not what you wanted to do. Carbon immutable doesn't let you do that. You have to basically create a new instance that you're, you know, every single time. So it's another one of these strict things, right? It's like kind of forcing you into not making mistakes. It's one of those, like, how strict do we want to be by default versus how much do we want people to allow to choose strictness when it's fitting for them? So.

Taylor Otwell:
Yeah, and I actually like carbon immutable and to Tim's point he was he was like yeah It is probably a breaking change, but it's also. You know just like Ian has carbon date use carbon immutable. It would be very easy for people like in the upgrade. We say hey, I don't want to use carbon immutable just do date use carbon. You know now you're right back to Laravel 10 behavior, so we'll see how that plays out.

Matt Stauffer:
Okay, I was thinking for some reason I was thinking of a carbon immutable you needed to clone it but you don't have to it's just if you make a modifier it creates a new instance every time which is actually...

Taylor Otwell:
Just like collections.

Matt Stauffer:
It's still breaking, but it's not as impactful because people don't have to go modify their code unless they were accidentally or intentionally relying on that modification.

Taylor Otwell:
Yeah. Exactly.

Matt Stauffer:
I got two more topics if we have time for them. We might not get to both of them, but I want to talk real quick about Pest versus PHP unit as a test runner. I'm working on a video right now that will have been released by the time this podcast comes out. Unfortunately, it's not out yet, so Taylor, you have not seen it. But it's referencing a tweet that you put out where you basically polled and you asked people, what should the test runner be for the next version of Laravel? Should it be P est or PHP unit? And one of the things I'm clarifying in this video that I wanted to kind of say here and get your thoughts on is the idea that there's two really impacts of changing to Pest from phpunit. And one of them is that when you run your tests, regardless of how those tests are defined, what are they running through? It can run through phpunit or it can run through Pest, which is a layer on top of phpunit. So it's basically phpunit configured a certain way when it adds you know, code coverage and, you know, prettier output and all these things. But it's really like they're both running PHP unit. One just comes with a bunch of plug-ins and decorations on top of it. And then the second part of Pest is an optional new syntax for writing your tests that is this functional, you know, Jest style syntax. But you can use the PHP unit class syntax with Pest as a test runner, which I don't know if a lot of people know. And that's why I was very curious about the fact that your tweet asked about not what should be the default test syntax? but what should be the test runner ? I did notice that you said, well, if Pest is going to be the default test runner, we also, if you ran PHP artisan make test, it would make a pest test unless you pass in dash dash PHP unit. But in theory, if you make a brand new Laravel app, And if you have chosen at that point to make Pest be the default test runner, you can still, you know, create as many PHP unit style classes as you want. So it's not forcing people out of that style. It's just meaning you have to do a little bit more work to do it that way. And now by default, you're going to get all those extra benefits that Pest provides as a runner, regardless of your syntax. Do you have thoughts about that? Am I telling the story correctly? And do you have any thoughts about how you're leaning as of today?

Taylor Otwell:
No, that's pretty much the story. I was just curious to tap into the community on Twitter and see what people preferred . I was actually hoping the results would be even more dramatic one way or the other. I can't remember what it came out to roughly like 60 40.

Matt Stauffer:
I think yeah something like that. l was hoping it would be like 80 20 you know or even like 70 30. So I can't say it really swayed me too hard one or the other. I like a lot of the features of Pest. I like a lot of the syntax of Pest. I think the data provider syntax especially is like a huge improvement over PHP unit but then again PHP unit just has so much familiarity and sort of legacy presence in the PHP ecosystem. It is sort of like a big ask just moved kind of the default testing setup away from that So I don't have a firm answer on like way. I'm leaning unfortunately. I was hoping that poll would be more dramatic as I said But yeah, I mean it is cool that like. You know, maybe there is merit to Pest being the test runner, even if PHP unit was the default test syntax. I didn't actually consider that very strongly, but it may be an interesting approach.

Matt Stauffer:
I'll share the video with you once I'm done with it. But basically, and I was talking to Nuno a little bit, and I was like, you know, I'm making this video. He's like, oh, you should really talk to people about the syntax. And I was like, no, no, no, syntax is cool. But there's an adoption cost to the syntax. The syntax, the new syntax has all these great benefits. The data providers is better. So it's really cool stuff. But the thing is, we don't need to convince people to change syntax. If I'm correct here, which I hope I am, I've run it by Nuno, I've done some tests on my own. If I'm correct here, the whole Laravel world should consider moving to Pest as a test runner. You've got an ancient Laravel codebase with 800 PHPUnit style classes, you should still consider Pest as a test runner. Because, I'm going to say this in the video, but your console output is more beautiful, especially in some Laravel specific ways that, you know, PHPUnit doesn't consider. You get parallel testing for free. You get code coverage generation for free. You get speed profiling for free. You get type coverage, like what percentage of my code base is covered by type coverage, if you care about this kind of stuff. You get stress testing for free. And you also can have the Expectations API. And you can use that Expectations API, which is a different way to write assertions that I think is cleaner. It's a more fluent syntax. But you can do the expectations API in your PHP unit style classes. So there are other cool things that Pest offers that I understand that like people can make the decision about whether or not they want. But I'm like, look, if we have an entirely PHP unit style code base, and there are no shortcomings that I haven't thought of. And the problem is, I haven't done this on 100 code bases, right? So I don't want to be the guy who makes this campaign and we discover, oh, man, it burns you in this way. But at least on a brand new code base, I've done it in a brand new code base multiple times. Pest is the test runner, keep making PHPunit style code classes, and I'm having a great time with it. You know, I get all those benefits. I don't have to learn new syntax, which I personally have learned, but I'm just saying as a hypothetical person who doesn't want to learn it, it's kind of great.

Taylor Otwell:
C an't you even mix and match like PHP unit, test classes with Pest test classes in the same project and it will just run.

Matt Stauffer:
You can have 800 existing ones with the old style. You can write all your new ones in the new style and all of them are getting those benefits I just listed off, you know. So and I didn't get that and when I when I interviewed him on the podcast like a year ago I was thinking it's all or all or nothing, right? And so I was talking purely about the syntax and he almost accidentally revealed to me. He's like well I mean you get these benefits what you know either way and it's not as if those benefits are things you can't get yourself in a PHP unit, you know, you can add parallel testing, you can add code coverage, all these things, but I've added them before and it's work. And with PEST, they're just there. So I'm kind of like, well, if we just get all those things for free, why not? And again, I asked Nuno and I've run some of my own tests, but if somebody hears this and they're like, here's a cost to using Pest as your test runner on top of an existing PHP unit, please let us know. Let me know on Twitter. But I have not seen any cost to it yet.

Taylor Otwell:
Yeah, that's interesting.

Matt Stauffer:
So we'll see.

Matt Stauffer:
"c.hange to Taylor" It's good stuff to chew on you know leading up to Laravel 11's release sometime in this first quarter of this year.

Matt Stauffer:
Yeah, okay, so we I think we do have a little bit of time for our last topic. And I've asked you this question a couple times before so apologies for making you rehash it. But people keep asking this question of how do you guys and you ask them to both of us? How do you manage a team? How do you do synchronous versus a synchronous communication and How do you task people? Do you have product managers and developers? How do people know what to do? And I just figured like we could both just kind of share a little bit about how we kind of run our teams. And just because I'm the one asking the question, I'll start and then kind of see where it kind of leads for you because I know we run our teams a little bit differently. But basically, our entire teams, everything is in Slack. We don't use email at all. Everybody's relatively synchronous. We ask people that they can work US-based hours so that we know there's going to be a majority overlap with people's hours. The vast majority of teams have a project manager and two programmers. The programmers spend, I would say, a quarter to three quarters, depending on the team, of their week pair programming. And then there's a lot of time just working independently, but we do at least one weekly check-in where the entire internal team meets up to talk, and at least one weekly check-in where the entire team meets up with the client to talk. And then there's regular check-ins multiple times during the day. Usually our project managers are managing the backlog so that the programmers can be programming. And when they get a task, they can ask for the clarification questions they need. They can do their architecture planning together and stuff like that, and they can kind of go code. And they can run things by the PM and everything like that. But the PM is often like, once that has been done, the PM is working with the client to define like, what's the next set of tasks going to be working on? And, oh, well, you didn't give us this definition or whatever. So that's kind of our most asynchronicity comes from the fact that the PM is gathering definition often while the programmers are actually doing code. Our lead programmer will often work together with the PM also to make sure that the definition makes sense from a technical perspective. But we've read the book Remote from 37 Signals, and we are so much more synchronous than them. They're very much in the write it up in Basecamp, somebody else reads it at some point in the next 24 hours, somebody else approves in the next 24 hours, you do the code in your own, you throw it over a wall. And Taylor, I want to hear from you, because I think you're a little bit more asynchronous than we are. You're a little bit more Basecampy. We're much more synchronous. There's a lot more communication and collaboration. But what we try to avoid is unnecessary meetings. And that's something I've noticed that's very different between us and the culture of a lot of the companies we worked with, is that meetings and emails are much more heavy in other companies than they are at Tighten. If we need a meeting, it's because we saw a limit of written or, you know, Slack communication. And then we're like, yeah, the quicker things to do is jump on a call for five minutes, right? And then go back off versus like, oh, every time we need to have a conversation, it's going to be an hour long phone call with 17 people or something like that. So we're synchronous, but we're trying to keep it low cost synchronous versus I think some folks are just like, everybody's on every single call all the time and it takes three hours and yada, yada, yada. So that's kind of, I mean, people asked about async versus, they talked about meetings, communication, frequency of meetings, async versus sync. I think that's kind of it for us. And oh, for tasking, that was the other thing. So Taylor, can you talk a little bit about like what it looks like for you doing that kind of arrangement of communication and tasking, everything like that at Laravel?

Taylor Otwell:
Yeah, I think we're much closer to your style than like a full asynchronous style. So of course we use slack. That's our honestly our main form of communication. We do use Basecamp some but we use it in a limited way. We don't use all of its features like we don't use like the chat feature in Basecamp. Really we use Basecamp for I post a monthly write-up of what we want to work on that month and I kind of assign it to the devs. I basically am functioning as the product project manager you might say across Forge , Envoyer, Spark all of that. I write up that monthly write-up. I assign it to the devs and from there most of our devs here have pretty wide creative freedom, I would say, in terms of how things actually are implemented. And we'll discuss the details in Slack. If someone has a question like, hey, should this work like this or like that? And I'll kind of chip in and give my feedback and get their thoughts. And we'll go from there. And that's kind of how we work through those decisions. So we don't write up that kind of stuff like in Basecamp, like, hey, I'm struggling with this. What should we do? And it's like a big Basecamp thread. We don't really function that way. We also use sort of like a Kanban board on Basecamp to keep track of what everyone's actually currently working on and sort of what state it's in. Like is it blocked? Is it pending review? Is it in progress? And then the third thing we use in Basecamp is daily check-ins where every day at 4.30 it pings every employee and just asks like, hey, what did you do today? And it just has to be like a few sentences or a paragraph about sort of what you were doing. And really the main reason we do that is so that I can just kind of have a high-level overview of what's actually happening at the company, because sometimes it's hard to keep track of what state everything is in, what people are working on, if they're stuck or not. And so that's sort of the role that that plays. Everything else is really just in Slack. We almost never do calls. We probably do less than we should. And I should probably like caveat all this by saying I think Laravel will change this year because we would like to beef up the team because we have some more ambitious projects we'd like to tackle in 2024 and I think we will have to move closer to like actual project managers on some of these products like Forge and Vapor instead of it just being me. With a team of devs under them and things like that because I feel like we're basically running on a skeleton crew at this point sometimes. We're at ten people. We probably need to be like closer to 20 people given the size of these products. So you know that's how we are now, but I bet if we talk about this again next year we'll have a different setup and that could be interesting to revisit.

Matt Stauffer:
Yeah, I love that idea. You actually said two things that I've realized that we do and aren't even named, so I appreciate that. We do Kanban for almost everything. Almost all of our projects are on Trello, if possible. If not, we try to get the most Kanban view in whatever tool the client's using. And it's almost always like, Backlog, you know to do immediately this week or whatever doing the done and ready for code review done and ready for client review. Whatever the various stages are like done and on staging but not in production or whatever. And then we also have a weekly or not a daily thing where everybody writes kind of like an EOD and end of day and and it just says like, hey, here's what I did today. And it's a bot that actually scrapes those messages and puts them in one central place. I used to read all those so that I knew what was going on for all of our projects, and I'm at the level of the company right now where I can't, but Keith has access to them and the PMs if they need to kind of ask those questions, they can. But essentially the main thing is just sort of saying like, hey, at the end of every day, let's talk about what we did. For some projects, we're actually sharing that with the clients. For some projects, the clients would be overwhelmed by that, so we're not. Let's make sure we know what we did. We can also go back later and if the clients are being like, well, what happened this week? We always have a great record of it. We can say, oh, well, here's the thing I did every single day and you also had access to the information or whatever. I would definitely love to check in in a year to see what the new structures of the company look like. We'll have to set a reminder for that. All right, well, we are at time, so the last question we have open here is, what is the album released most recently that you've really enjoyed? So some album, new album that comes out in the last months to year that you've actually enjoyed listening to.

Taylor Otwell:
One that sticks out that was like a new discovery for me in the electronic, well, yeah, I guess kind of down-tempo electronic space was this group called The Lastlings, L-A-S-T-L-I-N-G-S. It's like a brother-sister duo. I think you know she kind of sings and yeah, it's a pretty sweet. They're pretty pretty good group. So their most recent album is perfect world came out in 2023, but yeah I listened to that quite a few times over the past few months. It's just sort of like good music to chill and work to they've got a another album that came out in like 2020 .

Matt Stauffer:
Okay, that's awesome!

Taylor Otwell:
P retty cool. Yeah What about you?

Matt Stauffer:
I just looked at my side I split between iTunes and Spotify so I don't know if this is the best way to look but I'd noticed two, three albums actually that I've that came out recently starting from the earliest Harry Styles, I've never listened to him before. I don't know anything about him, but my fiancee Amani was like, you, this Harry's house album that he just came out with, I think you would really like the vibe of this. I love this album, man.

Taylor Otwell:
Yeah, I like Harry Styles.

Matt Stauffer:
Like I play it when I'm cleaning, I dance around it. I'm like, okay, I like some pop, I guess. So I'm glad you've heard of him. I know he's a, he's famous. I think, is he an actor too? Was he in that one movie that set in the sixties recently?

Taylor Otwell:
I'm not sure.

Matt Stauffer:
IMDB, let me check real quick. Because if so, I really liked him as an actor, too. Sorry. Don't Worry Darling. It's one of those where, like, you don't know all the details at the beginning, so I don't know what I should say about the movie. It was a really fun movie. I would definitely recommend it to anybody. But he's one of the two leads. He's the male lead, and then some famous woman is the female lead. It's a great movie. And I did not know, or at least wasn't actively aware of the fact that this is a singer. You know, it wasn't one of those like, yeah, you brought the rapper in kind of, you know, brought the pop star in kind of vibes. Like he did a really freaking good job. So anyway, Harry Styles. W e love the, the Spider-Man soundtracks around this house. My son plays out the Spider-Man and the Metro booming one. I don't think it was as good as the first end of the Spider-Verse soundtrack, but it was still very good. And then, um, Jamila Woods is a weird hippie, dippy singer, songwriter person I listened to. And I, um, I don't know if I would say I love Like Love It, that everybody should listen to it, but I've kind of been enjoying her Water Made Us album that just came out I think at the end of last year or the beginning of this year. But Harry's House is definitely the standout one where I would say worth a listen to anybody.

Taylor Otwell:
Nice.

Matt Stauffer:
Sweet. Well, Taylor, thanks for hanging out as always. Great conversations. And I'll make sure that everything we talked about is in the show notes. Everybody, including the Cashier Quickstarts, Franke nPHP, Worldwide Meetup. Make sure you go to meetup.laravel.com and you can actually type your name and email address to get a reminder for when the January 30th meetup comes up. And we'll also have the boot service writer tweet and my video about passwords of PHP unit. And if you have thoughts on any of these things, hit us up on Twitter, you know how to find us. Until next time though, see y'all later.

Taylor Otwell:
See ya.

Creators and Guests

Matt Stauffer
Host
Matt Stauffer
CEO Tighten, where we write Laravel and more w/some of the best devs alive. "Worst twerker ever, best Dad ever" –My daughter
Taylor Otwell 🪐
Host
Taylor Otwell 🪐
Founded and creating Laravel for the happiness of all sentient beings, especially developers. Space pilgrim. 💍 @abigailotwell.
Cashier vs. Spark, Pest vs. PHPUnit, and How We Manage Remote Teams
Broadcast by