Refolk
PlaybookSales and go-to-market

From Dependency Manifests to a Ranked Target-Account List

You will run one package name through public dependency manifests and finish with a deduplicated, company-resolved account list ranked by depth and recency of adoption.

16 min readLast reviewed September 15, 2026Read as Markdown

Key takeaways

  • A runtime dependency entry proves a company ships the code; a star only proves someone bookmarked the repo, which is why manifest mining beats stargazer mining.
  • GitHub code search returns at most 100 matches per query across 5 pages, so anyone who queries a popular library once undercounts the market massively and must shard.
  • GitHub only indexes forks that out-star the parent and carry a pushed commit, so the raw match list is already biased toward substantive users and most personal forks never appear.
  • Enrichment error is structural, not random: parent/subsidiary confusion and rebrands cluster on your largest, most-acquisitive accounts, so manual review must be weighted toward big firms.
  • In Refolk's index, React-skilled engineers in target titles are about 11.8x more numerous in the US than Germany (5,362 versus 455), so the same list needs very different rep coverage by region.
  • Vue.js slightly outnumbers React in the US index sample under the same engineer-title filter (5,621 versus 5,362), a reminder to prospect on measured adoption rather than framework reputation.

This is the end-to-end method for turning one library or package name into a ranked, deduplicated account list. It is for founders selling their own product, account executives, SDR leads, and partnerships teams who want to know which companies actually run a competing or complementary tool, not just which developers watched its repo. Follow it start to finish and you finish with company-resolved accounts, scored by how deeply the tool is embedded, ready to route to reps.

Most GitHub prospecting guides stop at stargazer mining, issue scanning, and keyword alerts on individual developers. None of those prove a company ships the code. This one starts from a package name, works across npm, PyPI, Go, Maven, and Cargo manifests, and ends at ranked accounts.

Why a dependency manifest beats a star

A dependency manifest proves execution; a star proves interest. That is the entire reason this method exists.

A star is a bookmark. A developer clicks it, moves on, and may never touch the code again. A runtime entry in a package.json dependencies object, a require directive in go.mod, or a compile-scope entry in pom.xml means the library is installed and shipped when the application runs. That is the difference between someone who might buy and someone who has already committed engineering effort to the category you sell into.

The manifest also hands you a built-in interest filter. Every ecosystem separates code that ships from code that only helps developers build and test. A // indirect comment in Go, a [dev-dependencies] block in Rust, a <scope>test</scope> tag in Maven, and a devDependencies object in npm all mark dependencies that never reach production. When you reject those, what remains is adoption you can defend to a rep.

100
Maximum code-search matches returned per query
GitHub's UI caps results at 100 across 5 pages with no sorting, so a single query on a popular library undercounts the market.
A star is a bookmark. A runtime dependency entry means the library ships.

Where each ecosystem declares its dependencies

Each ecosystem has one root-level declarative manifest, and that file is where you point every query. Learn the five and you cover almost every codebase you will prospect.

For npm, the file is package.json in the repo root; runtime imports live under the dependencies object, which npm installs automatically on npm install. For Go, it is go.mod at the module root, where a require directive declares a module dependency with a minimum version. For Python, pyproject.toml is now authoritative: PEP 621 standardised project metadata including dependencies directly in that file, removing the need for setup.py in most cases. You will still see requirements.txt, but the distinction is clean: pyproject.toml describes the project, while requirements.txt describes an install. For Java, it is pom.xml, where a dependency is defined by a dependency element. For Rust, it is Cargo.toml, with dependencies split across [dependencies], [dev-dependencies], and [build-dependencies].

Ruby uses a Gemfile under Bundler, with runtime gems declared at the top level and dev or test gems inside group blocks. The Bundler pattern follows the same top-level-is-runtime logic, but verify the exact grouping syntax against Bundler's own docs before you rely on it.

The manifest is the outermost thing you search

  1. Repository
    the owner and repo that resolves to a company
  2. Root manifest file
    package.json, go.mod, pyproject.toml, pom.xml, Cargo.toml
  3. Runtime section
    dependencies, require, project.dependencies, compile scope, [dependencies]
  4. The package token
    the exact name or module path you are hunting
Point every query at the root manifest filename, then filter down to the runtime section inside it.

Direct and runtime versus everything else

The load-bearing distinction in this whole method is direct-and-runtime versus transitive-or-dev. A name that appears in the runtime table with no dev or indirect marker is a real-adoption signal. A name anywhere else is noise.

EcosystemRuntime signal to keepReject
npmdependencies objectdevDependencies
Gorequire with no // indirectlines marked // indirect
Mavendefault compile scope<scope>test</scope>
Rust[dependencies][dev-dependencies]
Python[project.dependencies]dev or optional groups

In Go, the tooling adds a // indirect comment when no package from the required module is directly imported by the main module, so a require line without that comment proves a direct import. In Maven, compile is the default scope when none is specified and is available on all classpaths. In Rust, [dev-dependencies] are excluded when compiling a package for building and only used for tests, examples, and benchmarks. Keep this table open while you filter in step four.

The constraints that shape every query

GitHub code search has hard caps that decide how you must work, so internalise them before you write a single query. The 100-result cap in particular is the reason careful practitioners beat careless ones.

LimitValueWhat it forces
Results per query (UI)100, across 5 pagesShard broad queries
Total API results1000Segment large markets
File size indexedunder 5 MBMiss huge manifests
Bytes searched per filefirst 500 KBMiss late entries
Code search rate10 requests per minuteThrottle scripts

Two more indexing rules change what you can and cannot see. Only the default branch is indexed, so code on release or feature branches is invisible. Only files under 5 MB are searchable, and only the first 500 KB of any file is read, so an entry near the bottom of a very large lockfile can be missed. Vendored paths such as node_modules and non-UTF-8 files are excluded from the index, and identical content is deduplicated by SHA, which means one library can appear across many near-identical manifests and still collapse to fewer indexed hits than you expect.

The fork rule quietly works in your favour. GitHub indexes a fork only if it has more stars than its parent and at least one pushed commit. Most personal forks fail that test and never appear, so your raw match list already leans toward substantive users rather than idle copies.

Run the procedure end to end

This is the full path from a package name to assigned accounts. Each step names who does it, roughly how long it takes, and what done looks like.

Package name to ranked account list

  1. Scope the target package
    Fix the exact import string for each ecosystem: the npm name, the Go module path, the Maven groupId:artifactId, the crate name, the PyPI project name. Done when you have one canonical token per ecosystem you will search. Analyst, 10 to 20 minutes.
  2. Build manifest-scoped queries
    For each ecosystem, restrict the query to the manifest filename plus the package token, for example filename:go.mod plus the module path. Done when each query returns results in the UI with no validation error. Analyst, 20 to 30 minutes.
  3. Harvest matches within the caps
    Because code search returns at most 100 matches per query, split broad queries with narrowing qualifiers such as org, size range, and language to stay under the cap, and respect the 10 requests per minute limit. Done when each sub-query returns fewer than 100 results and pages are exhausted. Analyst or script, 30 to 90 minutes.
  4. Filter to direct runtime dependencies
    Drop go.mod lines marked // indirect, Rust dev-dependencies, Maven test scope, and npm and Python dev or optional entries. Done when every surviving row is a runtime import. Analyst, 30 to 60 minutes.
  5. Deduplicate files to repos, then repos to orgs
    Collapse multiple manifest hits inside one repository to a single repo row, then collapse repositories under one owner to a single org row. Done when the owner login is unique per row. Script, 20 to 40 minutes.
  6. Resolve orgs to companies and enrich
    Apply the domain-normalise-then-match pattern: strip to a bare domain, skip personal and ISP domains, drop consultancy and mirror repos, and match on the canonical domain field. Done when each row carries a legal company name and domain. Analyst or tool, 30 to 60 minutes.
  7. Score depth and recency
    Rank each account by matching repos per org, the last commit date touching the manifest path, and the age of the pinned version string. Done when every account carries a numeric score. Analyst, 30 minutes.
  8. Route to reps
    Export the ranked, deduplicated rows to the CRM and assign owners, weighting rep coverage by regional talent density. Done when every account has an owner. RevOps, 15 minutes.

The queries in step two are the mechanical heart of the job. Keep them literal: the filename qualifier scopes the match to a declared dependency rather than a mention in docs or code comments, and the package token is the exact string, not a fuzzy keyword.

Manifest-scoped code search queries, one per ecosystem
filename:package.json "your-npm-package"
filename:go.mod "github.com/vendor/module"
filename:pyproject.toml "your-pypi-package"
filename:pom.xml "com.vendor:artifact"
filename:Cargo.toml "your-crate"

Replace the token after each filename with your exact package name or module path, then shard with org, language, or size qualifiers until each returns under 100 results.

Deduplicate honestly and know your funnel

The dedupe funnel runs raw file matches to unique repos to unique orgs to resolved companies, and it always narrows sharply. The stage order is reliable; the survival percentages are not something anyone publishes, so treat any figures you have not measured yourself as illustrative.

Raw counts inflate for a documented reason. GitHub deduplicates identical content by SHA and excludes vendored paths, so one library appears across many near-identical manifests, and several of those manifests sit inside the same repo or the same owner. Collapsing files to repos, then repos to orgs, is what converts an impressive raw number into an account list a rep can actually work.

The dedupe funnel narrows from files to accounts

  1. Raw file matches
    100

    capped per query, so shard first

  2. Unique repositories
    fewer

    multiple manifests collapse to one repo

  3. Unique orgs
    fewer

    many repos share one owner

  4. Resolved companies
    fewest

    personal and consultancy owners drop out

Every stage collapses duplicates, and the shape is real even though the exact percentages depend on your own run.

Because published per-stage numbers do not exist, do not report a funnel percentage as fact. Report your own counts from your own harvest and label them as such. The value is in the method, not in a borrowed number.

This is where a plain-language search removes most of the manual labour. Instead of writing and sharding queries by hand, then resolving each owner to a company, you can describe the population you want and get resolved accounts back. Refolk runs the resolution and enrichment step, the part where a raw GitHub owner login becomes a legal company name and domain, without you scripting it.

Resolve owners to real companies

Resolving a GitHub owner to one company follows a documented domain-based pattern, and its failures are documented too. Normalise any associated email to a bare domain, skip personal and ISP domains, and match on the canonical domain field with an exact match, then enrich that domain to a legal name, HQ, and headcount.

The hard part is returning correct data for the company you actually asked about. Subsidiaries get confused with parents, rebrands return stale identities, and long-tail international companies often do not resolve at all. This error is structural, not random. It clusters on your biggest, most-acquisitive target accounts, which are exactly the ones reps care most about, so weight your manual review toward large firms rather than spreading it evenly.

Personal forks, consultancy repos, and mirror repos are the main false-positive sources. The fork rule filters most personal forks for you, but an agency that imports the library across many unrelated client stacks is not the end customer. Flag any owner whose repositories span many unrelated stacks and treat it as a lead into that agency's clients rather than an account itself.

How this goes wrong

The failure modes below are where a manifest-mining pipeline produces a list that looks clean and is not. Each has a false positive and a concrete check.

  • Fork inflation. A popular library spawns thousands of forks, and each carries the manifest, so a personal fork gets counted as a company adopter. Check: rely on GitHub's fork filter, which indexes only forks that out-star the parent and have a pushed commit, then drop owners with no company domain.
  • Transitive or dev false match. A // indirect Go line or a test-scope entry looks like adoption but proves nothing runs the code. Check: reject any match not in the runtime table.
  • Cap truncation illusion. The 100-result cap makes a large market look small, and you conclude a library has few users. Check: shard queries by size and org and confirm each returns under 100.
  • Default-branch blind spot. Code on release or feature branches is invisible because only the default branch is indexed, so you miss real adopters. Check: for known targets, verify with a local git grep across branches.
  • SHA-dedup drops copies. Identical vendored manifests collapse under GitHub's content deduplication, hiding distinct orgs. Check: cross-reference your org list against a second signal such as the org page or the company website.
  • Consultancy or mirror repos. An agency repo importing the library is not the end customer. Check: flag owners whose repos span many unrelated client stacks.
  • Enrichment mismatch. A domain resolves to a parent or a rebrand and misassigns the account. Check: confirm the domain-to-legal-name match and reject when headcount or industry conflicts.

Route by adoption depth and by talent density

Ranking has two inputs: how deeply the tool is embedded, and how you should staff the account. The depth score is the guide's own construct, not a documented standard, so state it as a method and keep it simple.

Score each account on three signals: the number of matching repos per org, the last commit date touching the manifest path, and the age of the pinned version string. More repos means broader internal adoption. A recent commit on the manifest means the dependency is live and maintained. A recently bumped version means an engaged team. An account with three matching repos, a manifest edited this quarter, and a current version is a warmer account than one with a single repo pinned to an ancient release.

The second input is coverage. Talent density is a routing signal, and it is wildly uneven by geography, so the same adoption list should be worked with different rep coverage by region.

CountryMatching profilesUS multiple
United States5,3621.0x
Germany45511.8x fewer

In Refolk's index of professional profiles, filtered to Software Engineer and Frontend Engineer titles with the React skill, the US holds 5,362 matching profiles against Germany's 455, a ratio of about 11.8 to 1. A German account on your adoption list sits in a far thinner talent pool than a US account of the same size, which changes how many seats a rep should expect and how you weight coverage.

Adoption folklore also breaks on title-filtered data, which is a reason to prospect on measured manifests rather than reputation.

SkillMatching profilesvs React
React5,3621.0x
Vue.js5,6211.05x

In the same US index sample under the same engineer-title filter, Vue.js slightly outnumbers React, 5,621 to 5,362. Reputation would tell you React dominates; the counts say the gap is small and runs the other way in this slice. Let manifest adoption, not category folklore, decide which library you prospect. The top React-US employers in the index sample include Vercel and Amazon, while top React-Germany employers include Capgemini and Google, so even within one skill the account shape shifts by region.

11.8x
How much larger the US React talent pool is than Germany's
5,362 US profiles against 455 in Germany in Refolk's index, so the same list needs very different rep coverage by region.

Verify before you hand it off

Run this check before the list leaves your hands. It catches the errors that survive the procedure and would otherwise land in a rep's queue as noise.

Before routing to reps

  • Every surviving match sits in the runtime table with no dev or indirect marker.
  • Each broad query was sharded until every sub-query returned under 100 results.
  • File matches are collapsed to unique repos, and repos to unique orgs, with a unique owner login per row.
  • Personal, ISP, consultancy, and mirror owners are dropped or flagged as agency leads.
  • Every account carries a legal company name and a verified domain.
  • The top decile of accounts is hand-verified for parent, subsidiary, or rebrand mismatch.
  • Each account has a numeric depth-and-recency score and an assigned owner.
  • Rep coverage is weighted by regional talent density, not by account count alone.

Keep the list current

A dependency list decays because manifests change. Companies add and drop packages, bump versions, and rearchitect, so a list you built last quarter no longer reflects who runs the code today. Treat the harvest as a repeatable job, not a one-time export.

Re-run the manifest-scoped queries on a fixed cadence and diff against your last run. New orgs entering the runtime table are fresh accounts to route. Orgs that dropped the dependency, or moved it to a dev group, are churn signals worth a note to the owning rep. Because only the default branch is indexed and only the first 500 KB of each file is read, always confirm your highest-value additions with a local check rather than trusting a single code-search pass. The method holds; the numbers underneath it move, and re-running it is how you keep the account list honest.

Questions practitioners ask

What GitHub search query finds companies importing a specific library?

Combine the manifest filename qualifier with the package token, for example filename:package.json plus the npm name, or filename:go.mod plus the module path. This scopes matches to declared dependencies rather than any mention in code or docs. Because code search returns at most 100 matches per query, shard by org, language, or file-size range to see the full market instead of the first 100 hits.

Why is a dependency manifest a better prospecting signal than stargazers?

A star is a bookmark; it proves interest, not use. A runtime dependencies entry in package.json, a require directive in go.mod, or a compile-scope entry in pom.xml means the library actually ships in the application. The // indirect and test-scope markers are exactly what let you filter interest from adoption, so manifest mining proves execution while stargazer mining proves only attention.

How do I avoid counting forks and dev dependencies as real adopters?

GitHub only indexes forks that out-star the parent and carry at least one pushed commit, so most personal forks never appear and the raw list is already biased toward substantive users. On top of that, reject any match that is not in the runtime table: drop go.mod // indirect lines, Rust [dev-dependencies], Maven test scope, and npm devDependencies. Both filters together remove the two largest sources of false positives.

Can GitHub code search find every company using a package?

No, and you should plan around the gaps. Only the default branch is indexed, only files under 5 MB are searchable, and only the first 500 KB of each file is read, so adopters on feature branches or in very large or vendored manifests are invisible. For known targets, confirm with a local git grep. Treat the code-search list as a strong lower bound, not a census.

How do I resolve a GitHub org to the real company behind it?

Normalise any associated email to a bare domain, skip personal and ISP domains, and match on the canonical domain field, then enrich the domain to a legal name, HQ, and headcount. The hard part is returning the company you actually asked about: subsidiaries get confused with parents, rebrands return stale identities, and long-tail international firms often fail to resolve. Weight manual review toward your largest accounts where these errors cluster.

Try it on the search you came here for

Stop building boolean strings. Just describe the person.

Type one sentence. I plan the search, read GitHub, public LinkedIn and Crunchbase records, and the open web as it is right now, and hand back a ranked list with the reason next to every name.

  1. 01Describe them

    One plain sentence. Role, city, stack, stage, whatever matters to you.

  2. 02I read the web live

    GitHub, public LinkedIn and Crunchbase records, the open web. Not a database that went stale last quarter.

  3. 03You read the shortlist

    Ranked, with the reasoning under every name. Open a profile, ask a follow-up, narrow it down.

  • No boolean, no filters, no seat to buy. One box.
  • Read at search time, so a profile updated yesterday counts today.
  • Every step visible as it runs, every name with its reason.

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

Read next