Refolk
PlaybookEngineering and open source

Mapping the Repository Landscape Around One Seed Project

You will turn a single seed repository into a deduplicated, ranked landscape map where every project is classified as an alternative, dependent, or adjacent tool with evidence recorded.

16 min readLast reviewed August 5, 2026Read as Markdown

Key takeaways

  • GitHub's own dependent counts are explicitly approximate, and a peer-reviewed study measured roughly 20% errors in dependencies and 10% in dependents, so a defensible map shows a range across sources rather than one figure.
  • GitHub's 'Used by' figure represents a single package and never appears below 100 dependents, so a monorepo publishing ten packages can look far smaller than a single-package rival.
  • Reverse-dependency completeness is language-dependent: deps.dev indexes 7 ecosystems but resolves full graphs for only 5 and has none for C or C++, so coverage silently varies with the seed's language.
  • Percentile-rank scoring survives leadership review where raw thresholds do not, because one dominant dependent (75th percentile gives 0.75) cannot swamp the ranking.
  • Fork, mirror, template, and archive exclusion must happen before scoring, following the Linux Foundation recipe, or the map ranks duplicates.
  • In Refolk's index the US DevRel population outnumbers Germany's by about 11.7x and US leadership is only about 18% of the US base, so competitive-landscape work concentrates in a thin senior pool.

You have one repository you care about, and you need to know the whole neighbourhood around it: the direct alternatives, the projects that depend on it, and the adjacent tools that share its domain but do a different job. This playbook is for engineering managers, technical founders, developer-relations leads, and technical sourcers who need that map to survive scrutiny. It sequences the free public sources into one repeatable pass and, just as important, tells you how to reconcile their conflicting, approximate counts instead of pretending one of them is truth.

Most pages on this topic either explain a single tool or hand you a generic list of places to look. Neither gets you to a finished artifact. By the end here you will have a deduplicated, ranked landscape map in which every project is labelled alternative, dependent, or adjacent, with the evidence behind each label written down.

What the finished landscape map contains

A finished map is a single ranked table of distinct projects, each tagged with one of three classes and the signal that earned the tag. Nothing in it is a fork, mirror, template, or archived repository, and no count appears without its source.

The three classes are not interchangeable, and the whole method exists to keep them apart:

  • Alternative - a project a user could choose instead of the seed. It shares the seed's core purpose, usually visible in overlapping topics or registry keywords.
  • Dependent - a project that builds on the seed. It appears in a reverse-dependency list for one of the seed's packages.
  • Adjacent tool - a project in the same domain that solves a different problem. It shares context but not purpose.

The reason to be strict about this is that the three come from different sources and carry different confidence. Dependents come from dependency graphs, which are approximate but machine-verifiable. Alternatives and adjacent tools come from topic and keyword overlap, which is a human judgement dressed as data. A map that blends them without saying which is which cannot be defended in a review.

A landscape map that hides its sources is a guess wearing the costume of a dataset.

The four sources and what each one actually covers

Four free sources feed this map, and each covers a different slice. No single one is complete, which is the entire reason the pass triangulates rather than trusting one number.

SourceEcosystems / managersReverse-dep unit
GitHub dependency graphSupported ecosystems, public repos onlyDependent repos + packages (approximate)
Libraries.io36 package managers100M declared dependencies
deps.dev7 (resolved graphs for 5)Resolved dependents

GitHub's dependency graph lists other public repositories that depend on the repository or on packages it publishes. It is not reported for private repositories, and GitHub Enterprise Server does not calculate dependents at all. You can filter the list to package-only dependents with the "Packages" toggle above it. Critically, there is no official count endpoint: GitHub does not return the "Used by" or dependents count through its REST or GraphQL API, so you either read the UI or run a community scraper against the Dependents page.

The open datasets extend past GitHub's graph. Libraries.io monitors over 2 million open source packages across 36 package managers, gathering license, releases, contributors, and dependency data; its published dataset holds about 2.5 million unique components, 9 million versions, and 100 million declared dependencies across 25 million repositories that use them. ecosyste.ms aggregates package registries, software repositories, vulnerability databases, containers, and operating systems, with a packages index on the order of 5,684,962 packages and 72,603,805 versions, and it exposes dependent-repository counts per package. Google's deps.dev supports Cargo, Go, Maven, npm, NuGet, PyPI, and RubyGems, but resolves full dependency graphs for only Go, npm, Cargo, Maven, and PyPI, and carries the fork and parent metadata you need to strip duplicates later.

5,684,962
Packages indexed by ecosyste.ms
With about 72.6 million versions, this is why registry data extends coverage past GitHub's own graph.

The end-to-end procedure

Run the eight stages below in order. The whole pass takes an analyst roughly four to five hours plus a half-hour reviewer pass, and the ordering matters: fork exclusion happens before ranking, not after.

One seed repo to a classified landscape map

  1. Fix the seed and its package identity
    Record the seed repository URL and every package name it publishes across registries. Done when you have the repo plus each ecosystem:package pair, because reverse-dependency lookups are per-package, not per-repo.
  2. Pull GitHub dependents
    Open the repo's Dependents tab, capture both the repository and Packages counts, and note the "Used by" figure. Because no API returns this, use the UI or a community scraper. Done when raw counts and top dependents are saved with a timestamp.
  3. Extend reverse deps via registries
    For each package, query ecosyste.ms and deps.dev for dependent repositories and packages. Done when every published package has a dependent list from at least one open source, covering ecosystems GitHub missed.
  4. Harvest alternatives and adjacent tools
    Walk the seed's GitHub topics and each registry keyword set, listing co-tagged repos, then add topic-page and registry-suggested neighbours. Done when you have a raw candidate pool with topic or keyword evidence attached to each entry.
  5. Deduplicate and drop non-competitors
    Using fork/parent, stars, and description metadata, collapse mirrors and exclude forks, mirrors, templates, and archived repos. Do this before scoring. Done when each surviving entry is a distinct, live project.
  6. Classify each project
    Label every entry alternative, dependent, or adjacent, recording the deciding signal: appears in the dependents list means dependent, shares core-purpose topics means alternative, shares domain but differs in purpose means adjacent. Done when no entry is unlabelled and each label cites its evidence.
  7. Rank by percentile-weighted score
    Score with a criticality-style weighted sum over free signals such as dependent count, recent commit activity, and contributor count, using percentile rank rather than raw values. Done when the map is sorted and each score is reproducible.
  8. Reconcile conflicting counts
    Where GitHub, ecosyste.ms, and deps.dev disagree, record all three and flag the roughly 20% and 10% error band. Done when every count shows its source and disagreements are annotated, not silently averaged.

The single pass, start to finish

  1. Seed identity
    List the repo and every ecosystem:package pair it ships.
  2. Gather dependents
    GitHub UI plus ecosyste.ms and deps.dev per package.
  3. Gather peers
    Topics and registry keywords give alternatives and adjacent tools.
  4. Deduplicate
    Drop forks, mirrors, templates, archived repos.
  5. Classify and rank
    Label each project, then score by percentile rank.
The map is built once, left to right, with deduplication deliberately placed before ranking.

Why step 1 is per-package, not per-repo

Reverse-dependency data is keyed on packages, not repositories. A repo that publishes three packages has three separate dependent lists, and GitHub's "Used by" sidebar shows only one of them. If you record the seed as a single URL and stop there, you will undercount a multi-package project against a single-package rival before you have gathered a single number. Write down every ecosystem:package pair first.

How to classify: the signals and when they lie

Classification turns on three signals, one per class. Each proves something specific, and each fails in a recognisable way. Record the deciding signal for every project so the classification is auditable rather than remembered.

ClassDeciding signalWhat it provesWhat it looks like when it lies
DependentAppears in a reverse-dependency listThe project builds on the seedA fork of the seed shows up in its own dependents list
AlternativeShares core-purpose topics or keywordsUsers could pick it insteadA repo tagged with a topic it has no code for
AdjacentShares domain topics, different purposeSame context, different jobA generic tag like library linking unrelated tools

GitHub topics are the primary machine-readable classifier. Topics appear on a repository's main page, and clicking one shows related topics and other repositories classified with it; registry keywords play the same role for packages. A repository allows a maximum of 20 topics, each up to 50 characters. But topics only work as a signal when they agree with the repository name, description, README, and actual code. A repo labelled kubernetes with no Kubernetes code has spent a free label to buy attention, and it will poison your alternatives list if you trust the tag alone.

There is no published numeric cutoff for how much topic overlap makes a project an alternative rather than adjacent. That threshold is not established publicly, so it is a choice you must make and write down. A workable default is: two or more shared core-purpose topics, confirmed against the README, counts as an alternative; one shared domain topic with a different stated purpose counts as adjacent. State whatever rule you pick at the top of the map so a reviewer can argue with it.

Once you have your dependents and peers gathered, the slow part is often the human layer: finding the people who maintain the leading alternatives, or the teams shipping the dependents, so you can act on the map. That is a plain-English search rather than another graph query.

Refolk turns the landscape map from a list of repositories into a list of people, which is usually the point of building it. Once you know the alternatives and dependents, you can ask for the maintainers, the DevRel leads at the companies shipping dependents, or the engineers who contribute to both the seed and its closest rival, without hand-assembling contributor lists from commit histories.

Ranking that survives a review

Rank by percentile rank of each signal, not by raw values, so one dominant project cannot swamp the map. This is the single change that separates a defensible ranking from one that collapses the moment an incumbent enters the set.

The OpenSSF Criticality Score is the reference model: a project's criticality score is a number between 0 (least critical) and 1 (most critical), computed from signals including project age, time since last update, contributor count, organization count, commit frequency, recent releases, closed-issue activity, and dependents count, with weights an end user can adjust. The Linux Foundation variant improves robustness by scoring on rank, not raw value: the scoring function is a linear combination where each term is the percentile rank of a project's signal relative to all others. More contributors than 75% of the set gives that signal a value of 0.75.

The reason to prefer percentile rank is concrete. In most niches one incumbent has orders of magnitude more dependents than everyone else. Sum raw dependent counts and that one project takes the entire top of your ranking while burying real differences among the rest. Convert every signal to its percentile first and the incumbent still ranks first, but the spread below it stays legible.

Reading a ranked entry at a glance

Active, frequent commitsStale, no recent commits
Niche and quiet
Note it, low priority to watch
Widely used but stalling
Watch closely, adoption may erode
New or narrow but lively
Track as an emerging alternative
Widely used and active
Treat as a primary competitor or dependency
Few dependentsMany dependents
Two axes worth plotting once the map is scored: adoption against how alive the project is.

A minimal, reproducible scoring rubric you can adapt:

Percentile-rank score for one project
score = 0.5 * pct(dependent_count)
      + 0.3 * pct(commits_last_90_days)
      + 0.2 * pct(contributor_count)

where pct(x) = fraction of projects in the set with a lower value than x
example: more contributors than 75% of the set -> pct = 0.75
output: a single 0-1 number; sort descending to rank the map

Compute each signal's percentile across the full candidate set, then combine. Adjust weights to your question and record them on the map.

How this goes wrong

The failure modes below are where landscape maps quietly become wrong. Each has a false positive that looks fine on the page, and each has a check. Treat this section as the load-bearing part of the method.

Trusting "Used by" as total demand. The "Used by" figure represents a single package from the repository and only appears once more than 100 repositories depend on that package. A multi-package seed is structurally undercounted, so a monorepo publishing ten packages can look far smaller than a single-package rival. Ranking on this figure alone rewards packaging shape, not adoption. Check: sum every package's dependents separately.

Treating GitHub counts as exact. They are explicitly approximate and may not match the dependents actually listed, and the peer-reviewed error rate is around 10% for dependents. The false positive is a clean-looking number no other source confirms. Check: cross-reference ecosyste.ms and deps.dev before trusting any single count.

Missing whole languages. deps.dev has no C or C++ data, so a systems-language seed looks unused when it is simply not indexed. Check: confirm the seed's ecosystem is actually covered before concluding low usage.

Counting forks as competitors. Popular repos carry thousands of forks that inflate the map and can even appear in dependent lists. Check: verify the fork/parent flag before labelling anything an alternative, and exclude forks, mirrors, templates, and archived repos early.

Keyword-only classification. A topic present in name only misleads. The classic false positive is a repo tagged kubernetes with no Kubernetes code. Check: confirm every classifying topic against the README and the code.

Averaging conflicting counts. Silently averaging GitHub against registry numbers hides the disagreement that is itself a finding. Check: record all sources side by side and annotate; never merge into one number.

Raw-threshold ranking. A single mega-dependent repo swamps raw sums. Check: use percentile rank so one outlier cannot dominate.

Who acts on the map, and how thin that pool is

A landscape map is only useful if someone senior owns the response to it, and that population is smaller and more concentrated than most teams assume. Competitive-landscape work in open source ecosystems tends to land on a handful of developer-relations owners rather than a broad bench.

In Refolk's index of professional profiles, the geographic and seniority distribution is stark:

MarketDevRel IC profilesTop employersRatio vs Germany
United States350Google, WP Engine, Telnyx11.7x
Germany30SAP, JetBrains, Siemens1.0x

The US developer-relations population outnumbers Germany's by about 11.7x. The seniority split narrows the pool further:

BandProfilesShare of US DevRel base
IC (Advocate / DR Engineer)350100% (base)
Leadership (Head/Director/VP)6318%

Leadership is only about 18% of the US base, so roughly 63 people carry the Head, Director, and VP of Developer Relations titles in the country's largest market. If your map is meant to drive outreach, competitive positioning, or hiring, the people who can act on it are a small, senior group. Plan the follow-through accordingly, and use the map's classified alternatives and dependents as the entry point to reach the right owners at each project rather than starting from scratch.

Before you call it done

Run this checklist before shipping the map. Each item is a specific thing to verify, not a topic to think about.

Landscape map release check

  • Every package the seed publishes has its own dependent list, not just the "Used by" sidebar figure.
  • Each dependent count shows its source (GitHub, ecosyste.ms, or deps.dev) with a timestamp.
  • The seed's ecosystem is confirmed as indexed by at least one open source before any "low usage" conclusion.
  • Forks, mirrors, templates, and archived repos were excluded before ranking.
  • Every project carries exactly one class label and the signal that decided it.
  • Every classifying topic was checked against the repository's README and code.
  • The alternative-versus-adjacent threshold is stated at the top of the map.
  • Ranking uses percentile rank of each signal, and the weights are written down.
  • Conflicting counts are recorded side by side and annotated, never averaged into one number.

Keeping the map current

The map decays as the ecosystem moves, so treat it as a living artifact with a re-check cadence rather than a one-time deliverable. The mechanisms that change are predictable: new packages get published, dependent counts drift, projects get archived, and topics get retagged.

Re-run the reverse-dependency pull whenever the seed publishes a new package, because a new ecosystem:package pair is a new dependent list you do not yet have. Re-check archived and fork status on the top-ranked entries on a fixed schedule, since a project that goes dormant should drop in the ranking. Because deps.dev data is licensed CC-BY 4.0 and clients may cache it, you can store a snapshot and diff against it on the next pass instead of re-fetching everything, which makes it cheap to see what moved. When two sources disagree by more than the known error band, that gap is a signal worth investigating on its own, not noise to smooth over. The point of building the map this way, with sources and evidence attached, is that the next update is a diff, not a rebuild.

Questions practitioners ask

Can I get a repository's dependent count from the GitHub API?

No. GitHub does not expose the 'Used by' or dependents count through its official REST or GraphQL API. The API lets you check what a repository depends on, but not which repositories depend on it. To capture reverse dependencies you must read the Dependents tab in the web UI or use a community scraper against that page, then cross-reference open datasets like ecosyste.ms and deps.dev for coverage the graph misses.

Why is my seed project's 'Used by' number so much lower than a competitor's?

The 'Used by' figure represents a single package from the repository, not the whole repo, and it only appears once more than 100 repositories depend on that package. A repo publishing several packages is structurally undercounted, so a monorepo can look far smaller than a single-package rival. Sum every package's dependents separately instead of trusting the sidebar number.

How accurate are open source dependency counts?

They are provably wrong by a known margin. A peer-reviewed study of GitHub's dependency graph measured roughly 20% errors in dependencies and roughly 10% in dependents. That is why a defensible landscape map records a range from GitHub, ecosyste.ms, and deps.dev rather than presenting one authoritative figure, and annotates disagreements instead of averaging them away.

Does reverse-dependency data cover every language equally?

No. Completeness is language-dependent. deps.dev indexes seven ecosystems but resolves full dependency graphs for only five, and it has no data for C or C++ because they lack a clear packaging model. A systems-language seed can look unused when it simply is not indexed. Confirm your seed's ecosystem is actually covered before concluding low adoption, and triangulate across ecosyste.ms and Libraries.io.

Should I filter out forks before or after ranking?

Before. The Linux Foundation criticality methodology filters forks, mirrors, templates, and archived repositories up front, which is the opposite of a signals-first pipeline but the more defensible order. Popular repos carry thousands of forks that inflate the map, so exclude them early or you will spend effort ranking duplicates and near-mirrors of the same project.

Try it on your own search

Stop building boolean strings. Just describe the person.

Type one sentence and I plan the search, read GitHub, public LinkedIn and Crunchbase records, and the open web live, then hand back a ranked shortlist with the reasoning behind every name. No filters to learn, no export to clean up, no sales call to sit through.

  • One sentence in, a ranked shortlist out. No boolean, no filters, no seat to buy.
  • Read live at search time, not from a database that went stale last quarter.
  • Watch every step as it runs, and see why each name made the list.

500 free credits on sign-up. No card, no demo call. See real searches.

Read next