Awesome lists follow the same arc. Someone builds one with care, it is useful for about six months, and then it describes a weekend three years ago.
The links still resolve, which is what makes it hard to notice. A repository archived two years ago has a good README, a plausible star count, and no indication that nothing has been merged since. You find out after you install it.
The cause is structural. A list is research done once, and a pull request only ever adds. Nobody browses a list they already published looking for things to delete.
So I built one where removal is automated and addition is the manual part.
The figures are pulled, not typed
Every entry resolves against the Packagist and GitHub APIs on a schedule:
schedule:
- cron: '17 6 * * *'
Star counts and install counts in the table are fetched. A hand-typed star count is wrong the day after you type it, and a reader has no way to tell how stale it is.
The rendered list carries the timestamp of its last refresh, so the figures are either current or visibly not.
Three ways an entry earns removal
The same job that fetches the numbers evaluates whether an entry still belongs:
const STALE_AFTER_DAYS = 365;
archived: Boolean(gh.archived),
abandoned: Boolean(p.abandoned),
stale: idle !== null && idle > STALE_AFTER_DAYS,
Archived on GitHub means the author has said in the clearest way the platform offers that the project is finished.
Marked abandoned on Packagist is the PHP ecosystem's explicit field for this, and tooling underuses it. Composer will tell you at install time, so a list that does not check it hands you a warning you get later.
Quiet for over a year is the soft one. A year of silence is not death, and plenty of small packages are simply finished. This warns instead of removing, and a person decides.
Two of the three signals are declarations by the author and can be acted on mechanically. The third is an inference, so it needs judgement.
Five went before the first commit
The list shipped with 58 packages across 10 categories, having already dropped five.
I found them by running the refresh against my initial research before publishing. Five entries that looked reasonable in a search result were archived or abandoned. Publishing first and automating later would have put all five in the launch announcement.
Run your freshness check before the first commit. The research phase is when your information is most likely to be stale, because search results have no opinion about whether a project is alive.
Validation runs before the network does
A second script checks the data file itself, and it runs first:
if (seen.has(pkg.packagist)) fail(`duplicate entry: ${id}`);
if (!CATEGORY_IDS.has(pkg.category)) fail(`${id} points at unknown category`);
if (!pkg.summary) fail(`${id} is missing "summary"`);
Duplicate entries, unknown categories, malformed vendor/package names, missing summaries. None of that needs an API call, so a bad pull request fails in a couple of seconds instead of after a hundred network round trips.
A contributor who typo'd a category name gets told in three seconds.
What I would do differently
The one year threshold is a guess. I picked 365 days because it sounds reasonable, not because I measured anything. A better version would look at each package's own release cadence. A library that shipped twice a year for six years going quiet for fourteen months means something different from a weekly-release project going quiet for three.
Download counts flatter incumbents. A package with 100,000 installs and no commits in two years outranks a better-maintained newcomer on every visible figure. I show the numbers because hiding them would be worse, but sorting purely by them recommends the past.
Automation cannot judge quality. It can tell you a package is alive. Whether it is any good still takes a person reading the code, and that does not scale, which is why curated lists remain worth having.
The gap it fills
The general Laravel lists are much larger and better established. chiraggude/awesome-laravel alone has over 13,000 stars, and they are excellent.
They also predate this category almost entirely. Laravel AI tooling, MCP servers, agent frameworks, RAG and evaluation packages arrived after those lists took their shape, and retrofitting a new top-level section into a list with a decade of structure is a harder ask than starting one.
So: 58 packages across multi-provider abstractions, provider SDKs, MCP, agents and orchestration, RAG and vectors, AI-assisted development, evaluation, token optimisation, content discoverability and utilities.
awesome-laravel-ai. Pull requests welcome, and the validator will tell you in three seconds if the entry is malformed.
Top comments (0)