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

Toggle Laravel Package

qandidate/toggle

Qandidate Toggle is a PHP library for managing feature toggles (feature flags) in your applications. Define toggles, activate them conditionally with strategies, and roll features out safely without redeploying code.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. qandidate/toggle is a framework-agnostic PHP library built around a narrow, useful domain model: a toggle (named feature) holds a collection of conditions, each condition being an operator + key + operand evaluated against a context array; a repository abstraction (ToggleRepository, with in-memory and key-value/Redis-style implementations) persists toggle definitions. That is a decision engine, not a flag-management platform. It has no HTTP layer, no admin API, no audit trail, no events, and no Laravel coupling — which is simultaneously its strength (clean seam, easy to bind into the container) and its cost (all the platform around it is yours to build).

Integration feasibility. composer require qandidate/toggle is trivial; the real work is glue you must write: a service provider, a config file, a facade/contract, and a repository choice wired to your Redis instance. Effort: roughly 1–3 engineer-days for a production-credible wrapper with tests, assuming Redis is already available; 1–2 weeks if you also want an admin surface, per-flag caching, and rollout semantics. There is a first-party Symfony bundle in a separate repo — do not install it in a Laravel app; it drags Symfony dependencies for functionality you will reimplement in ~80 lines.

Technical risk.

  • Maintenance risk (highest). 379 stars and 0 known dependents is a thin adoption signal for infrastructure that gates production behaviour. The stated 2026-08-09 release date should be verified against commit cadence and issue responsiveness — a metadata bump is not a roadmap. Treat this as a library you may end up forking; MIT makes that legal and feasible, but it becomes your code.
  • Semantic risk. The condition/operator model is attribute-comparison oriented. Verify whether percentage rollouts, sticky bucketing, prerequisite flags, and evaluation analytics exist — if not, do not use this for growth experiments or A/B testing; use it for release/ops/entitlement flags only.
  • Hot-path risk. Naive usage means one store round-trip per flag per request. Without request-scoped memoisation this becomes a latency and Redis-load problem at scale.
  • State-leak risk. If you memoise toggles in a singleton for performance, long-lived workers (Octane, queue workers) will serve stale or cross-tenant flag state.
  • Security risk. Flags guarding entitlements, admin routes, or paid features must never be evaluated from client-controllable context; the condition model makes it easy to write user_id conditions that are only as trustworthy as the caller's input.

Key questions to answer before committing.

  1. What PHP versions and Predis/ext-redis majors does composer.json actually permit versus our Laravel 11 / PHP 8.3 baseline?
  2. Is there any native percentage rollout or is that always a hand-written custom operator?
  3. What is the documented behaviour when the backing store is unreachable — exception, or default-inactive?
  4. Does the repository interface allow batch-loading a whole toggle set in one call (needed for per-request caching)?
  5. Who owns this in our org, and are we prepared to fork and maintain it if upstream goes quiet for 12 months?
  6. What is our exit cost if we later standardise on Unleash/LaunchDarkly/Flagsmith?

Integration Approach

Stack fit. The library's shape fits Laravel well — bind a repository in a service provider, expose a thin facade, keep evaluation in the domain layer. The version era is the concern: it is a PHP 7-generation package. Validate against PHP 8.2/8.3 for deprecations before any design work; if it emits notices under 8.3, that is a fork-and-patch decision, not a blocker.

Recommended pattern — wrap, don't call directly. Define an application-owned contract (e.g. App\FeatureFlags\Flags with active(string $flag, array $context = []): bool) and implement it with qandidate internally. Every call site depends on your interface. This costs half a day, makes the package swappable, gives you a single place to add caching, logging, fail-open/fail-closed policy, and test doubles, and is the single highest-leverage decision in this assessment.

Migration path. Typical starting state is env()/config flags or a hand-rolled config('features.*') array. Sequence: (1) introduce the Flags contract backed by config, so call sites change once; (2) swap the implementation to qandidate with the in-memory repository to keep dev/test hermetic; (3) point staging/prod at Redis. This ordering means feature-flag call sites are converted before the provider is risked. If instead you are migrating off a hosted vendor, keep the contract provider-shaped so both can run in parallel for a release cycle.

Compatibility specifics to pin.

  • Redis client: if Laravel already pulls Predis, force the package to reuse that client rather than adding a second connection stack; otherwise prefer ext-redis and one adapter.
  • Key namespace: use a dedicated prefix (and ideally a separate logical DB) so FLUSHDB or key-scan operations from other systems cannot wipe your flag set.
  • Do not back the repository with Laravel's cache repository — flags are authoritative state, not a cache; mixing them invites silent revert-to-default bugs.
  • Octane: register the manager as scoped, not singleton, or explicitly reset per request.

Sequencing (suggested 4–5 weeks elapsed, part-time).

  1. Spike, 2 days: install in a branch, prove install + Redis round-trip + one condition evaluation on the real PHP/Laravel baseline. Go/no-go.
  2. Contract + provider + config + in-memory default (3–4 days), with tests.
  3. Redis repository in staging (2–3 days): namespacing, per-request batching, fail-mode policy, metrics.
  4. Pilot three flags (3–5 days): one kill switch, one entitlement, one internal rollout. Deliberately cover the three risk classes.
  5. Operations layer (optional, 1–2 weeks): Artisan commands, an admin UI or Nova resource, expiry metadata, evaluation logging.
  6. Rollback plan: every flag must have a documented safe default, and the kill-switch class must fall back to a deploy-time env path if Redis is unavailable.

Operational Impact

Maintenance. Plan for custodianship, not consumption. Budget a named owner plus a recurring dependency-review task (PHP minor bumps, Predis majors, security advisories). Because MIT permits forking, the realistic end state for a long-lived dependency is "vendored fork with our patches" — acceptable, but it should be a conscious, documented decision rather than an incident-driven one.

Support. Community-only, small audience, no SLA and no visible CVE process. That is fine for internal rollout flags and unacceptable as the sole control for a security boundary. Pair any entitlement flag with an independent server-side authorisation check.

Scaling. The workload is read-heavy and write-rare — a good architectural fit. Load the full toggle collection once per request (not once per flag), memoise within request scope, and reset on worker recycle. With that pattern, cost is a single Redis GET per request and negligible evaluation overhead. Writes go through your admin layer, not the request path; keep them rare. Multi-region is the sharp edge: independent Redis stores mean flags can disagree across regions for seconds to minutes, so global kill switches should live in config/deploy artefacts, not in a replicated key-value store.

Failure modes to design for explicitly.

  • Store unavailable — choose per flag class: fail-closed for entitlements (feature disappears), fail-open only for cosmetic/experimental flags. Make this a config property of the flag, not a global guess.
  • Malformed toggle definition — one bad condition set can throw during evaluation and take down a request path; wrap evaluation and degrade to the default.
  • Missing context key — comparison against absent attributes; confirm the unknown-operator behaviour rather than assuming.
  • Stale cache / stale flags — two distinct problems: short-TTL caching risks flip-flop after a change; long-lived flags become permanent, undocumented branches in code. Enforce owner + expiry metadata at creation.
  • Type coercion — string vs integer comparison in operators produces flags that "work" in staging and silently mis-target in production.
  • Flag debt — without a cleanup ritual, the toggle set becomes an unreadable second configuration system within a year.

Ramp-up. The API surface is small; a mid-level Laravel developer is productive in under a day, and the wrapper contract means they never touch qandidate directly. The real ramp-up cost is organisational, not technical: naming conventions, default-state policy, fail-mode classification, expiry discipline, and a documented list of who may flip what in production. Write that one-page convention document before the pilot, not after — it is cheaper than retrofitting semantics onto a few hundred call sites.

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.
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons