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

Bones Macros Laravel Package

genealabs/bones-macros

genealabs/bones-macros bundles reusable Laravel macros for GeneaLabs Bones projects, extending Blade, collections, and request helpers so common patterns become one-line calls and everyday boilerplate shrinks.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. bones-macros is a single service provider that registers Blade::directive(...) and/or Form::macro(...) calls at boot. That is the entire architecture: a global, unscoped, boot-time mutation of the framework's templating layer. It fits cleanly into exactly one slot in our stack — presentation-layer sugar for internal CRUD and admin screens — and fits nowhere else. It does not touch domain logic, persistence, or request handling, so it cannot corrupt data; it can only emit wrong or unsafe markup. That narrow blast radius is the strongest thing in its favour.

Against modern Laravel (8+/9+), native Blade components and FormRequest already occupy this slot with first-party support, test coverage, and zero supply-chain exposure. So this is not an architecture decision; it is a "do we accept an unmaintained third-party dependency to avoid writing ~200 lines of Blade" decision. Framed that way, the answer is usually no.

Integration feasibility. Mechanically trivial. composer require on Laravel 5.5+ auto-discovers the provider; older versions need a line in config/app.php. Real feasibility is gated on metadata we have not yet read: declared illuminate/* and php constraints, the emitted HTML flavour (Bootstrap 3/4, Tailwind, or framework-agnostic), and whether it drags in laravelcollective/html. That last one is decisive — the Form/Html facades were removed from the framework proper and the Collective package is effectively unmaintained past 5.x, so if it is a dependency, every form built on it breaks at once on the next major bump.

Effort to a defensible answer is small: roughly half a day for the source read and compatibility spike, 3–4 engineer-days to close the evaluation including a port of the macros that earn their keep. This is a cheap decision to make and an expensive one to defer.

Technical risk. Ranked by severity:

Risk Severity Notes
Unescaped attribute injection Critical Hand-rolled sprintf form macros are a classic stored-XSS vector. Payload " onfocus="alert(1) bound to old() is the test. Back-office stored XSS is a hard stop, not a finding to log.
Missing CSRF / _method High Silent 419 on first submit. Needs verification, not assumption.
laravelcollective/html dependency High Couples our form rendering path to a deprecated package; upgrade becomes an all-forms-at-once event.
Silent macro name collision Medium Blade::directive overwrites without warning. Shadows an in-house helper and produces subtly wrong markup that surfaces weeks later as a styling regression.
Abandonment Medium Zero stars, zero dependents, score 0, no visible release cadence. Assume dormant and plan to own it.
Discovery skipped in prod Low --no-dev / optimized autoloaders can skip package discovery; works locally, breaks in CI/prod.

The absence of stars, dependents, and peer review is not vanity-metric noise — it means no production corroboration and no one else's bug reports to borrow. We would be the first serious consumer of code sitting directly on our form-rendering path.

Key questions to close before any template is touched.

  1. What are the declared php and illuminate/* constraints, and what is the last commit date?
  2. Does it require laravelcollective/html?
  3. What are the exact macro names and argument signatures? (Blade::getCustomDirectives() after install is the authoritative inventory.)
  4. Does every macro apply e()/htmlspecialchars to attribute values? Read every concatenation.
  5. Do the form macros emit @csrf and @method?
  6. What HTML flavour is emitted, and does it match our CSS framework and a11y conventions?
  7. Do the macros accept value and error arguments, or must repopulation be post-processed in a wrapper?
  8. What existing directives in our codebase would this shadow?
  9. Can we reimplement the 2–3 useful macros as app-owned components in under a week? (Almost certainly yes — this is a few hundred lines.)

Integration Approach

Stack fit. Constrained to legacy or version-pinned applications (roughly Laravel 5.x–8.x), or teams with an existing macro convention worth preserving for consistency. On any new build or modern Laravel target, native <x-form.input> components are the first-party default and this package should not enter the conversation. Where it does fit: internal admin panels, settings pages, disposable prototypes, migration-era back-office tooling.

Two migration paths — pick one deliberately, do not drift into one.

  • Path A — Adopt, but isolate. Install, wrap every macro usage in an app-owned partial or component so the macro name appears in exactly one file per field type. Swapping to a native component later becomes a one-file change instead of a grep-and-replace across the codebase. Acceptable only if the compatibility spike and escaping audit both pass.
  • Path B — Extract and port (recommended). Read the source, reimplement the two or three macros that carry real value as app-level Blade components under our own HTML snapshot tests, and keep the package out of composer.json entirely. Same developer-hour savings, zero upgrade liability, no dependency-intake precedent to defend. Given the package's size, this is the default.

In practice two or three macros carry all the value; the rest are noise. Treat the macro set as a menu, not a bundle.

Compatibility. Verify via spike, never from the README. Pin the exact version. If Path A is chosen and upstream is dormant — assume it is — vendor via private fork or packages/ path repository at a commit SHA. Do not let a floating Packagist resolution sit on the form-rendering path.

Sequencing.

  1. Source read + constraint check (0.5d) — provider, macro definitions, composer.json, last-commit date.
  2. Collision audit — diff array_keys(Blade::getCustomDirectives()) before and after; this doubles as the in-house-helper shadow check.
  3. Escaping + CSRF audit — line-by-line, with the injection payload test. Hard gate; stop on failure.
  4. Single-screen pilot — one low-risk internal CRUD or settings partial. Not customer-facing. The goal is not standardization, it is answering "does the emitted markup match our CSS framework and conventions?" View-source, not DOM inspector — you need to see the escaping.
  5. Snapshot tests around the wrappers — these survive a later port to native components unchanged, so the test investment is never stranded.
  6. Decision gate — keep, vendor, or port out. Close it; do not leave a pilot running indefinitely as de facto production.

One sequencing rule that matters: run this after the Laravel upgrade target is fixed, not before. The port-vs-abandon calculus inverts completely once the target version is known, and a pre-upgrade pilot can produce conclusions we then have to unwind.

Operational Impact

Maintenance. Assume upstream stays dormant and budget accordingly — this becomes our code the day it ships. Path B removes the question entirely, which is most of its appeal. Path A requires a named internal owner, a pinned version or fork, and an entry in the upgrade checklist tied to the Laravel major version. Given zero dependents and no release cadence, "we'll pick up fixes upstream" is not a plan.

Support. No vendor, no community, no issue-tracker signal to lean on. Support is entirely internal. Bus factor is one until at least two engineers have read the provider — mitigate by making the source read part of the pilot rather than a solo spike.

Scaling. Runtime scaling is a non-issue: directives compile into cached views, no per-request overhead. The real scaling constraint is organizational. Registration is global, boot-time, and permanent — every macro is available everywhere with no opt-in, scoping, or ordering control. That is tolerable for one team; as teams are added, the shared directive namespace becomes a collision surface with no detection mechanism. This is a second, independent argument for owning a single app-level provider instead.

Failure modes to instrument for.

  • Silent shadowing — a shadowed in-house helper emits subtly wrong markup; surfaces weeks later as a styling or attribute regression.
  • Stale compiled views — the number-one cause of "the macro works in tinker but not in the browser." Standard remedy after any provider or config change: config:clear, view:clear, composer dump-autoload.
  • Missing CSRF — silent 419 on first POST, looks like a session bug.
  • Unescaped attributes — stored XSS in a back-office form; the one failure mode with a security incident attached.
  • Discovery skipped in prod — works locally, fails under composer install --no-dev. Diagnose with php artisan package:discover.
  • Form facade removal on major bump — if laravelcollective/html is in the tree, every form breaks simultaneously. This is the failure mode that turns a utility into an incident.

Debug by dumping storage/framework/views/*.php — the compiled output shows what a directive actually emitted, which is faster than reasoning about the template.

Ramp-up. Half a day for any Laravel-fluent developer to absorb the macro contract. That is not the cost. The real cost is review discipline: someone must actually inspect the emitted HTML — escaping, error classes, label association, aria-invalid, accessibility — rather than trusting it. Budget that as explicit task effort on the pilot, not as background QA. It is also the line item that most often reveals the package is not worth keeping.

Governance note. With zero stars, zero dependents, and a score of 0, this evaluation is really a test of whether we enforce dependency intake policy. Whatever we decide, treat it as precedent-setting — the answer sets the bar for the next "small utility" request. Recommended position: evaluate cheaply, decide explicitly, default to porting the useful macros into app-owned components, and record the decision so the next request inherits a rule rather than a re-litigation.

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.
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings
coleus/apps
seampact/laravel
emmyconceptng/laravel-ng-postcode
jjsquady/round-robin
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route