poshtive/router
Convention-based route discovery for Laravel controllers. Public methods become routes automatically, with PHP attributes for HTTP verb overrides, middleware, where constraints, prefixes, and model-bound parameters. Supports Laravel 12/13 and PHP 8.3.
What it is. poshtive/router is a convention-over-configuration route registrar for Laravel. It recursively scans a controller directory, reflects over public methods, and derives routes from filesystem path + class name + method name + method signature. Overrides are supplied through PHP attributes (Route, Where, LocalOnly, DoNotDiscover, IgnoreParentMiddleware) and a small config file. It is not a router replacement — it runs inside routes/web.php and coexists with hand-written routes.
Architecture fit. Low. Laravel's routing is already declarative, cacheable, and introspectable via route:list; this package trades that for implicit derivation. The route table becomes a function of source code shape — renaming a method, changing a parameter type hint, or moving a controller between namespaces silently changes public URLs. For any product with externalized URLs (bookmarks, SEO, mobile clients, partner integrations, webhooks), that is an unacceptable coupling between refactoring and contract stability. The value proposition — "less boilerplate" — is small for teams already using Route::resource and grouped route files, and negative for teams that value route-table reviewability in PRs.
Blocking technical findings (ordered by severity):
PHP: ^8.3 and Laravel components: ^13.0. Laravel 13 is not a shipping release line, so Composer resolution fails on every production-grade application today. This alone disqualifies it from any integration path; adopting it requires either --ignore-platform-reqs (never acceptable in production) or a fork with a relaxed constraint.public methods are considered." There is no #[Route]-required gate. Any public non-action helper on a controller — authorization shims, formatting utilities, trait-provided helpers — is registered as a reachable GET route. This is an attack-surface expansion mechanism, not a convenience. It requires a hard rule that controllers contain only actions, plus an allowlist/denylist discipline the package does not provide.strict defaults to false, meaning duplicate VERB + URI collisions are logged (only "when available") and registration continues. Last-write-wins route resolution means a controller added in the wrong directory can quietly steal traffic from an existing endpoint.poshtive/router, repository is poshtive/laravel-router, but both CI badges point at qoqn/laravel-router. This is a republished/renamed fork of another author's package under a new vendor namespace, with 0 stars and 0 dependents. No verifiable upstream diff, no security disclosure path, no independent review. Supply-chain diligence cannot be completed from the available sources.strict: true throws, and the child-controller rule ("all methods inside a User/ folder must have at least one Eloquent Model parameter, registration will fail otherwise") throws. A single bad controller added by a contributor produces a 500 on every route in the application, including health checks and auth.IgnoreParentMiddleware, class-level #[Route(middleware: ...)], and parent-class inheritance interact to determine auth on a route. Security review of "is this endpoint authenticated?" becomes a traversal of the class hierarchy plus attributes rather than a grep of a route file. This is an auditability regression on the highest-risk dimension of the framework.uri: on a controller escapes its own prefix. #[Route(uri: 'profile')] on UserController yields GET /profile, not GET /user/profile. Namespaced overrides that discard the derived prefix create collisions that are invisible at the call site.Positives worth crediting. Documentation quality is materially above the 0-star baseline: options are enumerated with defaults, a decision guide exists, attributes have worked examples, and there is a changelog with two releases. CI (PHPUnit 11 + Testbench 11) and codecov badges are present, and 1.0.0/1.1.0 notes indicate real hardening work (deterministic tie-breaking, strict diagnostics, skipped-route logging). The strict + report_skipped_routes pair shows the author anticipated the two failure modes I flagged above. The engineering intent is sound; the model is the problem.
Key questions for the maintainer / due-diligence checklist:
qoqn/laravel-router be published? Why was it republished under a new vendor?^13.0 a typo or a forward-looking constraint? What is the supported matrix (Laravel 10/11/12, PHP 8.1–8.4)?php artisan route:cache? Is a cache clear mandatory on every deploy that adds a controller?#[Route]-required) rather than opt-out for public methods?Recommendation: do not integrate. Decline for production use at this time and revisit only if the version constraint, the provenance question, and the public-method exposure model are all resolved. The package's core idea is legitimate, but it is not currently adoptable at acceptable risk. The remainder of this section documents the conditional path if a stakeholder overrides that recommendation, and doubles as the evaluation protocol.
Stack fit. The package assumes attribute-based, reflection-driven registration on PHP 8.3+. It fits a greenfield, internally-facing application with a small controller surface and no externalized URL contract — for example an internal admin console or a back-office tool behind SSO where URLs are never shared. It does not fit public APIs, versioned endpoints, anything with a sitemap, or any codebase where non-action public methods exist on controllers. Given typical Laravel codebases, the misfit case is the common case.
Migration path (brownfield). There is no incremental migration story that is safe, because the failure mode is additive: discovered routes and hand-written routes occupy the same namespace and can collide. Any pilot must run in an isolated route group with a distinguishing prefix (e.g. Route::prefix('discovered')) and strict: true from day one, so collisions fail loudly during development instead of in production. Do not run discovery un-prefixed against an existing routes/web.php — the shadowing risk is unquantifiable without a full route-table diff.
Compatibility work required before any spike:
laravel/framework to the actually-deployed major; confirm tests still pass on your Laravel version (the package's own CI targets 13, so you are now maintaining the fork).composer.json, not by tag or branch. With 0 dependents and an unclear provenance, a moving ^1.0 reference is not acceptable.route:cache behavior explicitly — assert that a cached route table is byte-identical to the uncached one in CI.Sequencing (gated, each step is a stop/go):
eval behavior beyond directory scanning, verify no post-install Composer scripts. Hard gate.php artisan route:list --json as a fixture and fail CI on any diff. This is the single most important control: it converts implicit URL changes into reviewable, intentional diffs and neutralizes the "refactor changes the contract" risk.strict: true, report_skipped_routes: true, method_extends: false, an explicit http_methods_map rather than scattered attributes. No uri: overrides on classes.Exit cost. Bounded but real: every discovered route must be rewritten explicitly, and the URL shapes produced by the convention (/user/{id}/show, not /user/{id}) will have leaked into front-end code, tests, and documentation by then. Contain this by keeping the pilot's route count small and documenting the derived URL scheme before anyone wires a UI to it.
Maintenance and bus factor. Single-maintainer, 0 stars, 0 dependents, no visible security disclosure process, no commercial backing, no SLA. Two releases to date with genuine hardening (deterministic ordering, strict diagnostics). The risk is not abandonment mid-feature — it is a framework upgrade gap: when Laravel ships the next major, this package must be updated or your application is pinned, and you have no leverage to request it. Budget for a fork you own; treat upstream as a source, not a dependency.
Support. GitHub issues on a low-traffic repo; no guaranteed response. Documentation is the de facto support channel, and it is good enough to self-serve for the happy path. Notably, the docs do not cover route caching, discovery performance, or deployment sequencing — precisely the operational questions that matter in production. Those will be answered by you, in production, or in a spike.
Scaling. Registration is a recursive directory scan plus reflection over every candidate class and method. With route:cache enabled this is a deploy-time cost only, which is acceptable. Without it, the cost recurs per request and scales with controller count — measure at 500+ controllers before committing. Two scaling cliffs: (a) the child-controller convention requires a model parameter on every method in a nested folder, which does not scale to controllers with non-model actions; (b) the "every public method is a route" rule means the reachable surface grows with every helper someone adds, unintentionally.
Failure modes and blast radius.
strict: true in CI and a route-table golden test, not in production-only.strict: false) → wrong handler serves a URL; presents as a data-integrity incident, not a routing error.IgnoreParentMiddleware on a method strips class-level auth; a single attribute is the difference between authenticated and public.Ramp-up. Writing routes is trivial — that is the entire pitch. Reading the route table is where cost shifts: a new engineer must internalize the path-derivation algorithm (folder + kebab-cased class + reordered parameters + method name), the child-controller nesting rule, the parameter-ordering heuristic and its keepOrder escape hatch, and the middleware inheritance model. Route debugging moves from "grep routes/web.php" to "read the filesystem tree and reflect on signatures." For a team of 2–3 who wrote it, fine; for a rotating or growing team, this is a persistent tax that the boilerplate savings do not offset.
Net assessment. Score 2.53 reflects the reality accurately: competent execution and above-average documentation wrapped around an installable-nowhere constraint, an unaudited fork provenance, and a discovery model that expands the attack surface by default and couples public URLs to private code structure. The strict and report_skipped_routes options show the author understands the danger; they do not remove it. Recommendation: no-adopt. Use explicit routes or Route::resource today; if attribute-driven discovery is genuinely wanted, evaluate a package with a published support matrix and a real dependent base rather than a 0-star republication.
How can I help you explore Laravel packages today?