The Complete Laravel Developer Toolchain for 2026
Every six months or so I get the same question from developers joining my teams or reaching out after a talk: "What does your full stack look like?" I used to answer it ad-hoc. Now I'm writing it down properly because the ecosystem has shifted enough in 2025–2026 that a lot of older guides are actively misleading people.
This is my current, opinionated, production-tested toolchain for Laravel 12 projects. I'll explain the reasoning behind each choice — including the alternatives I considered and why I passed on them.
What you'll learn
- How to choose between Laravel Sail, Herd, and Valet for local development and when each one actually makes sense
- Which IDE setup gives you the best Laravel developer experience without overpaying
- How to automate code quality with Pint, Larastan, and Rector so problems never reach production
- How to run your full Pest test suite in parallel and cut CI times by 70%
- How to debug effectively with Ray and Telescope instead of
dd()and prayer - How to deploy confidently using Forge, Envoyer, or the newer Laravel Cloud
Why your local environment choice matters more than you think
Most Laravel guides treat local environment setup as a five-minute throwaway section. It isn't. The environment you choose affects onboarding time for new teammates, how quickly you debug infrastructure issues, and whether "it works on my machine" stays in your vocabulary.
In 2026 there are three realistic options: Laravel Sail, Laravel Herd, and Laravel Valet. Homestead is legacy — move on.
Local development: Sail, Herd, or Valet
Laravel Sail
Sail is Docker under the hood, wrapped in a friendly CLI. New Laravel 12 projects ship with it by default, and for team projects it is still a great recommendation.
# New project includes Sail out of the box
laravel new my-project
cd my-project
# Start the environment
./vendor/bin/sail up -d
# Run artisan through Sail
./vendor/bin/sail artisan migrate
# Open a shell in the container
./vendor/bin/sail shell
The real value of Sail is reproducibility. When you commit a docker-compose.yml to the repo, every developer on the team — on any OS — gets identical PHP versions, the same MySQL configuration, the same Redis instance. That consistency pays for itself within weeks on a team project.
The honest downside is resource usage. On macOS with Docker Desktop, Sail consumes 2–4GB of RAM and noticeably impacts battery. For solo work on a MacBook, it can feel sluggish compared to native alternatives. On Linux, Docker runs natively and the performance gap disappears.
Use Sail when: you're working on a team, your project has non-standard service dependencies (custom MySQL configs, Meilisearch, MinIO), or you need Windows compatibility.
Laravel Herd
Herd on macOS runs PHP natively — no Docker, no VM, just binaries. It installs in minutes, uses around 100MB of RAM, and makes PHP version switching instant.
# After installing Herd from herd.laravel.com
# Sites in ~/Herd/ are automatically served
herd php --version # Check active PHP version
herd use 8.4 # Switch PHP version instantly
The Herd Pro tier ($99/year) adds a local mail viewer, an integrated log viewer with IDE jump links, and a dedicated dumps viewer that catches dump() output outside the browser. On a MacBook used for solo client work, Herd Pro pays for itself in time saved.
My answer when someone asks which I'd choose is always Herd. The simplicity and speed make it a no-brainer — no Docker daemon to babysit, no RAM overhead, PHP version switching in a single command. For everything I build, Herd is the default and I haven't looked back.
Use Herd when: you work solo or on a fully Mac team, you value low resource overhead, and you want the tightest Laravel Forge integration.
Laravel Valet
Valet is the original lightweight macOS solution and it still works. But Herd has superseded it with a better UI, faster setup, and PHP version management that Valet requires external tools to match. Unless you have an existing Valet setup you're happy with, there's no reason to reach for Valet on a new project in 2026.
IDE setup
PHPStorm
PHPStorm remains the highest-ceiling choice for Laravel development. Route-to-controller navigation, Eloquent model completion, Blade component validation, migration-aware column suggestions — the deep framework understanding justifies the $69–$199 per year.
The setup I run:
- Laravel Idea plugin (free) — adds advanced Blade validation, view resolution, and translation completion on top of PHPStorm's built-in Laravel support
- Database tools panel connected to the project's MySQL instance so I can query without switching to TablePlus
- PHPUnit/Pest integration configured to run the current test file with
⌘⇧T
PHPStorm's refactoring tools are where it genuinely pulls ahead. Renaming a method cascades correctly through routes, Blade templates, and test files. That's worth real money on a large codebase.
VS Code
VS Code is a perfectly capable Laravel environment and costs nothing. If budget is a constraint or you work across multiple languages in the same repo, it's a strong choice.
The minimum extension set that makes VS Code feel like a first-class Laravel IDE:
- PHP Intelephense (freemium) — the language server that powers completion, diagnostics, and go-to-definition
- Laravel Extension Pack — bundles Blade syntax, route navigation, Artisan commands, and a handful of other quality-of-life extensions
- Thunder Client or the built-in REST client for API testing
The gap versus PHPStorm is most visible in Blade: VS Code's Blade support requires more manual configuration and occasionally misses component completions that PHPStorm catches automatically.
Zed
Zed is worth a mention in 2026. Built in Rust, it is noticeably faster than both PHPStorm and VS Code, particularly on large projects with many open files. The Laravel community extension (croustibat/zed-for-laravel) adds 130+ snippets, Pint format-on-save, and Blade syntax support.
I don't use Zed as my primary editor yet — the PHP language server integration is less mature than Intelephense in VS Code — but I watch it closely. If you're on an M-series MacBook and feel frustrated by VS Code's memory usage, it's worth trying.
Code quality tools
This is the section most teams skip until they regret it. Automated code quality enforcement is not bureaucracy — it's the difference between pull request reviews that discuss architecture and pull request reviews that discuss whether to use single quotes or double quotes.
Laravel Pint
Pint is Laravel's official PHP code formatter, built on PHP-CS-Fixer. It ships in every new Laravel 12 project. If you're on an older project:
composer require laravel/pint --dev
Run it:
# Format all files
./vendor/bin/pint
# Check without modifying (for CI)
./vendor/bin/pint --test
# Only format files with uncommitted changes
./vendor/bin/pint --dirty
The default laravel preset is opinionated and I lean into it rather than fighting it. If you need to override specific rules, a pint.json in the project root handles it:
{
"preset": "laravel",
"rules": {
"simplified_null_return": true,
"new_with_parentheses": {
"anonymous_class": true,
"named_class": true
}
}
}
The --dirty flag is the one I use during active development — it only processes files I've modified, so feedback is nearly instant on large codebases.
Larastan
Larastan wraps PHPStan with Laravel-specific knowledge — it understands Eloquent magic, facades, relationships, and service container bindings that would otherwise generate false positives.
composer require --dev "larastan/larastan:^3.0"
Minimal phpstan.neon:
includes:
- vendor/larastan/larastan/extension.neon
parameters:
paths:
- app/
level: 10
I install Larastan at level 10 from day one on every new project — maximum strictness, no exceptions. The upfront cost of writing properly typed code is real, but it pays back tenfold over a project's lifetime. Bugs that would only surface at runtime get caught at the command line. Refactors that would silently break things get flagged immediately. Once you build with level 10 from the start, dropping down to level 5 feels like flying without a seatbelt.
For legacy codebases, start with --generate-baseline to capture the existing violations and fix them incrementally — don't try to jump to level 10 overnight:
# Analyse the codebase
./vendor/bin/phpstan analyse
# Generate a baseline for existing violations (legacy projects)
./vendor/bin/phpstan analyse --generate-baseline
# Run with increased memory limit on large codebases
./vendor/bin/phpstan analyse --memory-limit=2G
If you're joining a project mid-flight and suggesting Larastan for the first time, start at level 3 to get buy-in, then raise the level in each sprint until you reach where it needs to be.
Rector
Rector is the tool most Laravel developers haven't tried but should. It performs automated code refactoring — upgrading deprecated syntax, modernising patterns, and preparing codebases for the next Laravel version.
composer require --dev rector/rector
A practical example: Rector can automatically convert every string controller reference in your routes file to the typed class syntax:
// Before
Route::get('/users', 'UserController@index');
// After (automatically applied by Rector)
Route::get('/users', [UserController::class, 'index']);
Run it in dry-run first to preview changes:
./vendor/bin/rector process app/ --dry-run
./vendor/bin/rector process app/ # Apply changes
I typically run Rector before a Laravel version upgrade to catch and fix deprecations automatically, rather than hunting through changelogs manually.
Testing with Pest
Pest is now the default testing framework recommendation in the Laravel ecosystem, and version 3 makes it even harder to argue against. The expressive syntax reduces the cognitive overhead of reading test files, and the built-in parallelisation is a significant CI time saver.
Installation and basic setup
composer require pestphp/pest --dev
composer require pestphp/pest-plugin-laravel --dev
./vendor/bin/pest --init
A basic feature test in Pest for Laravel:
it('creates a new user', function () {
$response = $this->postJson('/api/users', [
'name' => 'Steven Richardson',
'email' => '[email protected]',
'password' => 'secret',
]);
$response->assertStatus(201);
$this->assertDatabaseHas('users', ['email' => '[email protected]']);
});
Pest's expect() API makes assertions read naturally:
expect($user->isAdmin())->toBeFalse();
expect($response->json('data'))->toHaveCount(3);
expect($user->created_at)->toBeBefore(now());
Parallel testing
The biggest practical improvement in Pest 3 is that parallel testing is a single flag:
./vendor/bin/pest --parallel
On a project with a few hundred tests, this typically cuts execution time by 60–75%. On my current project (417 tests), sequential takes 43 seconds; parallel drops it to 11 seconds.
The important caveat: parallel testing with a real database requires that each process has its own database to avoid race conditions. Laravel handles this automatically when you use SQLite in-memory for testing:
// phpunit.xml
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
If you need a real MySQL database in tests (for JSON columns, full-text search, etc.), you'll need Laravel's parallel testing hooks to create per-process databases:
// AppServiceProvider or a TestCase
use Illuminate\Support\Facades\ParallelTesting;
ParallelTesting::setUpTestDatabase(function (string $database, int $token) {
Artisan::call('migrate', ['--database' => $database]);
});
Architecture testing
Pest 3's architecture testing is underused. It lets you encode structural rules about your codebase and have them fail loudly when violated:
arch('controllers should not use models directly')
->expect('App\Http\Controllers')
->not->toUse('App\Models');
arch('all commands should be invokable')
->expect('App\Console\Commands')
->toImplement(ShouldQueue::class);
These tests run in milliseconds and catch architectural drift early. I add them to new projects from day one.
Database tooling and debugging
Laravel Telescope
Telescope is Laravel's local debugging assistant and it's excellent at its intended purpose: giving you a real-time view of everything happening in your application during development.
php artisan telescope:install
php artisan migrate
Visit /telescope in your browser and you get a live feed of requests, queries, jobs, mail, notifications, and cache operations. When a page loads slowly, Telescope's query panel tells you immediately whether you have an N+1 problem and exactly which query is being repeated.
One important configuration: keep Telescope local-only. In production it writes every request to your database. The config/telescope.php enabled gate handles this:
'enabled' => env('TELESCOPE_ENABLED', false),
Ray by Spatie
Ray is my day-to-day debugging tool and the one I reach for before dd(). It sends debugging output to a desktop app where you can filter, colour-code, and inspect data without interrupting the HTTP response.
composer require spatie/laravel-ray
Install the Ray desktop app from myray.app, then use it anywhere in your code:
ray($user); // Inspect a variable
ray($query->toSql(), $query->getBindings()); // Debug a query
ray()->measure(); // Start a stopwatch
// ... some slow operation
ray()->measure(); // Stop and display elapsed time
ray($data)->if($debug)->send(); // Conditional — only sends in debug mode
The ->if() conditional is underrated. You can leave Ray calls in your code with a $debug flag and they're silent in production-like environments.
Ray has a free trial (20 messages per session) and a one-time license for unlimited use. For the amount of time it saves compared to dd() debugging, the license pays for itself quickly.
TablePlus
For database work outside the application, TablePlus is the GUI I use. It connects to MySQL, PostgreSQL, SQLite, and Redis, has a clean interface, and imports/exports cleanly. Not free, but well worth it for the time saved versus using a terminal client for everything.
CI/CD pipeline
The goal of CI is simple: catch broken code before it reaches production. Here's the GitHub Actions workflow I use on new Laravel projects — it runs Pint, Larastan, and Pest in parallel across PHP 8.3 and 8.4:
name: CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
php: [8.3, 8.4]
steps:
- uses: actions/checkout@v4
- name: Set up PHP ${{ matrix.php }}
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: mbstring, pdo_sqlite
coverage: none
- name: Install dependencies
run: composer install --no-interaction --prefer-dist --optimize-autoloader
- name: Check code style
run: ./vendor/bin/pint --test
- name: Run static analysis
run: ./vendor/bin/phpstan analyse --memory-limit=2G
- name: Run tests
run: ./vendor/bin/pest --parallel
env:
DB_CONNECTION: sqlite
DB_DATABASE: ":memory:"
The Makefile I add to every project wraps these commands for local use:
.PHONY: test lint analyse fresh
test:
./vendor/bin/pest --parallel
lint:
./vendor/bin/pint
analyse:
./vendor/bin/phpstan analyse
ci: lint analyse test
fresh:
php artisan migrate:fresh --seed
migrate:
php artisan migrate
Running make ci locally before pushing means CI almost never surprises me.
Deployment
Laravel Forge + Envoyer
Forge handles server provisioning: it creates your VPS on DigitalOcean, AWS, or Linode, installs Nginx, PHP, MySQL, and Redis, and configures SSL via Let's Encrypt. Envoyer handles zero-downtime deployments — it deploys to a new release directory and only flips the symlink when everything is healthy.
The combination is $12/month for Forge plus $20/month for Envoyer. For a consultancy managing multiple client sites, this is the reliable default. You control the infrastructure, deployments are fast and repeatable, and the Forge UI surfaces server health without you needing to SSH in for routine checks.
The Herd desktop app also includes a direct "Deploy to Forge" workflow, which is convenient for solo developers who don't want to context-switch to a browser.
Laravel Cloud
Laravel Cloud is the official fully-managed PaaS, launched in February 2025. You push code, Cloud handles the rest — provisioning, scaling, SSL, queues, scheduled tasks. There's a free sandbox tier for prototyping.
I've migrated a handful of client projects to Cloud (clients under NDA, so I can't name them) and the operational simplicity is real. There's no server to patch, no Nginx configuration to debug, no scale events to anticipate manually. The feedback from those teams has been consistent: they spend less time thinking about infrastructure and more time shipping features, which is exactly the point.
The trade-off is control. You can't customise the PHP build, you can't install arbitrary system packages, and pricing scales with usage in ways that need careful modelling before committing a high-traffic application.
My rule of thumb: new projects for non-technical clients who need low maintenance overhead go on Cloud. Projects with custom infrastructure needs, compliance requirements, or traffic patterns that would make Cloud expensive go on Forge.
Laravel Vapor
Vapor deploys your application as Lambda functions on AWS, giving you true serverless auto-scaling. If you're building something with genuinely unpredictable traffic spikes — a product that might get Hacker News'd or has seasonal peaks that are 50x normal load — Vapor is worth the learning curve. For steady-traffic applications, the Lambda cold-start latency and added complexity rarely justify it.
Monitoring
Laravel Nightwatch
Nightwatch launched at Laracon EU 2025 and is the first first-party Laravel APM. It tracks HTTP requests, database queries, queued jobs, scheduled commands, cache operations, and outgoing HTTP requests — the full application lifecycle, not just exceptions.
The integration is a single package install, and it surfaces data in a Laravel-native dashboard rather than requiring you to learn a third-party tool's data model.
I run Nightwatch on every production application now. When a client reports that "the dashboard feels slow," Nightwatch shows me in 30 seconds whether the problem is a slow database query, a queued job backing up, or an external API call taking too long.
Sentry
Nightwatch and Sentry serve different purposes and I run both. Sentry's strength is exception tracking and user impact reporting — it tells you how many users hit a specific error and gives you the full stack trace with breadcrumbs. Nightwatch gives you the performance picture. They complement each other well.
Productivity: Makefiles and dotfiles
Two things that cost an hour to set up and save hours every week.
Makefiles give your team a shared vocabulary of common commands. New developer runs make fresh to get a clean database with seed data. They run make ci before a PR. They run make test during TDD. The commands are documented in the repo and work identically regardless of whether someone uses Sail, Herd, or Valet.
Dotfiles keep your environment consistent across machines. Shell aliases, Git configuration, editor settings — if you switch laptops or set up a new machine, dotfiles mean you're productive again in 30 minutes instead of 3 days.
Advanced patterns and edge cases
PHP version management at the project level. If you work across multiple projects with different PHP requirements, Herd's instant switching covers you on macOS. On Linux or in CI, use shivammathur/setup-php in GitHub Actions with a matrix strategy to test across multiple PHP versions simultaneously (as shown in the CI workflow above).
Rector in CI. I don't auto-apply Rector in CI — instead, I run it as a dry-run check and fail the build if there are outstanding modernisation opportunities. This forces code to stay current rather than letting deprecations accumulate:
- name: Check for code modernisation
run: ./vendor/bin/rector process app/ --dry-run --no-progress
Larastan on package development. If you maintain a Laravel package, level 10 is non-negotiable. Package code is called by others with no safety net — every type error you miss becomes someone else's production bug.
Telescope in staging environments. Telescope is typically kept local-only, but running it in a staging environment (behind authentication) is genuinely useful for QA. It gives testers a window into what the application is doing without them needing developer access.
Testing this
The toolchain itself should be tested the same way you test code — with a repeatable process, not a mental checklist.
After setting up a new project, I verify the following before the first team commit:
# Verify all tools installed and functional
./vendor/bin/pest --version
./vendor/bin/pint --version
./vendor/bin/phpstan --version
./vendor/bin/rector --version
# Run CI suite locally — should all pass on a fresh project
make ci
# Verify parallel testing works
./vendor/bin/pest --parallel --processes=4
# Verify Pint applies the correct preset
./vendor/bin/pint --test
If any of these fail on a fresh project, fix it before the first feature branch. Retrofitting tooling onto an active codebase is significantly more friction than including it from the start.
Common mistakes
Running Pint without --test in CI. Pint's default behaviour is to reformat files in place. In a CI environment without auto-commit, this silently passes when it should fail. Always use ./vendor/bin/pint --test in CI pipelines.
Starting Larastan at level 0 "just to get it running." Level 0 analysis finds almost nothing useful and gives you a false sense of coverage. Start at level 10 on new projects. For legacy codebases, generate a baseline and start at level 3, then work upward — but always have a target of 10 on the roadmap.
Using php artisan test --parallel instead of Pest's parallel flag. Laravel's built-in parallel test command works, but Pest's --parallel flag is faster and provides better output. If you've installed Pest, use ./vendor/bin/pest --parallel instead.
Mixing Sail and Herd on the same team. Some developers run Herd on their MacBooks, some run Sail. This leads to PHP version drift, different service configurations, and "it works on my machine" problems. Pick one and document it in the project README.
Leaving Ray calls in production code. The spatie/laravel-ray package no-ops gracefully when the Ray desktop app isn't running, but leaving ray() calls in committed code is messy. Add a pre-commit hook or a CI check that fails if ray( appears in committed PHP files:
- name: Check for leftover debug calls
run: |
if grep -rn "ray(" app/ --include="*.php" | grep -v "//"; then
echo "Found ray() calls in code"
exit 1
fi
Wrapping up
The toolchain above is not the only valid configuration — it's the one I reach for on new projects because it balances developer experience, code quality enforcement, and operational simplicity. Sail for team consistency, PHPStorm or VS Code with proper extensions, Pint + Larastan + Rector for code quality, Pest with parallelisation for testing, Ray and Telescope for debugging, and Forge or Cloud for deployment depending on the project's needs.
The common thread across all of these choices is automation. The best tooling is the kind you configure once and then don't think about — style is enforced automatically, type errors are caught before review, tests run in parallel without manual setup, and deployments happen via a single push. Every hour spent configuring this toolchain correctly at project start saves ten hours of manual work later.
FAQ
What tools do Laravel developers use?
The modern Laravel stack in 2026 centres on a few core tools: Laravel Sail or Herd for local development, PHPStorm or VS Code as the IDE, Laravel Pint for code formatting, Larastan for static analysis, and Pest for testing. For deployment, Laravel Forge remains the most widely used server management tool, with Laravel Cloud growing quickly for teams that prefer a fully managed approach. Ray by Spatie and Laravel Telescope are the standard debugging tools during development.
What is the best IDE for Laravel development?
PHPStorm is the highest-ceiling option — its built-in Laravel intelligence (route navigation, Eloquent completion, Blade validation) is unmatched, and the Laravel Idea plugin extends it further. VS Code with PHP Intelephense and the Laravel Extension Pack covers 90% of PHPStorm's functionality for free and is the right choice if cost is a factor or you work across multiple languages. Zed is a fast-rising alternative worth watching, particularly for developers who prioritise editor performance on large codebases.
How do I set up a Laravel development environment?
On macOS, install Laravel Herd from herd.laravel.com for the quickest path to a running project — it handles PHP installation, Nginx configuration, and SSL certificates automatically. For team projects or cross-platform development, use Laravel Sail: install Docker Desktop, create a new Laravel project with laravel new my-project, and run ./vendor/bin/sail up -d to start all services. Sail provides a consistent, reproducible environment that works identically on Mac, Linux, and Windows.
What testing framework does Laravel use?
Laravel ships with PHPUnit configured out of the box, but the community has largely moved to Pest as the preferred testing framework. Pest is built on top of PHPUnit but offers a more expressive API, built-in parallel test execution, architecture testing, and mutation testing. Install it with composer require pestphp/pest pestphp/pest-plugin-laravel --dev. You can run PHPUnit tests and Pest tests in the same project during a migration.
How do I deploy a Laravel application?
The most common approach is Laravel Forge for server provisioning (it creates and configures your VPS on DigitalOcean, AWS, or Linode) combined with zero-downtime deployments via Envoyer or Forge's built-in deployment feature. Laravel Cloud is the simpler alternative — push your code and it handles provisioning, scaling, and infrastructure automatically. For high-scale serverless deployments on AWS, Laravel Vapor wraps your application in Lambda functions for true auto-scaling. The right choice depends on how much infrastructure control you need versus how much operational overhead you want to avoid.
What is Laravel Sail?
Laravel Sail is Laravel's official Docker-based local development environment. It provides a sail CLI that wraps Docker Compose commands, making it straightforward to run your application inside containers without deep Docker knowledge. Sail includes pre-configured containers for PHP, MySQL, PostgreSQL, Redis, Meilisearch, and several other services commonly used in Laravel projects. It ensures all developers on a team use identical environments regardless of their operating system, which eliminates the "works on my machine" class of problems.
Steven is a software engineer with a passion for building scalable web applications. He enjoys sharing his knowledge through articles and tutorials.