I nearly dropped a dependency for two reasons that were both false
The plan was to build on an existing Laravel page-builder package. I decided against it because it did not support the current Filament version and looked unmaintained. Both claims turned out to be wrong, the decision stayed the same, and writing down why is the part that mattered.
Two documents in this project, written weeks apart, both recommended building Atelier on top of Z3d0X/filament-fabricator. It is the established block-based page-builder skeleton for Filament: page resource, slug resolution, front-end routing, a layouts and blocks abstraction. Reuse before custom, and the reasoning was sound.
Then I decided not to use it, and gave two reasons:
- It only officially supports Filament 3. It works on newer versions but is not supported.
- The maintainer has stepped back.
Before rewriting five documents around that decision, I checked. Both were wrong.
What the check found
The compatibility table is in the readme:
| Fabricator | Filament | PHP |
|---|---|---|
| 1.x | ^2.0 | ^8.0 |
| 2.x | ^3.0 | ^8.1 |
| 3.x | ^4.0 | ^8.2 |
| 4.x | ^5.0 | ^8.3 |
Filament 5 is officially supported on the 4.x branch, and the repository ships an upgrade guide for moving from v4 to v5.
The maintenance claim did not hold either. Last push six weeks earlier, three open issues, not archived, 385 stars. Nobody had stepped back from anything.
That is two minutes of checking against a decision that was about to be written into a product spec as fact.
The decision did not change
Here is the uncomfortable part: I dropped it anyway.
Not out of stubbornness. Because checking the claims forced me to work out what the actual argument was, and there was one. Of the five things Fabricator provides, the spec already replaced four:
| Fabricator provides | Atelier's spec |
|---|---|
| A page resource edit screen | Replaced by the full-screen builder |
A single content column |
Replaced by separate draft and published columns |
| A slug on the page record | Replaced by a slugs table, unique per locale |
| Layouts and page blocks abstraction | Replaced by our own block registry and contract |
| Front-end routing and layout resolution | Kept |
What is left is a route, a controller and a slug lookup. Taking a dependency that shapes the page model, and then overriding the page model, is the worst of both: you carry its constraints and its upgrade path without using the parts that justify them.
That is a real argument. It is also completely different from "it does not support Filament 5", and it is the one that survives someone checking.
Cost, stated rather than hidden
The decision record says what it costs, because a decision that only lists benefits is marketing:
Feature 02 grows: the page model, slug resolution, front-end routing and layout resolution become ours to write and test. And Filament version tracking is now permanently our job. When Filament 6 lands, nobody upstream does that work for us. That is the trade and it is accepted.
That last sentence is the one to reread in a year.
Writing down the correction
The obvious thing to do, once the conclusion had not changed, is to write the decision and move on. The reasons were wrong but the answer was right, so who cares.
I put the correction in the document instead, above the argument:
First, correct the record on two claims that were made against it. Fabricator officially supports Filament 5 on its 4.x branch, with a v4-to-v5 upgrade guide in the repo, and it is actively maintained: last push 30 June 2026, three open issues, not archived, 385 stars. Checked 15 Aug 2026. Nobody bailed. If we ever revisit this, revisit it on the real argument below, not on those two.
Two reasons for that.
The first is that decision records get reread when the decision is being reconsidered, usually by someone who was not there. If the record says Fabricator does not support Filament 5, then in a year someone checks, finds it does, and reasonably concludes the whole decision was made on bad information. The real argument gets thrown out with the false one.
The second is that it keeps the argument honest. Leaving the false reasons in place lets a weak argument hide behind them. Removing them means the remaining reason has to stand on its own, and if it could not, that is worth knowing before writing the code rather than after.
The superseded documents got dated banners rather than edits. The original recommendation to build on Fabricator is still there, still readable, with a note saying what reversed it and why. The reasoning about where to spend effort in that document is still correct and still useful; only the conclusion changed.
What this cost and what it bought
The cost was real. The page model, the slug table, the catch-all route that has to not shadow the host app's own routes, layout resolution, and permanent responsibility for Filament version compatibility.
What it bought is that when a page needs two content columns, or slugs need a unique index per locale, or the edit screen needs to be a full-screen page outside the panel chrome, none of those are fights with someone else's abstraction. They are just the schema.
For a package that will be extended for years across client sites, that trade is worth making. It is also exactly the kind of trade that is easy to make for bad reasons, which is why the reasons are written down and the wrong ones are marked as wrong.
Building scalable systems and developer-first tools. Lead Software Engineer at DSRPT.
Frequently asked
-
Yes, and the case where the conclusion does not change is the one most worth verifying. If the stated reasons are wrong and the record keeps them, then the next person to revisit the decision will check, find the reasons false, and reasonably discard the whole decision including the parts that were sound. Verifying also forces you to articulate the argument that actually holds, which in this case was completely different from the one originally given and much harder to argue with. A conclusion that survives its reasoning being corrected is stronger than one that was never tested.
-
When you would override most of what it provides. Count the things the dependency actually gives you and mark off the ones your specification already replaces. If the answer is that you keep one of five, you are carrying that package's constraints, its release cadence and its upgrade path in exchange for something you could write in a day. That calculation is very different from a general preference for building things yourself, and it is worth doing explicitly because the reuse instinct is usually correct and needs a specific reason to override.
-
Correct it in place, above the surviving argument, with a date and what was checked. Do not quietly delete the wrong reasons and do not leave them standing. Deleting them hides that the decision was ever made on bad information, which means nobody knows to be careful next time. Leaving them lets a weak argument shelter behind claims that will not survive scrutiny. Superseded documents are best handled the same way: a dated banner saying what reversed the decision, with the original reasoning intact underneath, since the analysis is usually still useful even when the conclusion is not.
-
You own the page model, slug resolution, front-end routing and layout resolution, including the awkward parts like a catch-all route that must never shadow the host application's own routes. More significantly, you own framework version tracking forever: when the admin framework releases a major version, nobody upstream absorbs that work for you. The mitigation is to keep the surface that touches framework internals small and concentrated in as few files as possible, because that surface is exactly what breaks on a major version bump.