Skip to content

nikspyratos/toybox

Repository files navigation

Toybox - A TALL SaaS starter kit

Toybox cover image


My TALL stack boilerplate for Laravel SaaS builders.

The Toybox has a bit of everything - a grand tour of the Laravel PHP world, so to speak. Let's have some fun!

Even if you don't need another boilerplate, perhaps the list of recommended services will still give you a path forward, or the scripts will give you something to work with.

This project is intended mostly for use as a solo Laravel developer who wants to rapidly develop and deploy indie SaaS projects. This is not intended for junior developers - having worked with the modern Laravel ecosystem is ideal to use this project. This is also not intended for "professional" commercial use, i.e. for freelance clients - it's intended for use by indie developer-entrepreneurs.

Principles

  • Free, both ways: There's no need to pay anything for this - I build it because I use it! You can also do whatever you'd like.
  • Self-containment: With minimal extra commands, you should be able to clone this repo and get something running.
  • Tiny but mighty: Minimising the different technologies used, using simpler & standardised alternatives to common tools.
  • Don't reinvent the wheel: Use as much of the official & unofficial Laravel ecosystem where applicable. Use popular (i.e. sustainable, gets regular updates) tools & packages where applicable instead of rewriting boilerplate logic from scratch. We're in Laravel, not JS!
  • Quality code: Strict types. Automated linting & code analysis
  • Simplified Scaling: It's cheaper to scale with load balancing & bigger servers, and with minor manual input instead of full automation.
  • Bleeding edge: Let's play around with the latest tools out there!

Support this project

Project Status - can you use this yet?

Toybox is currently stable.

Features

  • Self-initialising, self-provisioning, self-deploying project using bash scripts.
  • Admin panel with Filament, great starting point for managing your application.
  • Terms of Service and Privacy Policy derived from Basecamp
  • Security enhancements included from Securing Laravel
  • Laravel ecosystem included - auth scaffolding, websockets, performance monitoring, webserver runtime, API authentication, feature flags, social login
  • Cookie Consent banner

All of this is done while keeping package dependencies minimal outside of trusted third parties like Filament or Spatie.

There were a few more features in the past, but for the aims of the project they were removed. Check the feature-freeze-240403 branch. This will have a CMS, blog, Orbit-based documentation generation, testimonials and roadmap management.

Components

  • OS: Ubuntu 22.04 LTS
  • Webserver: FrankenPHP's Caddy, configured to run through Laravel Octane
  • Database: SQLite, optimised for performance & stability
  • Websockets: Laravel Reverb
  • Application: Laravel (duh)
  • CI/CD: Good old Bash scripts.
  • Cache, queues, etc.: For some "easy" scaling and portability with SQLite and database drivers, Cache, Queue, Pulse & Telescope have their own separate SQLite database connections. This should theoretically avoid any potential write issues if one of the databases needs more frequent writes than others, and makes the app a little more portable (e.g. you can retain your cache as easily as copying a file when moving server).

Installation/Usage

Requirements

You will need PHP 8.3 alongside some extensions (at least the Laravel defaults and intl)

A good starting point of extensions that should cover most apps is:

bcmath
ctype
curl
dba
dom
fileinfo
filter
gd
gettext
gmp
iconv
intl
libxml
mbstring
mysqli
openssl
pcntl
PDO
Phar
posix
session
soap
sockets
tokenizer
zlib

Local Development

Environment Setup

Cross-platform
macOS

Note: Favicons with Valet-hosted sites are a bit broken. To fix it, edit your /opt/homebrew/etc/nginx/valet/valet.conf using one of simensen's workarounds, or just remove the favicon & robot.text handlers entirely.

Linux
  • Valet Linux AND install PHP on your system.
  • Install your DB of choice locally, or Takeout supports both Redis and MySQL/MariaDB, so it can act as a DBNgin alternative for Linux and more.
Windows
  • Herd is an all-in-one development solution, including database, redis, and other services (if you pay for Pro).
  • WSL2 is still required, as all the scripts in bin are built for Linux/Mac.

Installing Toybox

  1. Clone/fork this repository into a new repository.
  2. Run ./bin/init_dev.sh (remember to do so from WSL2 on Windows). It will:
    • Set up pre-commit linting,
    • Replace template names,
    • Conduct Laravel boilerplate setup (package installs, key generate, migrate, etc.).
    • The script will ask you for some basic environment variables (app name, domain, database name) and edit your .env accordingly.
    • It will also ask if you would like to install Jetstream Teams, and has a custom installer (bin/init_teams.sh) it runs if yes.

Note: By default init_dev.sh assumes your production server username is ubuntu. If it is not, you need to replace ubuntu in your Caddyfile.prod, templates/octane.conf and templates/reverb.conf with the correct username, once init_dev.sh is finished.

Once the script completes, you can commit the changes to the edited files.

For details, look in bin/init_dev.sh.

The sections below outline the recommended way to work with Toybox on your local system. Please note the included Caddyfile.prod is intended for production use and Caddyfile.dev for local testing..

Laravel Octane

The default Octane config will start with one worker per core, and restart workers every 500 requests. To account for this project's dependencies and any potential leaks, Toybox's config is a bit more conservative and will restart workers every 250 requests. You can change this in templates/octane.conf.

To use Octane with Valet/Herd, you'll need to proxy your site to your octane port.

Code Quality & Analysis

Five tools have been included for this:

  • Duster (linting),
  • Larastan (static analysis),
  • PHP Insights (analysis & architecture),
  • Rector (automated refactoring),
  • Rustywind (Tailwind linting),
  • Roave security advisories (prevent insecure package installs)

There are also some default Pest tests for architecture rules as well. You may see some overlap or conflicts in recommendations by these tools - if so, please make an issue so I can adjust the config to avoid the conflict.

By default, you will already have Duster & Rustywind running as a pre-commit hook. Larastan and PHP Insights can be run individually, or as a group with the command composer run analysis. Security Advisories runs on composer operations, to prevent installation of insecure packages. Note that PHP Insights is configured to automatically fix issues it is able to fix. You may also want to look inside config/insights.php and add/change any sniffs per your preference - there are some rules that may be too strict for some users.

The commands for all the tools are:

./vendor/bin/duster fix
./vendor/bin/duster lint #Linting may catch issues that fix can't resolve
./vendor/bin/phpstan analyse
php artisan insights

For Duster, if there are any unfixable issues raised in duster fix, you can get more info on them by running duster lint. Also note that you can add the --dirty flag to only run it for files that have changed.

Some analysis steps in these tools may fail on a default Toybox installation. Where reasonable I've tried to mitigate this, but some will be left up to you as the developer. Some fixes require opinionated configurations that I don't feel Toybox should have a default on.

Next Steps - DIY

These are the next steps you will have to implement yourself for your project as your needs change & scale.

Post-Setup

  • Websockets: If you won't be using any realtime features, remove the import './echo'; line from resources/js/bootstrap.js.
  • Create an admin user: Run the php artisan app:create-admin-user command to create an admin user. This will allow you to access Filament at /admin, and Telescope at /telescope.
  • Replaces assets, texts, attributions: You will also want to take some time to remove the Toybox logo, links to the repository and replace any such mentions and authors (e.g. in the footer) with your own. This also applies to any privacy policy and terms of service pages included, as these may have stub values in place.
  • Security: Update the public/.well-known/security.txt with a contact email or URL (e.g. Twitter).
  • Landing page:
    • Make sure to change the copy on the provided pages.
    • Assuming these pages are static, make sure they are heavily cached.
    • For some projects you probably won't even need the landing page provided, so go ahead and yank it out!
  • License: If your project is closed-source, you might want to remove the LICENSE.md file included in the repo.
  • Social Logins: For each provider you plan on adding, you'll need to add the relevant credentials and configuration for both Socialite and Socialstream. If you'd like to add additional social login providers, please check out the Socialite Providers site.
  • Payments: Payments-related code is currently not included in Toybox. The main reason for this is that many users might want to support different kinds of providers or billing models. See the recommendations section below for some packages for Lemon Squeezy, Paddle, or Stripe.

Ongoing Development

Production

Provisioning

This assumes you're starting from scratch on an unmanaged Ubuntu server with an ubuntu user that has sudo access.

Note: The provision_prod.sh and deploy.sh scripts are intended for early use in your SaaS. Once you need to go beyond vertical scaling, I'd highly recommend getting started with the recommended infrastructure and deployment tools.

