My CLAUDE.md Setup for Laravel Projects (With Real Examples)
A detailed walkthrough of my actual CLAUDE.md configuration for Laravel projects — global settings, project-level rules, and the sections that make the biggest difference.
I've been using Claude Code daily for months now. Early on, my interactions were fine but generic — Claude would give me textbook Laravel answers that missed how I actually work. It would spell out full commands I have aliases for, suggest patterns that didn't match my project's conventions, and ignore the tooling I'd already set up.
The fix was CLAUDE.md. Once I configured it properly, Claude stopped being a generic Laravel assistant and started working like a developer who actually knows my codebase. The difference is night and day.
This is a walkthrough of my actual configuration — the global file, the project-level file, and the specific sections that made the biggest impact.
Two Levels of Configuration
Claude Code reads CLAUDE.md files from two locations:
- Global —
~/.claude/CLAUDE.mdapplies to every project and every session - Project —
CLAUDE.mdin your project root applies only to that project
Global handles your personal environment — your tools, your shell, your preferences. Project handles everything specific to the codebase — architecture decisions, conventions, deployment, commands.
Both load automatically. No import statements, no config flags. Just drop the files in place and Claude reads them.
My Global CLAUDE.md
This is ~/.claude/CLAUDE.md. It's short on purpose — under 20 lines. Everything here applies regardless of what project I'm working on.
# Stu Mason - Dev Environment
## Stack
PHP (Laravel/Herd) | Node (nvm) | Python (pyenv) | Editor: VS Code
## Shell Aliases
`ga` git add | `gc` checkout | `nah` reset hard | `gamend` amend | `fuckit` WIP push
`art` php artisan | `master`/`main`/`develop` checkout+pull
`sso-devops` AWS login | `ecr-login` Docker ECR | `sam-build` SAM
## Tools ~/Code/tools/
`./hue recording|nightlights|daylights|off` | `make invoice` | `make review URL=<yt>`
## Prefs
Concise. Use existing aliases. Minimal changes. Don't over-engineer.
Why the Stack Line Matters
Declaring PHP (Laravel/Herd) up front means Claude never suggests Docker-based setups, never asks if I'm using Valet vs Sail, and never recommends php -S for local development. It knows I'm on Herd. That saves time on every single interaction.
Same with Node (nvm) — Claude uses nvm use instead of assuming a global Node installation.
Shell Aliases Are the Secret Weapon
This section changed how Claude generates commands for me. Before adding it, Claude would suggest:
php artisan make:model Post -mfc
git checkout -b feature/new-thing
git add . && git commit --amend --no-edit
After adding aliases:
art make:model Post -mfc
gc -b feature/new-thing
gamend
It's a small thing, but when you're reading dozens of commands per session, shorter is better. Claude uses the aliases naturally in its suggestions because I told it they exist.
The Preferences Line
Concise. Use existing aliases. Minimal changes. Don't over-engineer.
Four instructions, massive impact. Without this, Claude tends toward verbose explanations, comprehensive refactors, and architecturally impressive but unnecessarily complex solutions. With it, Claude gives me what I asked for and stops. No unsolicited redesigns. No paragraph-long explanations of things I already understand.
My Project CLAUDE.md
This is where the real value lives. Here's my project-level CLAUDE.md for a Laravel 12 + Inertia v2 + React 19 application, broken down section by section.
Git Flow Rules
## Development Workflow
### Git Flow
Never commit directly to main. Always:
1. Create a feature branch (`feature/phase-x-description`)
2. Do the work
3. PR
4. Review
5. Merge
This prevents Claude from ever running git commit on main. Before I added this, Claude would happily commit directly to whatever branch was checked out. Now it refuses and reminds me to create a feature branch first.
Deployment Context
### Deployment
Pushing/merging to `main` automatically triggers a deployment to production via Coolify webhook. No need to manually trigger deploys.
This one line gives Claude critical context. It knows that pushing to main isn't just a git operation — it's a production deployment. So when I ask Claude to help with a merge or push, it treats main with the appropriate level of caution. It warns me. It double-checks.
Without this line, Claude has no idea what your deployment pipeline looks like. With it, Claude becomes deployment-aware.
Working in Slices
### Working in Slices
Work in small, isolated vertical slices. One feature at a time, fully working and tested before moving on.
- Each slice = branch, PR, review, merge
- No half-baked migrations or models sitting around
- Test everything before moving to the next feature
- Keep the PRD todo updated as work progresses
This shapes how Claude approaches larger tasks. When I ask for a feature that involves a model, migration, controller, page, and tests, Claude doesn't try to build everything at once. It works through it methodically — one piece at a time, tested before moving to the next.
Generator Commands
## Generator Commands
Use these commands instead of writing boilerplate manually:
php artisan make:action User/UpdateProfile
php artisan make:action Order/ApproveOrder
php artisan make:dto UserProfile --properties=id:int,name:string,email:string
php artisan make:dto OrderData --properties=id:int,total:int,status:string --model=Order
php artisan types:generate
This is one of the highest-value sections. My project uses custom Action and DTO classes with artisan generators I've built. Without this section, Claude would create action classes by hand with whatever structure it thinks is right. With it, Claude runs art make:action and gets the exact boilerplate my project expects.
The types:generate command is equally important — it tells Claude that after creating or modifying DTOs, it needs to regenerate TypeScript interfaces. Claude remembers to run this because the docs say to.
Test Commands
## Running Tests
Use this command to run tests (avoids environment variable conflicts):
env -u APP_ENV -u DB_CONNECTION -u DB_DATABASE -u DB_HOST -u DB_PORT -u DB_USERNAME -u DB_PASSWORD -u SESSION_DRIVER -u CACHE_STORE -u QUEUE_CONNECTION php artisan test
This is project-specific and non-obvious. My local environment has shell variables that conflict with the test environment. The env -u flags unset them before running tests. Without this in CLAUDE.md, every test run Claude triggers would fail with database connection errors, and Claude would spend time debugging a problem that isn't a problem — it's just environment config.
Coding Standards References
## Coding Standards
Before writing any code, review the coding standards in `docs/standards/`:
- general.md - Core principles, type hints, imports
- backend.md - Laravel patterns: models, migrations, controllers, Actions, DTOs
- frontend.md - Inertia + React + Tailwind patterns
- testing.md - Pest v4 testing patterns
I maintain a docs/standards/ directory with detailed coding conventions. Pointing Claude to these files means it reads them before writing code. The result: Claude's output matches my project's style from the first attempt instead of requiring multiple rounds of corrections.
The Third Layer: Laravel Boost
There's a third piece that dramatically improves Claude's Laravel knowledge, and it's the one most people underestimate. Laravel Boost is an official MCP server built by the Laravel maintainers. It does two distinct things: it gives Claude tools to interact with your running application, and it auto-generates guidelines that get injected into your CLAUDE.md.
Installing Boost
composer require laravel/boost --dev
php artisan boost:install
The install command generates your .mcp.json, injects guidelines into CLAUDE.md, creates agent skill files in .ai/skills/, and sets up a boost.json config. You can add the generated files to .gitignore — they regenerate automatically.
The MCP Tools
Boost gives Claude 15 tools for interacting with your actual application:
| Tool | What It Does |
|---|---|
| Database Query | Execute read queries against your database |
| Database Schema | Inspect your table structures |
| Database Connections | Check available database connections |
| Search Docs | Query 17,000+ pieces of version-specific Laravel documentation |
| Tinker | Execute PHP in your application context |
| List Artisan Commands | Inspect available artisan commands with arguments |
| List Routes | Inspect application routes with middleware |
| Application Info | Read PHP/Laravel versions, packages, Eloquent models |
| Get Config | Read configuration values using dot notation |
| List Available Config Keys | Discover all config keys |
| List Available Env Vars | Discover all environment variable keys |
| Read Log Entries | Read the last N entries from your application log |
| Last Error | Pull the most recent error from logs |
| Browser Logs | Read browser console logs and errors |
| Get Absolute URL | Convert relative URIs to full URLs |
The Search Docs tool is the game-changer. It automatically passes your installed packages and their exact versions to a documentation API with 17,000+ indexed pieces across Laravel, Inertia, Pest, Tailwind, Livewire, Filament, Nova, and more. When Claude needs to check how deferred props work in Inertia v2, it gets back the right answer for your exact version. No hallucinated APIs. No outdated patterns.
The Database Schema and Database Query tools mean Claude can inspect your actual tables before writing migrations or queries. It stops guessing column names and starts knowing them.
Auto-Generated Guidelines
When you run boost:install, Boost scans your composer.json and package.json, detects which Laravel ecosystem packages you're using, and generates version-specific coding guidelines. These get injected directly into your CLAUDE.md.
Guidelines exist for 25+ packages including Laravel (with version-specific rules for 10.x/11.x/12.x), Inertia (React, Vue, Svelte), Pest (3.x, 4.x), Tailwind (3.x, 4.x), Livewire, Fortify, Wayfinder, Pint, and more.
The injected rules cover things like:
- Use
Model::query()instead ofDB::facades - Write Pest tests with datasets for validation rules
- Use Tailwind v4's CSS-first
@themeconfiguration instead oftailwind.config.js - Use Inertia v2's
<Form>component and deferred props - Run
vendor/bin/pint --dirtybefore committing - Use constructor property promotion in PHP 8
You don't write any of this. Boost generates it based on what's actually installed. When you update packages, run php artisan boost:update and the guidelines update too.
Agent Skills
Boost also includes on-demand skills — domain-specific knowledge that Claude loads only when relevant, keeping your context window clean. There are 14 built-in skills covering things like Livewire development, Pest testing, Tailwind CSS, Wayfinder routing, and MCP server development.
You can create custom skills too by adding SKILL.md files to .ai/skills/. I have one for my project's Action pattern that explains when and how to use make:action.
Why This Matters for CLAUDE.md
The key insight: your hand-written CLAUDE.md and Boost's auto-generated guidelines work together. You write the project-specific stuff — git flow, deployment pipeline, custom generators, test commands. Boost handles the framework-specific best practices. Neither replaces the other.
Tips That Made the Biggest Difference
Be Specific About What You Don't Want
Don't over-engineer and Minimal changes do more work than most positive instructions. Claude's default tendency is to be thorough and comprehensive. Sometimes that means refactoring three files when you asked it to change one line. Telling it what to avoid is as important as telling it what to do.
Include Real Commands, Not Just Descriptions
Don't write "use the artisan command to generate actions." Write the actual command:
php artisan make:action User/UpdateProfile
Claude is literal. If you give it the exact command, it uses the exact command. If you give it a description, it interprets — and sometimes interprets wrong.
Keep It Under 500 Lines
More isn't better. Every line of CLAUDE.md consumes context window tokens. A 1000-line CLAUDE.md eats into the space available for your actual conversation. My global file is under 20 lines. My project file is around 80 lines before Boost's additions. Be ruthless about what earns a spot.
Update It As Your Project Evolves
CLAUDE.md isn't write-once. When I add a new generator command, I add it to the file. When I change my deployment pipeline, I update the deployment section. When I notice Claude making the same mistake twice, I add a rule to prevent it. It's a living document.
Use the GitHub CLI Section
### GitHub Interactions
Always use `gh` CLI for GitHub interactions instead of web fetching:
gh pr view 123
gh pr view 123 --comments --json comments
gh issue view 123
This prevents Claude from trying to web-fetch GitHub URLs (which often fails with authentication issues) and instead uses the gh CLI that's already authenticated on your machine.
Before and After
Before CLAUDE.md: Claude gives me textbook Laravel. Full php artisan commands instead of art. Commits to whatever branch is checked out. Writes action classes by hand with its own structure. Runs tests without unsetting environment variables. Suggests Docker when I'm on Herd.
After CLAUDE.md: Claude uses my aliases. Creates feature branches. Runs my generators. Tests with the correct command. Knows that pushing to main means production. Matches my coding standards from the first attempt.
The time investment is maybe an hour to set up both files, then a few minutes here and there to keep them current. The return is every single Claude Code session being more productive, more accurate, and less frustrating.
If you're using Claude Code without CLAUDE.md, you're leaving most of its value on the table.
Get the Friday email
What I shipped this week, what I learned, one useful thing.
No spam. Unsubscribe anytime. Privacy policy.