Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Duster Laravel Package

tightenco/duster

Duster automatically applies Tighten's default Laravel code style by combining TLint, PHP_CodeSniffer, PHP CS Fixer, and Pint. Lint or fix everything at once, target only uncommitted files with --dirty, and customize includes/excludes via duster.json.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

Duster is a dev-only Composer package (Laravel Zero CLI application) that acts as a thin orchestrator over four independently maintained style tools: TLint, PHP_CodeSniffer, PHP CS Fixer, and Pint. Architecturally it is a build-time/developer-experience layer, not an application dependency — it installs with --dev, never executes in a request lifecycle, and ships no runtime code. That makes it a near-zero-blast-radius addition to a Laravel codebase: the worst-case failure is a noisy CI job, not a production incident.

The design decision that matters most is that Duster does not reimplement linting; it bundles pinned versions of upstream tools plus Tighten's curated presets (Tighten for TLint/PHPCS, Laravel preset for Pint, plus a CustomOrderedClassElementsFixer rule for class element ordering). Value is therefore concentrated in preset curation and orchestration ergonomics, not in novel capability. A team could replicate ~80% of the behavior by wiring the four tools together manually. This is the core build-vs-adopt tradeoff a TPM should price explicitly: Duster is buying you a maintained opinion about style, plus a single command surface (duster lint / duster fix) and a --dirty fast path. Both are real developer-productivity wins, but they are convenience, not differentiated technology.

Integration feasibility

High. Installation is a single Composer require, execution is ./vendor/bin/duster, and it degrades gracefully: --using="phpstan,tlint,pint" lets you compose which tools run and in what order, and duster.json gives include/exclude globs, custom scripts (arbitrary Symfony\Process invocations with a configurable processTimeout), which means static analysis and other gates can be folded into the same entry point. It publishes GitHub Actions and Husky hook stubs out of the box, and knows how to shell into containerized dev environments (ddev, warden, lando, sail) via --env. The --dirty mode (lint only files with uncommitted changes) is the key ergonomic feature for incremental adoption and for keeping pre-commit hooks fast.

The friction points are opinionation and configuration drift. The defaults are Tighten's house style, and per-tool customization requires creating and maintaining four separate config files (tlint.json, .phpcs.xml.dist, .php-cs-fixer.dist.php, pint.json) whose contents are copied from Duster's standards/ directory. That is a copy-and-drift surface: once you fork the standard, upgrades to Duster no longer meaningfully update your rules.

Technical risk

Low-to-moderate, and almost entirely toolchain risk rather than security or runtime risk:

  • Style churn as a breaking-change vector. Major versions (v1 → v2 → v3) have changed underlying tool versions and dropped platform support (v2 dropped PHP 8.0, bumped Pint and Laravel Zero to 10). Any ruleset change produces formatting diffs across the repo, which pollutes git blame and can collide with open PRs. This is the single most disruptive failure mode in practice.
  • Transitive dependency conflict. Duster pulls Pint, PHP CS Fixer, PHPCS, and Guzzle transitively. If your project (or another dev tool) pins a different major of laravel/pint or friendsofphp/php-cs-fixer, Composer resolution can force a Duster downgrade or block upgrades. Recent releases show active Guzzle/PHPCS bumps, so this is a live maintenance treadmill, not a hypothetical.
  • CI commit-loop hazard, explicitly documented. The companion duster-action commits fixes back to the repo; the README warns these commits stop other running workflows and do not trigger them. Getting the workflow_run orchestration wrong silently disables downstream checks — a correctness risk, not just an annoyance.
  • Adoption signal is weak as measured. Dependents: 0 and a blank star count are almost certainly artifacts of how dev-dependencies are (not) graphed, so they should not be read as "unused." But they do mean you cannot outsource the due-diligence to adoption metrics — validate maintenance health directly from the release history and PR activity.
  • Governance/bus factor. MIT-licensed, backed by Tighten (an agency with a clear interest in the tool), with recent first-time and repeat contributors and Dependabot noise. Reasonable health, but no published support SLA and security contact is an email address — acceptable for a dev tool, not something to build a compliance story on.

Key questions

  1. Does our house style actually agree with the Tighten preset, or will we spend the first sprint rewriting four config files to diverge from it?
  2. What PHP and Laravel versions are in scope, and does Duster's constraint set match them given the PHP 8.0 drop in v2?
  3. Do we already run Pint or PHP-CS-Fixer with our own pins? If so, which one wins?
  4. Is CI allowed to commit to main/feature branches, or must fixes be surfaced as a failing check only?
  5. What is the current lint/fix runtime on the largest repo, and does it fit the CI budget (PHPCS is the slow one, and it cannot auto-fix everything)?
  6. Who owns the style guide decision, and what is the change-control process when a Duster upgrade alters rules?
  7. Are our dev environments covered by the --env allowlist (ddev, warden, lando, sail) or do we need custom invocation?