Your first step is to download your project repository from your VCS. Then, run ./bin/provision_prod.sh from the project directory. It will:

  • Ask you for some basic environment variables (database credentials) and edit your .env accordingly. App name, domain & database name will be used from the values in your .env (i.e. from when you ran init_dev.sh).
  • Install PHP (with service config and extensions), Caddy, and Supervisor
  • Install the Octane, queue config for Supervisor
  • Setup your app (composer & bun install, key generate, migrate, install crontab, etc.). All you need to do is modify your .env as needed.

Once this is done, update your local .env's DEPLOYMENT_PATH and Caddyfile's APP_PATH as prompted by the output. This is to enable the deploy.sh script to work and to keep your Caddyfile in line with the production version.

If you're using websockets, you will also want to manually copy the templates/reverb.conf config over for Supervisor to run reverb for you.

For more details, look in bin/provision_prod.sh.

Manual steps

Naturally, you'll also need to configure your own DNS records to point your domain to your webserver.

When your application goes live, make sure to update the last updated dates of the terms & privacy policy pages to your launch date.

Deployment

In your local project, edit the following variables to your local .env, using the appropriate values:

DEPLOYMENT_IP=
DEPLOYMENT_USER=
DEPLOYMENT_SSH_KEY=

DEPLOYMENT_PATH should already be set up from when you ran init_dev.sh. If not, please edit it to the appropriate value.

To deploy the latest application changes, run ./bin/deploy.sh. It will:

  • SSH into your server using the variables above
  • Run git pull, composer install, bun install, bun run build, and php artisan migrate.

Troubleshooting

This is where your skills come in.

Caddy having issues obtaining SSL

Make sure your firewall rules allow incoming traffic on port 443. This includes checking security settings with your hosting provider, e.g. AWS security groups.


3rd-party Services/Tools

This is a list of options, not requirements. You can likely run your SaaS perfectly fine without many of these.

This list includes both commercial options and open-source, including packages.

For more, search for awesome-laravel repos on Github, like this one.

AI (LLMs)

The community-built OpenAPI PHP SDK is robust for building AI into your applications. Sparkle is another great tool (coming soon).

Analytics

Fathom and Plausible are great options. If I had to choose: Fathom has more accessible pricing, and is made with Laravel!

For tracking user actions in your app, Spatie Activity Log is great.

API Tools

Treblle provides a great suite of tools for API observability, security, analytics and more. The Laravel SDK is here.

Backups

Cache

Laravel Response Cache is a good starting point for caching frequently accessed & frequently unchanged pages. Beyond that, Varnish is excellent and as usual there's a Spatie package for it.

CMS

Statamic has excellent integration directly into Laravel apps. The core CMS functionality (without any frontend or control panel features) is FOSS, otherwise it's free for solo usage. For advanced features in a business use case with e.g. a marketing/writing team, it's recommended to pay for Pro.

Alternatively, there are plenty of other blog/content site providers out there, e.g. Wordpress. The CMS space is too huge to make any more specific recommendations.

If you want something free & simple for creating content for your app, consider using Jigsaw - a static site generator that uses Markdown & Blade. It's free and easy to use. If hosting it with Github Pages, have a look here on how to remove build artifacts from your main branch.

Code Generation

Blueprint by the Laravel Shift team is a great addition.

Containerisation

Beyond Docker, check out Colima (macOS + Linux) and Orbstack (macOS) as alternative runtimes that will save your system resources.

Data Analysis

I highly recommend checking out Metabase for this. While it's fairly simple to make graphs/dashboards and track database metrics with Laravel/Filament, Metabase is more specialised for the task and separates concerns nicely. It can also be self-hosted!.

Debugging

If you're a dd fan, Ray is a great addition.

Deployment - CI/CD

Forge & Ploi offer deployment, but Envoyer is a great addition.

As a deployment management layer over Docker, see Kamal

Desktop

While still in alpha, NativePHP will hopefully be a very promising option if you'd like to add desktop apps to your toolkit.

For a ready-to-go desktop-based database management/admin panel for your application, Invoker is worth a look.

Documentation

For documentation within your app, see LaRecipe.

Event tracking/system notifications

I recommend LogSnag.

File Storage

Consider using any S3-compatible storage service. The ordinary local disk may be enough for your use case, but it may be prudent to separate this from your app. That way if you don't need a big server but need lots of storage, you don't have to scale your server costs unnecessarily (storage is much cheaper!).

Infrastructure

Laravel Forge and Ploi are good options (I prefer Ploi) and support many cloud providers. I lean towards AWS, but only because they have a Cape Town region.

Open source alternatives include Deployer, Eddy, and VitoDeploy

Otherwise, generalised provisioning tools like Ansible, Chef or Puppet should work.

Logging

Laravel Pail gives tail-like log tracking in your terminal, for any log driver. For application monitoring, see Uptime & Monitoring

Mail Provider

Laravel recommends Mailgun, Postmark and SES. Another option that integrates well, and works for newsletters/marketing campaigns too, is Mailcoach.

Media Library

Spatie's Media Library Pro is excellent. See below for free version details.

Mobile

Yeah, nah. Maybe some mad scientist has gotten this one right, but I'd recommend sticking to "normal" mobile tech.

Payment Provider

There are a few options here, depending on your region. For many countries, Stripe with Laravel Cashier will be fine. Otherwise, have a look at Paddle (also has a Cashier plugin) or Lemon Squeezy (Laravel package here) for a Merchant of Record.

If you're in Africa, Paystack is a solid option (affiliate signup: here).

For more options, and whether or not you need an MoR, and taxation info see here.

Security

Have a look at Securing Laravel, and packages like Treblle security headers for reference.

Search

Algolia and Meilisearch are the ones supported by Laravel Scout. Meilisearch can be self-hosted, but can be a handful to manage and would still cost a fair bit in storage/RAM requirements, so you might not save much in time & headaches over using cloud.

Serverless

Either Laravel Vapor or roll-your-own setup for free with Bref. Note: this project is untested with serverless. If you get it working with any modifications, make a PR for adding your setup or instructions!

Uptime & Monitoring

I recommend OhDear. For error monitoring, Flare is also good.

Laravel Pulse is the latest offering in the OSS Laravel suite. Note however it won't work with SQLite databases.

Upgrading Laravel & PHP

For upgrading PHP, see Rector.

For upgrading Laravel, see Laravel Shift.

User Interface

  • Filament is intended to be used for UI where possible. Consult the documentation for details.
  • Tailwind UI is a great premium resource, and includes many site templates.
  • Alpine Components is the premier Alpine component kit.
  • WireUI is a Livewire-based component kit.
  • Pines is an Alpine-based component kit.
  • Blade UI Kit is another component kit for the TALL stack.
  • Mary UI is a Tailwind component kit.

For more recommendations, see here.

Websockets

Laravel Reverb is one of the newest ecosystem additions for this exact purpose.

Soketi and Laravel Websockets are a good alternatives.

Pusher and Ably are great paid options.

All options are to be used alongside Laravel Echo. If you want to DIY, see below.


Other Tools not included

  • APIs
    • Consuming APIs: I recommend Saloon - it can be a bit overkill for small APIs, but it really helps with structuring logic with larger APIs and OAuth. I use it as the base for my Investec Banking API SDK.
    • OpenAPI/Swagger: l5-swagger is great here - must-use for writing great APIs. Otherwise, Scramble is a new entry in the scene.
    • Data Transfer Objects: Laravel Data should cover you, but if you want something simple and non-Laravel, dragon-code/simple-dto does the job without much overhead.
  • Excel Import/Export: Laravel Excel - it's a wrapper over PHPSpreadsheet, very convenient. For exports from Filament tables, there's also Filament Excel which uses Laravel Excel under the hood.
  • Manual backups: Laravel Backup (with Filament plugin). By default there is a Download Database action in the Filament dashboard to download the SQLite databases.
  • Media Management: Try out Spatie Media Library alongside Filament's plugin.
  • Alternative Eloquent Drivers: Sushi is an array driver, while Orbit is a flat file driver. These can be useful for things like CMSes, or loading data into Filament tables (which rely on the Eloquent query builder) without needing a database-driven model.
  • Fixture data: Squire adds static fixtures (e.g. airport, country code, currency, timezone) available through Eloquent.
  • Provisioning & Deployment: There are many tools here, but I'd recommend keeping it simple with one of: Docker, Ansible, or even plain Bash scripts. Otherwise, look at
  • Application settings: Spatie Laravel Settings + Filament Spatie Settings
  • Security: Consider adding Spatie's CSP package.

For more niche suggestions and general Laravel resources, check out my Laravel links page.

