tightenco/tlint
Tighten’s opinionated linter for Laravel and PHP projects. Enforces consistent conventions and catches style issues using preset and custom rules, runnable via CLI or CI. Built on PHP_CodeSniffer with sensible Laravel-focused defaults.
Installation:
composer require --dev tightenco/tlint
Add to composer.json under require-dev:
"tightenco/tlint": "^9.0"
Configuration:
Create tlint.json in your project root with a basic preset:
{
"presets": ["tighten"]
}
First Run:
vendor/bin/tlint
This runs the default Tighten preset against all PHP files.
Onboarding a new developer:
Run vendor/bin/tlint to enforce Laravel conventions (e.g., facades, class ordering, Blade spacing) and auto-fix common issues with --fix.
CI/CD Hook:
Add to .github/workflows/lint.yml:
- name: Run TLint
run: vendor/bin/tlint --fix
Fail builds on violations unless --fix resolves them.
Pre-Commit Hook:
Use husky or pre-commit to run TLint on staged files:
vendor/bin/tlint --paths="app/Http/Controllers/**/*.php"
Custom Presets:
Extend the default preset in tlint.json:
{
"presets": ["tighten", "laravel"],
"linters": ["NoDump", "FullyQualifiedFacades"],
"formatters": ["ArrayParametersOverViewWith"]
}
vendor/bin/tlint --fix --only="FullyQualifiedFacades,NoDump"
vendor/bin/tlint --paths="app/Models,app/Providers"
vendor/bin/tlint --report=checkstyle > tlint-results.xml
vendor/bin/tlint as an external tool with:
Program: $ProjectFileDir$/vendor/bin/tlint
Arguments: --paths=$FilePathRelativeToProjectRoot$
False Positives:
NoDump linter flags @dd, @dump, and ray(). Exclude these in tlint.json:
{
"linters": {
"NoDump": {
"ignore": ["@dd", "@dump", "ray"]
}
}
}
OneLineBetweenClassVisibilityChanges may fail with docblocks. Use --fix to resolve.Performance:
vendor/, storage/) in tlint.json:
{
"paths": ["app/", "config/", "routes/"]
}
vendor/bin/tlint --paths="app/Http/Controllers/$FILE.php"
Breaking Changes:
NoCompact, UseConfigOverEnv). Update your config if using custom rules.tformat.json into tlint.json. Migrate old configs.vendor/bin/tlint -v
vendor/bin/tlint --dry-run
vendor/bin/tlint --no-cache
Custom Linters/Formatters:
Extend Tighten\TLint\Linter or Tighten\TLint\Formatter:
namespace App\TLint;
use Tighten\TLint\Linter;
class CustomLinter extends Linter {
protected $message = 'Custom rule: {{message}}';
public function lint($node) {
// Custom logic
}
}
Register in tlint.json:
{
"linters": ["App\\TLint\\CustomLinter"]
}
Preset Overrides: Override default presets by redefining them:
{
"presets": [],
"linters": ["tighten:NoDump", "tighten:FullyQualifiedFacades"]
}
FullyQualifiedFacades to avoid use Auth; in favor of use Illuminate\Support\Facades\Auth;.RequestValidation formatter to move validation logic from controllers to Form Requests.SpacesAroundBladeRenderContent) and directives (SpaceAfterBladeDirectives).--no-windows flag if encountering path issues:
vendor/bin/tlint --no-windows
How can I help you explore Laravel packages today?