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

Optional Laravel Package

petrknap/optional

Optional brings Java 8-style Optional to PHP, making null handling explicit and safe with isPresent(), get(), orElse(), and ifPresent(). Create strictly typed optionals for bools, strings, arrays, objects, and custom types using built-in traits with full static analysis support.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

What changed. v4.0.0-rc1 is a breaking major that removes the two features this assessment previously identified as the package's only credible TPM-relevant value: the TypedOptional helper (PRs #51, #56) and the typed-option examples (PR #44). It also removes Optional::toNullable (#38), replaces static with self (#34), makes the template covariant (#40), and changes the behavior of equals (#49), flatMap (#52), map (#53), filter (#54), ifPresent (#55) and the getters (#57). Prior assessment conclusions on integration value and pilot design no longer hold.

Architecture fit. Framework-level verdict is unchanged: still no service provider, facade, config, or Eloquent surface, so it remains architecturally clean and remains a stylistic choice rather than a gap in the Laravel stack. But the release materially weakens the fit argument. With TypedOptional and the typed examples gone, what remains is a bare Optional monad; the typed-wrapper story that justified a domain-layer pilot is now something we would have to design, document and own. The static→self change removes late static binding, which is the mechanism most hand-rolled wrapper patterns would lean on. The addition of a reference to OptionalTest.java (#50) also makes the design anchor explicit: this package is tracking Java Optional conformance, not PHP/Laravel ergonomics. That sharpens the "porting for its own sake" concern rather than answering it.

Integration feasibility. Downgraded from "composer-only, low friction" to "composer-only, more friction than before." Removing toNullable deletes the single-call escape hatch back to framework-native nullable returns, so every boundary crossing into Eloquent, Collection, or a nullable-typed collaborator now needs an orElse-style call (confirm an equivalent exists — if not, this is disqualifying for boundary use). Removing TypedOptional means any pilot must hand-build its wrapper layer with zero upstream reference implementation and no example code to point reviewers at. As a pre-release RC, it also requires an explicit 4.0.0-rc1 constraint (or a minimum-stability change) in a Laravel composer.json, which is a small but real governance wrinkle.

Technical risk. Higher than at v3.5.2, in three distinct ways. First, API churn at the features we valued: the value proposition was deleted in a major release from a single maintainer, which is evidence of an unstable public contract. Second, semantic drift: "correct behavior of flatMap" and "improved map/filter/ifPresent" imply 3.x was incorrect, so any 3.x pilot code may be depending on buggy semantics that 4.0 silently changes — this is a quiet-behavior-change risk, not a compile-error risk, for equals in particular. Third, variance and binding changes are static-analysis- and subclass-level breaks: covariant templates can alter PHPStan/Psalm inference and generic annotations, and self breaks any subclass relying on late static binding. The LGPL-3.0 gate is unchanged and still blocking. Adoption data remains absent (empty dataset supplied), so the previously observed zero-dependents posture is unverified and cannot be assumed to have improved.

Key questions.

  1. If TypedOptional is gone, who owns the wrapper layer we would now have to write — and if we are writing it anyway, why not own the entire ~100-LOC value object and drop the LGPL and single-maintainer exposure?
  2. Is there an orElse/getOrElse equivalent that cleanly replaces toNullable at framework boundaries?
  3. Did the in-flight or planned pilot rely on any 3.x map/filter/flatMap/equals behavior, and does 4.0 change observed results?
  4. Does Legal accept LGPL-3.0 for our distribution model — still unanswered and still blocking?
  5. Does our PHPStan/Psalm configuration and annotation style still resolve under a covariant template, and is the analyzer version pinned?
  6. What is the GA timeline for 4.0.0, and is there a post-GA backward-compatibility commitment? We should not build on an RC with no stated stability guarantee.
  7. Does a Java-Optional-conformance roadmap match any real need we have, or are we adopting a port for its own sake?

Integration Approach

Stack fit. Re-verify the composer.json PHP constraint after the major bump (minimum PHP may have moved), and confirm Laravel 9–12 runtime compatibility is unaffected — the runtime surface is trivial, so the realistic risk is analyzer and IDE tooling, not framework conflict. Note the RC constraint requirement above.

Migration path. The previous guidance (additive, reversible, one module, boundaries only, internals conventional PHP) was correct and is now harder to execute because the wrapper scaffolding and the nullable escape hatch are both gone. Critically: if a pilot already started on 3.x, this is not an additive upgrade. Call sites using toNullable, any use of TypedOptional, any subclass relying on static, and any equality or map/filter/flatMap assumption must be reviewed before bumping. Do not mix 3.x and 4.x across modules — the semantics differ.

Compatibility. Runtime compatibility with Laravel is likely unchanged; the compatibility axis is now version semantics plus static analysis. The covariant template change is a tooling-level break, not a runtime one, so a green PHPUnit suite will not catch it — the PHPStan/Psalm run is the actual gate.

Sequencing.

  1. Legal review of LGPL-3.0 against distribution model — still blocking, still step one.
  2. Pin decision before writing any code: 3.5.2 (stable, has TypedOptional, has toNullable) vs. 4.0.0-rc1 (removes both, mid-churn). Do not start a pilot on an RC.
  3. Spike: build the wrapper layer by hand on a 200–500 LOC slice with PHPStan wired, and measure what the package contributes versus what we wrote ourselves.
  4. Quantify the "own it" option — a small internal value object removes LGPL, fork, and abandonment risk entirely and should be priced as the baseline alternative.
  5. Decide expand / hold / drop. Given the release, the default is now drop unless step 3 shows the package still carries its weight.

Operational Impact

Maintenance. Unchanged structurally (single maintainer, no observable ecosystem) but worse in practice: a major release deleted headline features and thinned the documentation ("removed unnecessary typed option examples"). Treat as self-maintained — vendor a tagged release, pin a commit hash or exact version, and be ready to fork. The fork contingency now has to include re-implementing TypedOptional, which raises the true cost of the contingency. LGPL still obligates publishing modifications to the library.

Support. No community footprint, no Stack Overflow corpus. The internal ADR is now mandatory and must additionally record which version's semantics we target and what our own wrapper layer looks like, or the next major will silently invalidate it.

Scaling. Runtime cost remains negligible. Organizational cost rose: removing toNullable makes adoption effectively one-way, so teams cannot cheaply convert back to nullable returns if the idiom does not land. That converts a reversible stylistic experiment into a semi-permanent architectural commitment in whichever module adopts it, which is precisely the outcome the earlier assessment warned against.

Failure modes.

  • Fatal errors at deploy from removed toNullable / TypedOptional call sites when bumping 3.x → 4.x.
  • Silent semantic change: equals, map, filter, flatMap, ifPresent behavior differs from 3.x with no type error to catch it.
  • Static-analysis false confidence: covariant template or unpinned analyzer yields inference that does not match runtime.
  • Hand-rolled wrapper drift with no upstream reference implementation to converge on.
  • RC instability or an abandoned RC with no GA, leaving us pinned to a pre-release.
  • Previously identified modes persist: get() on empty, paradigm drift across modules, upstream abandonment with no fork owner.

Ramp-up. Individual learning curve is still low, but setup cost is higher: build the wrapper layer, wire and pin the analyzer, and handle the removed toNullable at every boundary. Budget the pilot sprint plus enablement as before, then add explicit time for the wrapper work that upstream used to provide — and compare that total against simply writing and owning a small internal value object.

TPM recommendation. Drop (previously "Defer with a scoped pilot"). The release removed the specific capabilities that justified the pilot, introduced behavior changes with no compile-time signal, and confirmed a roadmap aimed at Java conformance rather than PHP ergonomics — all while the LGPL gate remains unresolved and the package remains single-maintainer with no adoption evidence. If the team still wants explicit absence semantics in one domain module, evaluate owning a minimal internal value object first; it eliminates the license, fork, and abandonment risks at comparable effort. Re-open only at 4.0.0 GA with a restored typed-wrapper story, pinned analyzer support, legal sign-off, and a GA stability commitment.

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.
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel