In recent days Laravel Pint was introduced and caused havoc of ambivalence - some love it, some hate it. Personally I have mixed feelings about it, and I wanted to share my thoughts with the other developers.

Appreciation and admiration

First, I would like to emphasise my admiration for Nuno Maduro’s passion. He is truly dedicated to Open Source community, mostly Laravel part, and brings his ideas to life, providing tools for many people in PHP land. It’s truly amazing.

The thing is I am not completely fine with his latest work and would like to address some concerns here for discussion.

And now for something completely different

Pint pointing at the CS Fixer

This is first thing which triggered me: Nuno’s initial tweet is all about announcing new package, a zero-dependency code style fixer. There is not any mention about PHP CS Fixer, actual fixer package, on top of which Pint was built. Of course, there is information about it in Pint’s readme, but let’s do not fool ourselves - it surely wasn’t read by large part of the announcement’s audience. Stating it explicitly in the announcement would be fair to PHP CS Fixer’s creators and its maintainers…

Especially that Pint is not adding much in terms of coding standard fixing - it focuses on Developer Experience.

Lifelong wait is over

I saw many tweets from people that “have been looking for this”, like:

I was pretty confused. Where exactly those people were looking? Into Laravel Docs?

This is of course not Nuno’s fault that people in Laravel community don’t know basic tools that are present in PHP world for years now. It is just saddening that people don’t look for existing, battle-tested solutions further than laravel/* namespace. For all of those people, who “were looking for it”, it would be better to share upstream package explicitly in the announcement and teach them about existence of such tools.

But I get it’s not in Laravel’s interest…

Subjectively great DX

One of the most hyped features of Pint is its CLI user interface. Announcement had some nice, simple screenshot showing the output of the command. But in my opinion CLI commands above all should be useful and at some point Pint loses it:

Laravel Pint: Rule overflow

@TattedTechBro, Twitter

List of applied rules is presented horizontally in one line, so if multiple fixers were applied, the list may be trimmed, and you won’t know which were used. For people looking for fancy output, not actual important data, it won’t be a problem, probably. Personally, looking at the screenshot above I see messy block of text with some information lost. For me, it is not an advantage over regular CS Fixer’s output (at least at this point, it’s still 0.* release).

Zero dependency, non-zero problems

Pint is built with Laravel Zero, which means it’s shipped as executable which contains all of its dependencies. It surely will minimise amount of Composer conflicts, but please have in mind that it also hides actual dependency to PHP CS Fixer. You’ll get what’s bundled in Pint, not what’s available at Packagist. Effectively it means that you need to wait for Pint release to get fixes or new features from CS Fixer. It’s totally different from PHPStan or Rector, which also ship with “zero dependency” (PHAR file or prefixed, built-in vendors) - these are top-level tools while Pint is a wrapper for actual tool.

Sometimes it may be tempting to install Pint globally… Stahp. Don’t do it 😉. Each project should have its own set of dependencies with explicit versions, so every developer install exact same toolset and works the same way.

Your code, your rules

Another Pint’s hyped feature is “zero config”. People are delighted that “it just works!”.

But let me ask: were all of these 400+ styling issues actually violations? Well, it depends. If you use “zero config” approach, you’re giving away control over your coding standards to the tool. It’s not your coding standard then. It may lead to situations when code that you like needs to be changed to satisfy tool. Of course, you don’t need to apply all the fixes and configure PHP CS Fixer Pint, so some rules may be disabled or behave differently. But then it’s not zero-config anymore, so is it really that good to be advertised? 🤔

In my opinion it is good to have explicit config. It ensures that you’ll get exactly what you want, not what tool’s wrapper’s creator delivered as defaults. It’s especially important in initial development period (version 0.*), when you don’t have any backward compatibility promise.

Automate it: yes, but no!

Last thing I would like to point is CS automation. I saw many tweets about integrating Pint in Github Actions:

I did discuss it under several tweets (like here), but it’s out of control. So I would like to emphasise here that automating CS checks is highly encouraged, but automating CS fixes not. You should integrate CS tool in your development workflow (CLI habit, Git pre-commit hook, #CI job), and check if code satisfies your coding standards definition.

If check fails, you can decide if each violation should be fixed or if rule should be disabled/reconfigured. At some point maybe you’ll trust the tool enough to enable automatic fixes, but personally I don’t do it. Especially in large, legacy apps where standards are not fully applied, it may lead to unintentional code logic change (e.g. CS Fixer may change == to === when risky rules are enabled) that will cause the problems to the users.

Remember, tools are just tools, they do what programmers made them to do. And some scenarios or edge cases may be not tested or just implemented badly. Don’t take result of such tools as 100% safe.

In the end it’s your decision

Having said all the above, we can agree that in the end it’s up to you what fits your needs. You can use whatever tool you like, but do it responsibly and knowingly. Appreciate and support people working hard on tools you use, like Dariusz “keradus” Rumiński, creator and maintainer of PHP CS Fixer, which drives Laravel Pint.