Live catalog of known external PhoenixKit packages fetched from Hex.pm.
Fetched on demand and cached in an ETS table for 10 minutes. On Hex
failure, returns stale cached data when within the 24h max-stale-age
cap, otherwise returns extra_known_packages config entries only.
Cache uses an ETS named table (:phoenix_kit_known_packages_cache) with
read_concurrency: true rather than :persistent_term, to avoid
global-GC write amplification on multi-node cold deploys.
Public API
list/0andlist/1— return the catalog (cached).clear_cache/0— wipes the cache (for tests).
list/1 accepts opts (intended for tests, not production):
:ttl_ms— cache TTL (default:timer.minutes(10)):max_stale_age_ms— how long stale data may be served on Hex failure (default:timer.hours(24)):req_options— pass-through toReq.get/2
Operational signals
Hex outages emit Logger entries at three levels — each maps to a distinct degradation state operators can alert on:
:warning"Hex fetch failed … serving stale data" — cache hit withinmax_stale_age_ms. Catalog still works; Hex briefly unavailable. Transient.:warning"Hex fetch failed … no cached data" — Hex unreachable AND cache empty. Catalog shows config extras only. Visible degradation, but not a crisis (admin Modules page is the only consumer).:error"Hex fetch failed … exceeds max stale age" — Hex unreachable for overmax_stale_age_ms. Cached entries dropped, catalog falls back to config extras. The escalation level: page on this if it persists.
Summary
Functions
The human equivalent of the search this module runs against the Hex API.
Clears the in-process cache. Intended for tests.
Returns the list of known external PhoenixKit packages.
Whether the last catalog read reached hex.pm.
Functions
@spec browse_url() :: String.t()
The human equivalent of the search this module runs against the Hex API.
Offered when hex.pm is unreachable: a link stays current because Hex maintains it, where a catalog bundled into core would need a core release to add a package and would drift permanently.
@spec clear_cache() :: :ok
Clears the in-process cache. Intended for tests.
Returns the list of known external PhoenixKit packages.
Each entry is a map with keys: key, module, package,
hex_package, name, description, icon, hex_url, github_url,
latest_version, source.
See module doc for opts.
@spec status() :: :ok | {:stale, non_neg_integer()} | :unavailable
Whether the last catalog read reached hex.pm.
:ok — fresh data. {:stale, age_minutes} — hex.pm was unreachable but
cached data is still being served. :unavailable — unreachable with nothing
usable cached, so list/1 returned config extras only.
The UI needs this because "hex.pm is down" and "there are no packages" produce the same empty list, and showing the second when the first is true tells the operator something false.