For more tutorials, packages and more, make sure to look at Laravel News.

Filament Plugins & Tricks

This boilerplate relies heavily on FilamentPHP for the admin panel building. This also means there are plenty of extra resources to augment either your UI or admin panel:

Design


How to scale

This package is a starting point, but as your project scales, you may need to add some more pieces to keep it stable & safe.

You can do most of what is described below with the infrastructure tools recommended.

  • Vertical scale: Put simply, for some time, it can just be easier to increase the size of your server as your resource demand grows. For Toybox, the memory & upload limits are set in public/index.php.
  • Caching & Content Delivery Network (CDN): Cache frequent application responses with the tools in the Cache section. Sign up for a service like Cloudflare or Fastly to take the edge off of some of your traffic and protect from DDoS attacks.
  • Separation of concerns: You may notice some parts of your application require more resources than others. For example, your database needs tons of storage, or your Redis instance takes a lot of RAM. In this case, it can be smarter to switch to either a managed service (e.g. RDS for managed DB, SQS for queues), or spin up a generic server specifically to use that tool.
  • Horizontal scale: Spin more servers up, and stick a load balancer in front of them. Again managed services for this exist, or you can spin up a generic server with Forge/Ploi and use that for it. Just remember to modify your scheduled tasks to only run on one server.
    • This can also be manually done with Caddy with its load balancing configuration.
    • Laravel Reverb can be scaled with Redis
    • If you stick with SQLite, one of its limitations is that it only allows one write at a time. This is fine until a certain traffic scale, but you can use something like Marmot to run multiple SQLite nodes and have them replicated to each other. Note however at this time that you would have to run migrations manually for each node as a separate connection, as Marmot doesn't replicate schema changes to other nodes.
  • Self hosting: Some non-app modules of your business might be cheaper to self-host. For example: CMS, Metabase, Websockets. Be careful with this however, as there can be some hidden catch of complexity/cost involved that can make it more attractive to go for the managed service.
  • Serverless: There are two modes of thinking with serverless: pay to make the scale problems go away, or use it for infrequent, burstable task loads that don't need to be in your main app.
  • Content: The included content pages - landing, terms/privacy policy, etc. - are intended as a starting point. As your app grows, it may make more sense to move these pages to a separate CMS rather than include them in your application.

If you need even more than that:

  • Splitting into services: You can split portions of your app into new services, and scale those servers in particular. It's the same as Separation of concerns, but for your actual codebase. Note: service doesn't have to mean microservice.
  • Auto-scaling: Here be dragons. Take time to learn the tools you need and understand them, or hire professional help. Keywords: Containerisation, orchestration. Or, YOLO and experiment with the Spatie Dynamic Servers package. If you're at the point of needing these and more, congrats! You (hopefully) have a profitable & successful startup. You need to start hiring people. If you're still using this README, you're trying to melt steel with a lighter.

Other recommendations for business operations, launching, etc.

While this isn't really within the scope of this project, I think it's still valuable to provide some starting recommendations for other entrepreneurs.

The following is a non-exhaustive, and potentially outdated list of recommendations.

For more resources, such as for launching, advertising, sales, marketing, communities, and incorporating a business, see here.

Helpdesk/Support

Honestly, using a support@example.com email address will be most of what you need.

Helpdesk systems are only really needed as you need to start building support teams and processes.

Nevertheless, some options are: Crisp.chat, GrooveHQ, HelpScout, and HelpSpace.

Live Chat

Many of the Support recommendations will already have a live chat feature. Otherwise, have a look at Tawk.to and Intercom.

Knowledgebase

While you're solo, I'd recommend one of the following:

Once you need to start having the knowledgebase available to others, Notion is my go-to. Notion also supports making public pages, so you can also have your customer knowledgebase there.

Roadmap Management

Suggest.gg

Accounting

I don't know too much in this space other than Xero.

Terms & Conditions

Contributing

These are some features that would be nice to have, but I don't intend on building yet for one reason or another:

  • FrankenPHP binary build
  • PWA support
  • Dockerfile
  • Confirmed working Windows environment solution: I don't work on Windows, and while Herd may be a first prize solution, I do want a free setup recommendation to have for Windows devs.
  • Let me know if any new file changes need to be added to the Jetstream Teams installer.
  • Convert some of the install scripts to be Prompts-based (or hybrid with Prompts)

Back to top