amrshawky/currency
A Laravel/PHP package for currency exchange rates and conversion, with a clean API for fetching rates from multiple providers, converting amounts between currencies, and caching results for fast, reliable performance in your applications.
Architecture fit
amrshawky/currency is a framework-agnostic PHP client that wraps the public exchangerate.host HTTP API for current, historical, and crypto rates. It is not a Laravel package in the conventional sense — no service provider, no publishable config, no facade — so in a Laravel codebase it lands as a plain Composer dependency instantiated directly wherever conversion is needed. That is the core architectural concern: left unwrapped, it becomes a hard-coded outbound HTTP dependency scattered across controllers, jobs, and Blade views, with no seam for caching, mocking, or provider substitution.
The correct fit is as an infrastructure adapter behind a first-party ExchangeRateProvider interface (e.g., rate(string $base, string $quote, ?Carbon $date): Money), bound in a service provider. In that position it is perfectly serviceable. In any other position it is a liability, because the package is archived, unmaintained, and entirely dependent on a third-party free API whose commercial terms have changed since the release.
Integration feasibility
Low effort, high uncertainty. Installation is a single composer require, and the API surface is small enough to read in an afternoon. The blockers are not integration complexity but contract risk:
exchangerate.host endpoint. That upstream has since moved to an access-key model with tiering and rate limits. There is a strong likelihood the package fails out of the box with 401/403 or a changed response shape. This must be validated in a spike before any planning commitment.Technical risk
| Risk | Severity | Notes |
|---|---|---|
| Abandoned upstream (archived) | High | No fixes, no security patches, no API-drift response |
| Third-party free API with no SLA | High | Rate limits, key requirements, or shutdown would break us silently |
| Supply chain / low scrutiny | Medium | 27 stars, single maintainer, minimal external review of what runs in-process |
| Money-handling correctness | High | Float arithmetic on rates without a documented rounding policy |
| Crypto rate exposure | Medium | Volatile, and may carry regulatory/sanctions implications depending on use |
| License | Low | MIT — fork-friendly, no legal obstacle to vendoring |
Key questions
exchangerate.host access key, or is the plan to move to a different provider entirely?Stack fit
Composer-installed PHP library; consumable from any Laravel 8+ application on PHP 8.x, subject to dependency-conflict verification. It does not participate in Laravel's container, config, or queue systems natively, so the integration work is entirely ours: a config file for base URL/key/timeouts/cache TTL, an interface, an adapter, a service-provider binding, and a facade only if the team insists on one.
Migration path
Adopt-with-a-fork, not adopt-as-is. Because the package is small and MIT-licensed, the pragmatic path is to vendor the source into our own namespace (e.g., App\Support\Fx\ExchangerateHostClient) or a private fork. That converts an unmaintainable dependency into ~a few hundred lines of owned code, removes the abandoned-upstream risk from the equation, and lets us patch the request/response handling for the current API in the same PR. Public API of the adapter stays stable, so a later swap to a maintained client or a different provider is a one-class change.
Compatibility
Pin the exact version, verify Composer resolution against the target Laravel major, run the suite on the target PHP minor and watch for deprecations, and confirm the current exchangerate.host request/response contract against a real key in a throwaway test. Do not assume 2021 behaviour still holds.
Sequencing
ExchangeRateProvider interface and a Money/rounding policy agreed with finance.Cache::remember keyed by base/quote/date. Historical rates are immutable — cache indefinitely. Spot rates get an explicit short TTL.Maintenance
Effectively 100% internal. An archived package receives no bug fixes, no dependency bumps, and no response to upstream API changes — and the upstream has already changed once. Budget ongoing ownership: a named maintainer, dependency review on each Laravel upgrade, and a scheduled quarterly check that the provider contract still holds. The vendored-fork approach makes this tractable; using it as an unmodified dependency does not.
Support
No vendor support, no active community (27 stars, single maintainer), no documented escalation path. Any incident is ours to diagnose. Mitigation is documentation: a runbook covering how to switch providers, how to purge the rate cache, and what to do when the provider returns 401/429/5xx.
Scaling
Every uncached lookup is a synchronous outbound HTTP call. On a free tier this becomes the first bottleneck — rate limits will be hit before latency becomes the problem. Scaling levers, in order: aggressive caching with correctness-aware TTLs; batch/multi-symbol queries instead of N per-pair calls; a scheduled sync job writing rates to a local table for high-volume paths so request-time conversion is a single indexed read; and queueing any non-interactive conversion work. Crypto volatility may require a shorter TTL than fiat, which argues for per-pair caching policy rather than one global TTL.
Failure modes
bcmath.Each of these needs an explicit product decision: fail-open to last-known-good (availability over accuracy) or fail-closed (accuracy over availability). That decision differs between a marketing price display and a booked receivable.
Ramp-up
Low for any PHP developer — the API is small and the mental model is a single HTTP call. Realistic estimate: 1–2 days to spike, wrap, and test the happy path; roughly one sprint-week to production-harden with caching, persistence, resilience, observability, and the provider-abstraction seam. The team should treat the ramp-up cost as small and the ownership cost as permanent.
Recommendation. Do not adopt as a standing dependency. Adopt the pattern — thin provider adapter behind an interface — and either vendor this small MIT-licensed client as owned code or go directly to a maintained provider client. The library is a reasonable reference implementation and a poor long-term dependency, and the archived status combined with a changed upstream API makes it unsuitable for anything touching money without an abstraction layer and a documented replacement path.
How can I help you explore Laravel packages today?