---
title: 'Let''s Build a SaaS in Laravel - Set Up Our Dev Tooling and Environment'
source: 'https://youtube.com/watch?v=cAhVwrWpGlo'
video_id: 'cAhVwrWpGlo'
date: 2026-06-14
duration_sec: 889
---

# Let's Build a SaaS in Laravel - Set Up Our Dev Tooling and Environment

> Source: [Let's Build a SaaS in Laravel - Set Up Our Dev Tooling and Environment](https://youtube.com/watch?v=cAhVwrWpGlo)

## Summary

This video walks through setting up a local Laravel development environment from scratch, including installing the Laravel installer, creating a new project with Breeze and SQLite, and configuring code quality tools like Duster and Prettier with Husky and GitHub Actions. It also covers setting up Mailpit for email testing and verifying the database and tests work.

### Key Points

- **Project Creation** [0:04] — Use `laravel new Symposium` to create a new Laravel project with the new prompt-based installer, choosing Breeze with Blade and Alpine, skipping dark mode, and using Pest for testing.
- **Database Selection** [1:45] — SQLite is the new default database for Laravel apps, chosen because it requires no additional dependencies.
- **Duster Installation** [2:50] — Duster by Tighten brings together multiple linters (Pint, TLint, PHP CodeSniffer, PHP CS Fixer) into one package. Install via Composer and set up GitHub Actions and Husky hooks for automated linting.
- **Prettier Setup** [6:49] — Prettier is configured for Tailwind class ordering and code formatting. Follow a blog post at mattstauffer.com to install dependencies, create `.prettierrc` and `.prettierignore` files, and integrate with Husky and GitHub Actions.
- **Mailpit for Email Testing** [12:35] — Mailpit provides a local mock email inbox. Install via Homebrew or Takeout to view and click through emails during development.
- **Database Verification** [13:22] — Run `php artisan migrate` to confirm the database works. With SQLite, the entire database is a single file (`database.sqlite`), which can be deleted and recreated.

### Conclusion

The local Laravel environment is fully set up with linting, formatting, email testing, and a working database, ready for building the SaaS application in subsequent videos.

## Transcript

[Music]
all right for this first video we're
going to get your app up and running
from scratch and your local development
environment and while there is laravel's
herd Pro to provide a lot of these
dependencies for you we're also going to
make sure that you got a free version of
every single dependency you need to get
started so let's get going all right to
get started we want to make sure that we
have either valet or herd pointing to
our sites directory for me but some
primary directory we're going to use the
laravel installer which you'll get for
free if you have herd running but if not
you can use the LEL documentation which
will show you what it looks like to get
the larel installer working we're going
to run laral new Symposium to create our
new project and we're going to see this
beautiful new interface provided by
laravel's prompts we get to choose first
which starter kit we're going to use and
this new prompt-based system means we
don't have to install Lal and then
install a whole bunch of dependencies
afterwards we actually get to choose
which independencies we're going to
install as we go uh jet stream is a lot
more complicated than what we're going
to need in this particular project so
I'm going to choose working with Breeze
there's all sorts of options for B here
we can do Blade with alpine if you're a
reactor view developer you can get
inertia there's also an API only version
and of course there's all the live wire
options but because we're keeping it
simple on this one I'm going to stick
with blade and Alpine I choose generally
to stick with Blade with alpine unless I
really know I'm going to need Live Wire
and I'm personally not a big single page
application guy even though if I were
inera would be the way I would do it for
sure we're going to skip dark mode
support in this particular one if you're
not familiar pest is the default testing
framework that all larl apps use going
forward if you want to use PHP unit
that's fine but we're going to stick
with pest with this one because why not
so it's going to install our basic
dependencies and at some point here it's
going to ask us about database and here
we go so sqlite is the new default
database for larel apps and once again
it's not my SQL which we're always
familiar with but I would say it's the
default it doesn't require any
dependencies let's get started with it
and see how far it takes
us so we can watch it
[Music]
install and there we go we can CD into
our new app simposium and as you can see
it says CD Symposium PHP Artisan serve
which is the fastest and easiest way to
get up and running with serving but
because we have either Valley or herd
running we can assume we're going to be
able to visit as symposium. test in our
browser so before we do anything else
let's go actually go to our browser and
type that in to make sure it actually
works all right you can see what a
default lay app looks like in lar Val 11
got to zoom out a little bit here so
this is what every Stock laral app is
going to look like in L Val 11 it's
working the first thing we're going to
pull in is some dependencies that make
sure that all of your code is consistent
across all of your contributors and all
different environments and it's
something I've started pulling in in all
my projects going forward right at the
very
beginning so the first thing we're going
to pull in is a project called duster by
Titan and what duster is is it brings a
whole bunch of different linters and
fixers together in one place you've got
lille's pint but you've also got tlint
PHP code sniffer and PHP CS fixer which
each adds some things to our linting and
fixing situation that pint can't do for
example tlint can handle lel's blade so
basically what we want to do is have all
of them together in one kind of
organized thing where they're all
working together in unison and that's
what duster provides for us so we're
going to want to click on this which
will copy the install and then we can
paste it in here and this will Quire
duster in our project now one of the
cool things you can do with duster is
you can come over here and you can grab
this GitHub actions publish and these
husky hooks so with GitHub actions what
happens is every single time somebody
takes a certain action for example push
a commit uh it will run your linters or
your fixers or whatever else you want on
your project and so we can use this to
publish some uh GitHub actions for
duster we also have the same option for
Husky hooks which basically does the
same thing but instead of in CI it's on
your local machine so we're going to
install both for our projects let's
start with GitHub actions so when we run
this command it's going to allow us to
choose three different options we can
lint only which means it just is going
to error out if there is a problem if it
doesn't pass our code uh quality you can
fix and commit which actually makes a
new commit to fix it for you and then
actually uh commits that to your G
history uh there's also a third option
the third option is a little bit more
complicated what it does is recognize
that you often if you're going to do get
blame which shows you what particular
git commits contributed towards this
line of code looking this way you don't
often want to see the formatting commits
and so what this does is it fixes it
makes a new commit but then it also adds
that commit to a file that says ignore
these when we're running get blame it's
the most complex but it's really the
best so we're actually going to use that
one for this
project it says resulting commit we'll
stop any current R yep that's fine this
is what we expect it to do it's nothing
that stresses out so we say yes we want
to continue and that's
it and now we're going to do the same
thing for Husky hooks which again
remember with Husky hooks what happens
is every single time we run get commit
that's the way we're going to set it up
it's before you actually run get commit
it's going to run duster for you um so
you don't even get the whole way up to
continuous integration before it runs we
also get an option here we can either
have it lint so it'll error out the
commit or we can have it fix and commit
which means you know it'll actually make
a fix and then commit the fix for us you
may have noticed that when I was running
that we saw this little error here that
says XC run invalid after active
developer path sometimes when you update
Mac OS it loses its reference to where
the command n tools live and you need to
basically run a command that says hey
here's where it is and this is the
command it's xcode select DS and then
you just pass it the information of
where xcode is so I went to I turned off
recording I went to another tab I ran
this it's everything good and now we've
got husky hooks enabled so to dive a
little bit further into what husky does
it allows you to set a configuration of
what to do at certain moments in the G
workflow and in your do husky directory
you can add a new file for every single
moment we've got one here for the
pre-commit moment which is right before
git runs commit and basically you're
defining what happens in that moment and
we're saying is run the npm package lint
staged what lint stage lets you do as
you can see in our config file here is
defined that at that particular moment
it's going to run lint stage which is
going to say only for files that are
staged in git so that are like added
into our current working git stuff that
match this particular glob then take
this action so we say for all thephp
files we are going to run duster fix on
them but only the PHP files and only the
staged
ones so that's it for duster and now
it's time to take a look at our next
project that we're going to pull in
which is called prettier so prettier is
a little bit more complicated to install
in a laral app than duster is so I wrote
up a blog post in my personal blog
walking you through all the steps and
all the independencies you need so you
go over to Matt ster.com check out the
Articles and find this article how to
set up prettier on a larl app linting
Tailwind class order and more and you
can see that that's what I'm really
using it for more than anything else is
for linting my Tailwind class order and
I wanted to find a setup where I could
get the official Tailwind this is how to
order them I wanted it in idees I wanted
it in the command line I wanted it in
cicd I wanted it everywhere and I found
that this is the ideal setup for it so
just we're going to walk through the
steps here and it's going to talk
through exactly how to get that
done so as we read through it's going to
show us the dependencies we need to
install with mpm uh there's a file
called prettier RC that we need to
install that is basically a
configuration file uh so as soon as we
run that um I've got my options here or
my examples here and here's the main
example I'd recommend that you use but
of course you configure it however you
want and then there's a prettier ignore
file that's a little bit like G ignore
um it's instructions about how to use
the package and
unsurprisingly uh there's also some
information here about what it looks
like for you to run it
automatically uh with Husky as one
option uh hooks into vs code is another
option and in GitHub actions just like
we used for the other project so for the
project they're working on right now we
did the installation and now we need to
set up our pretty RC file so let's get
started there all right so we're going
to paste in the sample pretty r r C
configuration file and you can learn
more about it in my article or their
docs but you can see we're preferring
around 120 character wide column and
we're setting some specifications of how
we want to handle quotes and tabs and
commas and all that kind of stuff so we
also need to add a prettier ignore file
uh you can grab this and use it it's the
best one I put together but I'm not an
expert so if you are a prettier expert
uh use your own and ignore mine butum
Ching so now we're going to set it up
with Husky locally
um as you can see we're using lint
staged uh just like we did for duster um
and there's an example here that looks
exactly you know not exactly but very
similar to the one did for duster um I
did mention I should probably tweak this
to only run on files and the Resources
directory so if you are a you know lint
stage Guru feel free to tweak this for
your own but for now we're just going to
copy this edit our lint stage config
file and we're just going to paste it in
directly below um as you can see this
one's shaped like an array but the new
one is just a direct string so I got to
kind to put them next to each other with
a little bit different
syntax so now we're going to go and
we're also going to set it up in GitHub
actions and as you can see there's two
options it's the format your code option
or it is the lint your code and fail if
it fails option just like we had with
duster uh for this project once again
we're going to choose the one that says
format your code and so let's check out
that
tutorial so let's look through they've
got some sample code here that we can
use and we're just going to find the
ultimate sample GitHub action and copy
it now if you're not familiar uh GitHub
actions live in the GitHub slw workflows
directory and every file in there is a
specific workflow so we already have the
duster one here as you can see it's
defining basically when certain
behaviors happen take certain steps and
this is all for duster so what we need
to do is make one now for prettier as
well and we will name that one
prettier
right we'll paste in what we
copied as you can see it just says check
out the code and then it's going to run
this npm run format and I actually
showed in my blog post how to do this
npm run format it's something you add to
the script section of your package.json
file and it's a shortcut basically to
run all of this code
here if you're a l developer you're
familiar with you know the dev npm run
Dev or npm run build so we're just going
to add a new shortcut of our own
here so let's grab it from there and
paste it in so the one thing that you
might notice here is that this is going
to end up with this format command
running and when it runs in continuous
integration we're going to end up with a
lot of extra commits and that's one of
the reasons why we use continuous
integration as a fallback not as the
primary place with is happening because
remember we've got husky on our local
machine uh actually running it long
before it actually hits this continuous
integration um and handling those things
we have less commits and then you can
also install it in your IDE if you want
and having it in your IDE means less
commits and so this is just one piece of
a larger puzzle and you don't have to do
any of the pieces I would recommend you
at bare minimum choose a code style and
apply it across your code Basin whatever
way makes you comfortable you don't have
to use these particular tools or these
particular moments of integration I just
wanted to show you that these are the
ones that I really like right now
all right let's take a breath we're done
with all the code styling and formatting
things we have a few more steps to take
to get our local development environment
up and running so that we have all the
dependencies we need and we are going to
be ready to build this app uh for the
rest of this uh video series so there
were a few other dependencies we want to
take a look at making sure we have an
order and the first one would be a
database but because we chose to use
sqlite for this particular project we're
good we don't need any dependencies
there if we did I would highly recommend
DB engine which is a free tool for
setting up MySQL and other things like
that on your Mac so let's talk now about
mail I use a tool called mail pit which
allows you to uh basically send mail to
a local server and it gives you a mock
uh email inbox that you can use to click
around things there's a couple different
ways to install it I used Homebrew but
you can also use larl or Titans takeout
uh which is a Docker based tool if you
don't have Homebrew or you don't want to
use Homebrew um either way I recommend
setting up some way for you to be able
to click through an Emil inbox you could
just use laravel's log feature for your
mail but I highly recommend something
that lets you view and click on your
actual emails and mail pits a really
great way to set that up that's it for
mail and for any other dependencies that
we're going to need to deal with they're
either going to work by default because
larl has reasonable local drivers or
we're going to set them up in the
particular video so let's take a look
and make sure our database is actually
working we're going to hit PHP Artisan
migrate and it says nothing to migrate
which means we got a database up and
running and it's actually migrated uh
because we're using sqlite it's going to
be in the database SL database.sql file
we can actually open up that file and
see that there's it's a file that just
has content there but it's not content
we can actually understand or see uh
here's what's interesting though is the
full data of the application is just in
that file so if we delete that file and
we create a new one we now have what's
effectively an empty unmigrated database
so we can run php's as migrate and now
the database migrations will run just
fine so let's take a look at our tests
now make sure they all pass and they all
pass and yeah at this point we've got a
functioning database we got functioning
tests we got our mail working and all
the other dependencies we need to think
about again we're going to deal with in
future videos all right so you've done
it we have a local functioning layal app
up in the browser
linting uh mail dependency database
dependency uh it's everything you need
to basically get started working so
that's what we're going to do next time
asterisk we also want to make sure we've
got it up and running in a staging
environment so the next time is actually
going to be that and then we'll be ready
to work so for now get add get commit
push it up to GitHub if you want and
I'll see you again next time