Integration Approach

Stack fit

Strong fit for a standard Laravel/PHP application with Composer, Git, and GitHub Actions, particularly one already using Sail or a supported container tool. Poor fit for polyglot monorepos with mixed PHP/JS/Go services, or for teams that want a single cross-language formatter story — Duster is PHP-only and Laravel-shaped. It also presumes Git for --dirty, so it does not compose with non-Git VCS workflows.

Migration path

Adopt in report-only mode before any autofix. Concretely: (1) require the package on a branch, (2) run duster lint with no config to quantify the existing debt as a finding count, not a fix, (3) decide whether to converge on the Tighten preset or fork configs and record that decision, (4) apply duster fix once in a single dedicated "style baseline" commit with no logic changes, added to .git-blame-ignore-revs, (5) flip CI to a blocking gate. Step 4 as its own commit is the mitigation for the blame-churn problem and is worth enforcing as policy.

Compatibility

Verify PHP constraint alignment first, then check for existing laravel/pint or friendsofphp/php-cs-fixer requirements in composer.json that could conflict. Prefer letting Duster own the tool versions and removing direct pins, rather than fighting resolution. Pin Duster itself to a known-good minor and upgrade deliberately, treating each upgrade as a rule-change review, not a routine bump. The published config files in standards/ should be copied once and diffed on every upgrade to see what upstream changed.

Sequencing

  1. Spike on one representative repo; measure lint runtime and finding count.
  2. Decide preset-vs-fork; produce the config files and commit them.
  3. Baseline fix commit + .git-blame-ignore-revs.
  4. CI gate (lint-only, no auto-commit) on pull requests.
  5. Add --dirty pre-commit hook (Husky or equivalent) for fast local feedback.
  6. Optionally fold PHPStan/Rector into duster.json scripts so a single command covers all gates; tune processTimeout if the 60s default is too tight.
  7. Only then consider the auto-fixing duster-action, with the workflow_run trigger fix in the same PR.

Operational Impact

Maintenance

Low ongoing effort but a persistent low-grade upgrade tax. Roughly half the recent release notes are dependency bumps, meaning Duster's release cadence is coupled to upstream churn you would partially inherit anyway if you ran the tools directly. Budget one minor upgrade per quarter with a ruleset-diff review, and treat major versions as scheduled work items. Config-file divergence is the hidden cost: the more you customize, the more you own.

Support

Community-supported via GitHub issues/PRs under an MIT license with Tighten's commercial interest behind it. No SLA, no LTS branch, no formal deprecation policy. Acceptable for a dev tool; do not let it become a single point of knowledge — ensure at least two engineers can explain the config.

Scaling

Per-developer cost is near zero (single binary invocation). CI cost scales with repository size and matters more: full-repo lint runs PHPCS over every file and grows linearly with codebase size. Mitigation is --dirty locally and sharding or path-scoping in CI (duster.json include/exclude, or --using to drop the slowest tool). Across many repos, standardization is the win — one preset, one command, one gate — but also the risk: a bad preset change propagates to every repo at once, so roll Duster upgrades through a canary repo first.

Failure modes

  • Preset/ruleset drift on upgrade producing repo-wide reformatting noise and merge conflicts with in-flight PRs. Mitigate with pinned versions and canary rollout.
  • Composer dependency deadlock when the project pins a conflicting Pint/PHP-CS-Fixer version. Mitigate by letting Duster own those versions.
  • CI commit loop / suppressed workflows from the auto-fix action; downstream checks silently stop running. Mitigate with workflow_run triggers, or avoid auto-commit entirely.
  • PHPCS unautofixable findings blocking fix — Duster's own release notes added a hint to run lint for this reason; expect a class of issues requiring human judgment.
  • --dirty edge cases (untracked files, renames, detached HEAD in CI) producing empty or unexpected file sets; note v1.1.1 specifically fixed a non-zero exit when no dirty files exist.
  • Container detection mismatch when using an unsupported dev environment, resulting in cryptic binary-not-found errors.
  • Custom script timeouts silently failing or hanging long-running analysis at the 60s default.

Ramp-up

Very fast for anyone who has used Pint or PHPCS: one command to learn, one optional config file, and a --using flag for composition. Plan for ~30 minutes of onboarding per engineer, plus a short written note on the two things people get wrong — do not run fix on a dirty working tree without committing first, and do not assume fix resolves everything (PHPCS findings often need manual work). The main ramp-up cost is organizational, not individual: agreeing on the preset and the baseline commit before the first gate goes live.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
steadrun/laravel-monitor
labyrinthe/connect-laravel
elmogy/layan
drewdan/sentinel-client
dskripchenko/laravel-llm
fatryst/nuonuo
stevenay/myanfont
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin