wikimedia/alea
Alea is a PHP port of the Alea pseudo-random number generator, providing fast, seedable, deterministic random values. Useful for simulations, games, and tests where reproducible output matters.
What the package actually is. wikimedia/alea is Wikimedia's randomness abstraction for PHP: a thin, swappable layer over ext-random / random_bytes that MediaWiki core consumes for token generation, ID/nonce creation, shuffling, and randomized sampling. Its distinguishing feature versus plain random_int() is the pluggable generator source — you can inject a deterministic source in tests and a CSPRNG-backed source in production, from one call site. The GitHub repo is a read-only Gerrit mirror; stars, issues, and "0 dependents" are artifacts of that mirroring, not signals of adoption. The actual consumer base is MediaWiki's install footprint, which is very large.
Architecture fit. Poor-to-neutral for a typical Laravel app. Laravel's randomness needs are already covered three ways: random_int()/random_bytes() for security tokens, Str::random()/Str::uuid()/Str::ulid() for identifiers, and Faker for test fixtures. Alea fits only if we have a specific architectural requirement: a single, injectable, auditable randomness boundary — most commonly for testable determinism in code whose output is otherwise nondeterministic (invite codes, A/B bucketing, sampling, replayable fixtures). That's a real but narrow requirement. There is no service provider, no config surface, no Laravel-native API; it's a library of a few hundred lines.
Integration feasibility. Trivial mechanically: composer require wikimedia/alea, one container binding, a handful of call-site swaps. No migrations, no published config, no bootstrapping. The blocking question is not "can we" but "should we."
Technical risk. Low runtime risk, elevated lifecycle risk:
ext-random; each major is coupled to a minimum PHP version. A PHP upgrade in our platform becomes a dependency upgrade we must sequence.Key questions I'd want answered before approving:
Random\Randomizer already gives us an injectable object with the same ergonomics)?Str::random, Ramsey\Uuid, and Faker in our codebase, and who owns enforcing that boundary?Stack fit. Fine for Laravel 10/11 on PHP 8.1+, comfortable on 8.2+. It's framework-agnostic and composes cleanly with the container. The practical tension: on PHP 8.2+, Random\Randomizer with a Random\Engine is a first-party equivalent of exactly the pattern Alea provides. Alea's remaining edge is portability to PHP 8.1 and MediaWiki-adjacent conventions — neither of which typically matters in a Laravel shop.
Migration path. Side-by-side, incremental, no data migration:
RandomnessInterface (token(), int(), bytes(), shuffle(), pick()).testing, CSPRNG in everything else.Str::uuid()/Str::ulid() untouched; they aren't the problem Alea solves.If the interface is the valuable part, we can ship it with a native Random\Randomizer adapter as the default implementation and add the Alea adapter only where PHP 8.1 support is still needed. That converts this from a dependency decision into a design decision.
Compatibility. Coexists cleanly with Faker, Str::random, and native random functions — there's no global state in the package itself. Two real hazards: (a) composer resolution conflicts if another package pins a different alea major, and (b) test-suite state bleed — a deterministic generator seeded once will make unrelated tests order-dependent unless reset in setUp/tearDown or bound as a fresh instance per test.
Sequencing. Decide-native-first → spike behind the interface in one service → verify determinism story in CI → roll out to high-value call sites → leave the long tail alone. Do not attempt a repo-wide sweep; the value doesn't scale with coverage.
Maintenance. Low volume, low surprise: releases track PHP version drops more than features. The standing obligation is a line item in each PHP upgrade checklist ("re-verify alea major against new PHP"). Contributions go through Gerrit with a Wikimedia developer account — if we ever need a patch, the realistic path is a local fork rather than upstream. At a few hundred lines, forking is genuinely cheap; that materially de-risks the abandonment scenario.
Support. Community/self-support. No commercial backing, no SLA, no GitHub triage. Acceptable only because the code surface is small enough for one engineer to fully read and own in an afternoon. Budget that reading time as onboarding, not as ongoing load.
Scaling. Effectively free at runtime — it delegates to random_bytes/Random\Randomizer, holds no I/O, no locks, no persistent state. No throughput concerns at any realistic request volume. The scaling-adjacent benefit is test-suite determinism, which shortens CI debugging on flaky, randomness-dependent tests.
Failure modes, ranked by severity:
testing.ext-random can throw on entropy exhaustion; it surfaces as an uncaught exception on a hot path (login, token issuance). Wrap at the interface boundary with a clear error path.Ramp-up. Hours. One engineer, one afternoon, plus a short design note documenting the interface boundary and the "never seed in production" rule. The technical onboarding is cheap; the discipline cost — resisting the temptation to make production behavior "reproducible for debugging" — is the thing that needs an explicit written policy.
Bottom line for the roadmap. This is a legitimate, well-built small library with a real problem statement that most Laravel apps don't have. My recommendation is to adopt the pattern (an injectable randomness boundary with a deterministic testing mode) rather than the package, unless we're pinned to PHP 8.1 or need MediaWiki parity. If we do take the dependency, wrap it so the vendor namespace never appears in domain code, and treat the seeding rule as a security control with a test enforcing it.
How can I help you explore Laravel packages today?