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

Symfony Time Machine Laravel Package

icanhazstring/symfony-time-machine

Symfony Time Machine makes time-dependent Symfony code testable by letting you freeze, advance, or reset the application clock. Use it to create deterministic tests and simulate past or future dates without changing your system time.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. The first-order finding is unchanged by 0.1.1 and remains a framework mismatch: icanhazstring/symfony-time-machine is a Symfony bundle, not a Laravel package. It ships a Bundle subclass plus a DI extension and compiler pass, and is bootstrapped through config/bundles.php and the Symfony kernel. Laravel has no bundle loader — Illuminate\Foundation\Application cannot register a Symfony\Component\HttpKernel\Bundle\Bundle. A Laravel team therefore cannot "integrate" this package; it can only port the concept. That reframes the evaluation from "adopt" to "buy vs. build a ~100–200 LOC internal utility."

What changed in 0.1.1. A single patch release containing one PR, "Add timemachine handlers." It is the first activity since 0.1.0 (2022-10-14). The release notes give no detail on what a "handler" is — HTTP kernel handler/attribute, console command, message handler, or a clock-handler abstraction. That ambiguity is itself a data point: the changelog is a PR title, the source remains the spec, and the maintainer has added surface area without documenting it. Nothing in 0.1.1 addresses the framework mismatch, adds Laravel support, or adds dependents. It does not change the recommendation, but it does add entry points a reviewer must now enumerate before deciding anything about security exposure.

The underlying capability — mutating the application's notion of "now" so time-dependent logic (trial expiry, TTLs, scheduled promotions, aging workflows) can be exercised without waiting — is genuinely useful and legitimately hard to test otherwise. The value is in the pattern, not in this artifact.

Integration feasibility.

  • Symfony shop: feasible. Composer install, register in dev/test environments only, decorate the clock service, and now additionally audit whatever the new handlers expose (likely the operator-facing trigger surface).
  • Laravel shop: not feasible without a shim. The Laravel-idiomatic equivalent is a service provider that binds a Clock contract and calls Carbon::setTestNow() / Carbon::setTestNowAndTimezone(), optionally driven by middleware reading a header or session key.
  • Either way the enabling mechanism matters: if the bundle decorates Psr\Clock\ClockInterface / Symfony\Component\Clock, it only affects code that injects the clock — any legacy new \DateTime() or date() call site bypasses it. Coverage is partial by construction. The new handlers may widen the trigger surface without widening the capture surface; those are different problems.

Technical risk (high).

  • Abandonment (marginally softened, not resolved). Prior release 2022-10-14; 0.1.1 is a heartbeat, not a cadence. Still 7 stars, 0 dependents, single-maintainer bus factor. One patch release after a two-year gap does not constitute a maintenance commitment, but it does preserve the option to send upstream patches to a fork rather than owning a dead branch outright. Composer constraints likely still pin symfony/framework-bundle ^5|^6 and PHP 7.4/8.0–8.1, which will collide with Symfony 7 and PHP 8.3+ — verify, do not assume the new release relaxed them, since a feature PR often ships without dependency housekeeping.
  • New, undocumented surface area. "Handlers" plausibly means additional ways to invoke a time shift. Every new entry point is a new security boundary. Treat 0.1.1 as increasing the review burden, not decreasing it.
  • Scoring anomaly. A composite score of 0.935 sits awkwardly against opportunity: 2.67, 7 stars, and zero dependents. Treat the composite as unreliable; the opportunity sub-score is the honest signal.
  • Global mutable state. Time travel is process-wide. Under long-running workers (Octane, RoadRunner, Swoole, Symfony Runtime) a shift leaks across requests; in test suites it leaks across test cases and produces order-dependent flakes.
  • Security posture. If reachable in anything but local/test, an attacker-controlled time shift bypasses signed-URL expiry, password-reset token TTLs, JWT exp/nbf, TOTP windows, and rate-limit buckets. This must be hard-gated by environment and an explicit config flag, never by request input alone. If 0.1.1 adds a handler that reads from a request, that gate is now load-bearing in a way it previously was not.
  • Licensing is clean (MIT), so forking or reimplementing is unencumbered.

Key questions for the spike.

  1. What exactly does it mutate — a PSR-20 clock decorator, symfony/phpunit-bridge's ClockMock, or a custom service? (Determines coverage.)
  2. New in 0.1.1: what are the "timemachine handlers"? Are they HTTP-request handlers, console commands, kernel event listeners, or message handlers? Which are registered by default, and are they default-off?
  3. Does it expose an HTTP surface, a console command, or a profiler panel — and is that surface default-off?
  4. Did 0.1.1 touch composer.json constraints? Are they satisfiable on our PHP 8.2/8.3 and Symfony 6.4/7.x matrix?
  5. Does the shift propagate to queue workers, scheduler, and sleep()-based retry logic, or only the request process?
  6. Is the shift per-request or global for the process lifetime?
  7. What breaks when time is rewound — cache entries, signed URLs, and DB created_at rows written under shifted time?

Integration Approach

