webman-tech/common-utils
A collection of common utility helpers for the webman PHP framework, providing reusable tools to simplify everyday development tasks. Designed for webman-tech projects, it offers practical shared functions and classes that reduce boilerplate and keep application code cleaner and more consistent.
Bottom line up front: this is not a Laravel-ecosystem utility package. It is a Webman-first runtime abstraction layer, published as a read-only subtree split from a private monorepo, whose secondary purpose is to make business code portable to Laravel and to CLI/test contexts. A TPM should evaluate it as an internal-standards dependency, not a community dependency. The 0-star / 0-dependent signal is consistent with that framing and should be read as "no external adoption evidence," not as "low quality."
Architecture fit. The package implements an adapter pattern around framework primitives: Runtime + RuntimeCustomRegister for environment detection and path/container resolution, and Request / Response / Session / Route / Config / EnvAttr / Json / Encoding / View wrappers with a Middleware\BaseMiddleware base class and a Testing\Factory fake-injection layer. That is the correct shape for a cross-runtime standard. It fits organizations that (a) run Webman in production and Laravel in adjacent tooling or legacy services, (b) maintain shared domain/service code that must execute identically in HTTP, CLI, queue, and unit-test contexts, or (c) are actively planning a runtime migration in either direction. It does not fit teams who are Laravel-only: you would take on the abstraction, the read-only-release governance, and a single-maintainer risk for zero portability benefit.
Integration feasibility. Low mechanical cost, moderate semantic cost. Composer install plus a RuntimeCustomRegister::register() call in CLI/test bootstrap is the entire floor. The real work is cultural: the package only pays off if consumers stop calling request(), \support\App::runtimePath(), and raw json_encode(), and stop type-hinting framework-native request classes. That means lint rules, code review gates, and a documented "no native framework classes in shared code" policy. The testing fakes are the fastest win — they let service-layer unit tests run without booting Webman or Laravel, which is a measurable CI-time and flakiness reduction and requires no production code change.
Technical risk.
| Risk | Severity | Why it matters |
|---|---|---|
| Bus factor / governance | High | Read-only subtree split from webman-tech/components-monorepo; issues and PRs are not actionable at this repo. Any fix requires upstream access or an internal fork. |
| Version/semver opacity | High | Release cadence follows the parent monorepo; no independent roadmap, no visible BC policy. Pin exact versions. |
| Abstraction leakage | Medium-High | Session, Route, and Middleware semantics diverge across Webman and Laravel; parity is asserted by the skill docs, not by a published compatibility matrix. |
| Global mutable state | Medium | EnvAttr goes read-only after first get(); Route::clear() is destructive; test fakes are process-global and require explicit cleanup. Predictable failure mode but easy to trip in long-running workers. |
| Silent behavioral drift | Medium | withHeaders() / withCustomData() mutate the underlying native request; two runtimes, one contract, no third-party conformance suite. |
| Performance | Low | Thin delegation per call; negligible against I/O. Not a sizing concern. |
Key questions to resolve before adoption.
Session and Route under Laravel, or is it explicitly Webman-primary with Laravel as best-effort?Request::getCurrent() and the fakes request-scoped or process-scoped?Stack fit. Strong fit for a Webman-primary estate with Laravel sidecars; strong fit for any team that wants one test harness across both. Weak fit for Laravel-primary estates, and weak for teams standardized on PSR-7/PSR-15, since this package defines its own contract rather than implementing PSR interfaces — a relevant interoperability gap if the organization already has PSR-based middleware.
Migration path. Adopt bottom-up, never top-down. The abstraction is only as safe as the number of native-framework call sites remaining, so sequence from lowest blast radius to highest:
Factory::registerTestRuntime()). Production code untouched; immediate CI benefit; fully reversible.base_path(), runtime_path(), logger(), config()) in CLI scripts, commands, and queue jobs, where native Webman functions are unavailable anyway.Json / Encoding / View in shared serialization and rendering paths — mechanical, low-coupling, immediately improves edge-case handling (NaN/INF, non-UTF-8, Json\Expression for inline JS).BaseMiddleware for cross-cutting concerns (tracing, correlation IDs, response timing) that genuinely must run on both runtimes.Request / Response / Session / Route in shared business code last, and only where cross-runtime reuse is a stated requirement. This is where semantic divergence bites.Compatibility. Verify against the actual PHP matrix and both target Laravel majors before phase 1. Confirm the EnvAttr read-only behavior against existing .env handling — if the estate already has an env loader, expect a collision and resolve it in phase 2, not phase 5. Confirm whether Route::clear() or test fakes can be reached from production code paths; if so, add a static check or CI grep to block them.
Sequencing and gates. Each phase ships behind a measurable gate: phase 1 gate = CI runtime reduction and zero production diffs; phase 2–3 gate = native call-site count trending down under an agreed threshold; phase 4 gate = one production middleware running on both runtimes with identical trace output; phase 5 gate = a written compatibility matrix covering every abstraction method actually used, reviewed by the owning engineer. Do not start phase 5 without a signed-off fork/maintenance plan.
Maintenance. The dominant cost is not upgrades — it is ownership. A read-only split with 0 dependents means the organization is effectively the maintainer of last resort. Budget for a named internal owner, a pinned version policy (exact pins, no ^), a vendored-fork contingency, and a quarterly review of upstream activity in the parent monorepo. Treat every upstream minor as a potential breaking change until proven otherwise.
Support. No community support surface, no public issue tracker, no external Stack Overflow corpus. Internal onboarding docs and the shipped skill/best-practices guides become the primary reference — which is actually a strength here, since the package ships unusually good usage guidance (allowed/forbidden patterns, error-to-cause table). Assign a single internal SME; two is better.
Scaling. Runtime cost is negligible — thin delegation over native calls. The scaling concern is state, not throughput: under Webman workers or Octane, EnvAttr's read-only latch, Request::getCurrent(), and the test fakes are process-scoped, so correctness depends on disciplined per-request reset. Capacity planning is unaffected; correctness planning is not.
Failure modes to instrument.
UnsupportedRuntimeException in CLI, cron, queue workers, and any entry point that never auto-detects a runtime → the single most likely production-surprise failure. Fail fast at bootstrap with an explicit RuntimeCustomRegister::register().EnvAttr write-after-read exceptions during config warm-up or test setup → document changeSupportReadonly(false) as initialization-only.TestRequest / TestRoute → enforce clear() in beforeEach, not per-test.Route::clear() → block in CI.Json::encode() → good, but audit any downstream consumer that currently branches on json_encode() === false, since that branch becomes dead code.Session / Route behaving differently on Laravel than on Webman → only detectable with a cross-runtime contract test suite; build a small one rather than trusting parity.Ramp-up. Roughly one sprint for a mid-level PHP engineer to be productive, most of it spent unlearning native habits: no request(), no framework type-hints in shared code, no raw json_encode(), prefer helpers over concrete classes. The shipped best-practices doc shortens this materially — use it as the onboarding artifact verbatim rather than writing a parallel guide. Expect a longer tail on Middleware and Session, where the Webman/Laravel behavioral gap requires experiential knowledge; pair those reviews with the SME for the first few PRs.
How can I help you explore Laravel packages today?