Open source · MIT · No dependencies
Point it at a topic. It crawls GitHub and npm for candidates, puts each one to a decision model with a single typed question, and keeps the entries the model is confident about. Then it writes your README and rebuilds your site, every day, without you.
// The one sentence that defines your list. // Everything else in the repo is plumbing. { "judge": { "criterion": "A repository qualifies when its own code calls, wraps or extends the library. It does not qualify when it only mentions it, or is a list of other people's projects.", "listAt": 0.75, "rejectAt": 0.45 } }
GitHub search and npm, sharded past the 1000-result cap, with cheap regex scoring to decide what is worth a judgement.
Each candidate goes to a decision model as state, with your criterion as a single typed question. It returns a probability.
Confident yes is listed, confident no is dropped. The band between lands in a file for you, and your call is permanent.
The list is written between markers in your README and into a searchable static site. A scheduled Action commits both.
Why not just grep
Search for a library name and you get every awesome-list clone, every "models we support" table, and every project that happened to use the word. That is why hand-maintained lists go stale: filtering the noise is the work, and nobody wants to do it twice.
Asking a model one typed question per candidate moves that work off your desk and leaves a number behind - so a reader can see on what basis each entry got in, and you can be challenged on it.
The judge
These are decision models, not chat models: they take a state and a map of typed questions, and return a calibrated probability for every allowed option. Set credentials for one and the framework resolves the rest.
| Model | Provider | Size | Input price |
|---|---|---|---|
@cf/cloudflare/clef |
Cloudflare Workers AI | 27B, multimodal | $0.24 / 1M tokens |
@cf/cloudflare/clef-flash cheapest |
Cloudflare Workers AI | 9B, multimodal | $0.09 / 1M tokens |
jev-latest |
TypeSafe System One, direct or via Vercel AI Gateway | - | see provider |
Only tools/lib/judge.js knows which vendor answered. Swapping providers is an environment variable, not a refactor.
The number says how confident the model was that an entry meets your criterion. It is not a quality score, and the site says so on every card.
Judging a few thousand candidates costs cents. The GitHub API rate limit is what actually sets the pace of a run.
What you get
The list is rendered between two markers, so your hand-written introduction is never touched. Categories, star counts and trending entries are regenerated every run.
Filter, sort and search the list in the browser. Generated from your config, served by GitHub Pages, no build step and no framework.
It fetches the largest rival lists on your topic and records which of them already list each entry. That turns "you will not find this elsewhere" into a claim someone can verify.
Every entry, verdict and dismissal is JSON in the repo. When the crawler does something strange, git diff shows you exactly what and when.
Quickstart
Copy the example topic, write your criterion, add one provider's credentials as repository secrets, and run it. When a manual run looks right, uncomment the schedule and leave it alone.
# one provider, in .env.local or the environment CLOUDFLARE_ACCOUNT_ID=... CLOUDFLARE_API_TOKEN=... npm run fetch # discover and score candidates npm run judge # put the queue to the model npm run refresh # stars and push dates npm run coverage # what rival lists already have npm run render # README.md and site/ npm run update # all of it, in order
Honest status
awesome-x is the extraction of a crawler that has been running daily since September 2026 - same pipeline, same coverage check, with the topic-specific parts lifted into config. The framework itself is days old. The Cloudflare path is written to Cloudflare's published request shape but has not yet been run against a live key, so treat the first run as the real test, and open an issue when it is not.
Built with it