Stack fit. If the target is Laravel, close the package question and open a build ticket. The shim is small: one TimeMachineServiceProvider (bound to local/testing), a Clock binding or Carbon::setTestNow() call, and one middleware reading a test-only header or session key. Reimplementing costs roughly a day and yields a dependency we control, versus a fork of a barely-maintained bundle we would own anyway. 0.1.1 does not change this calculus; if anything the new handlers are Symfony-shaped plumbing we would not reuse.

If the target is genuinely Symfony, adopt with a fork: register the bundle in config/bundles.php only under dev and test, pin a vendored fork if composer constraints need loosening for Symfony 7, and review the new handlers before enabling them.

Migration path. There is no migration — nothing depends on this package, so there is no prior art to be compatible with and no downstream consumers to break. That is a benefit: we can define the contract ourselves (e.g., App\Contracts\Clock, TimeMachine::freeze()/travelTo()/reset()), and it also means zero ecosystem validation of the package's design. Note that 0.1.1 is a patch bump from 0.1.0, so any early adopter pinned at ^0.1 gets the new handlers automatically — which is the migration risk in miniature: new trigger surface arriving without a minor version or documented opt-in.

Compatibility. Verify before anything else: composer why-not against the current framework and PHP versions, re-run after 0.1.1 rather than reusing prior results. Expect friction on PHP ≥ 8.2 and Symfony ≥ 7. Also confirm whether it requires symfony/clock or psr/clock — if the codebase still calls now(), Carbon::now(), and date() directly rather than injecting a clock, the decorator approach yields false confidence. Grep for direct time calls first; that grep is the real integration cost, not the package.

Sequencing.

  1. Day 1 — spike: install/read source, diff 0.1.0→0.1.1 to enumerate exactly what the handlers add, answer the seven questions above, run composer why-not.
  2. Day 2 — decision: fork-and-patch vs. reimplement. Default to reimplement on Laravel; fork only if Symfony and the source is clean. The new handlers are now part of what must be "clean."
  3. Week 1 — test harness first: wire the clock into PHPUnit/Pest, add reset() in tearDown, and prove no cross-test leakage with a shuffled-order run.
  4. Week 2 — local dev affordance: opt-in header/middleware, gated on environment and config flag. If reusing the bundle, this is where the new handlers get evaluated for exposure.
  5. Later — ephemeral staging only, if at all, behind an explicit allowlist and audit log. Never production.

Operational Impact

Maintenance. We inherit full ownership on day one. Zero dependents and a sparse release history mean no upstream will absorb our patches at any reliable cadence; the 0.1.1 release is evidence the maintainer is alive, not evidence of a support commitment. Treat this as an internal utility that happens to have a public ancestor. Budget ~0 recurring cost for the reimplementation and ~1–2 days/year if we fork (dependency bumps, Symfony/PHP upgrades) — plus one review pass now to understand the new handlers.

Support. Effectively none. 7 stars, one maintainer, no issue triage, changelog reduced to PR titles. Documentation is thin — the source is the spec, and 0.1.1 makes that more true, not less. Plan for a developer-day of source reading during ramp-up, with extra time for the handler diff.

Scaling. Runtime cost is negligible — a single service decoration. The scaling risk is concurrency semantics, not CPU: under Octane/workers, process-static state means a shift applied for one request can bleed into the next. Either scope the shift to a request lifecycle with guaranteed teardown in a finally, or restrict the feature to short-lived CLI/test processes. Queue workers need explicit propagation or they will silently run on real time while the web tier runs on shifted time — a subtle, hard-to-diagnose inconsistency. Additional handler entry points multiply the number of places teardown must be guaranteed.

Failure modes to design against.

  • Test-order leakage → flaky CI; mitigate with hard reset() in teardown and randomized-order runs.
  • Cache/artifact staleness → values computed under shifted time (TTL keys, signed URLs, derived dates) become wrong when time is restored; flush affected caches on reset.
  • Auth/expiry bypass → TOTP, JWT, reset tokens, signed URLs; mitigate with environment + config gating and an audit log of every shift. The new handlers widen this attack surface until proven otherwise.
  • Data integrity → rows written with shifted created_at/updated_at; acceptable in ephemeral environments only, never against a shared or production-adjacent database.
  • Partial coverage → direct date()/now() call sites ignore the shift, producing false confidence in tests. Track coverage of clock injection as a first-class metric.
  • Silent upgrade → a ^0.1 constraint pulls new trigger surface on composer update; pin exactly if we vendor it at all.

Ramp-up. Low for Symfony-fluent engineers (familiar DI compiler-pass model), moderate for a Laravel team building the shim (provider + middleware + test harness, ~2–3 days including documentation). The organizational risk is not skill but discipline: an unguarded time machine is a security control bypass, so gate it in code review and in CI config policy.

TPM recommendation. Unchanged, and 0.1.1 does not move it. Do not adopt the package as a dependency. Port the capability (~1–3 days) behind an environment-gated, request-scoped clock abstraction, and invest the saved effort in removing direct time calls from the codebase — that refactor, not the time machine, is what actually makes time-dependent logic testable. The only follow-up 0.1.1 earns is a half-day source read to confirm what the handlers expose; if it turns out they add a request-reachable shift trigger without a hard config gate, that is a reason to strengthen the recommendation, not weaken it.

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.
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
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk