# 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.*

- Canonical URL: https://www.refolk.ai/guides/dependency-manifests-ranked-accounts
- Pillar: Sales and go-to-market
- Format: Playbook
- Published: 2026-09-15
- Last reviewed: 2026-09-15
- Reading time: 16 min
- Keywords: find companies using a library, github code search dependency manifest, who imports my competitor package, dependency adoption prospecting, build target account list from github, package.json go.mod prospecting

## 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.

| Ecosystem | Runtime signal to keep | Reject |
|---|---|---|
| npm | `dependencies` object | `devDependencies` |
| Go | `require` with no `// indirect` | lines marked `// indirect` |
| Maven | default `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.

| Limit | Value | What it forces |
|---|---|---|
| Results per query (UI) | 100, across 5 pages | Shard broad queries |
| Total API results | 1000 | Segment large markets |
| File size indexed | under 5 MB | Miss huge manifests |
| Bytes searched per file | first 500 KB | Miss late entries |
| Code search rate | 10 requests per minute | Throttle 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.

> **Watch out:** The cap makes big markets look small
>
> The 100-result limit is not a sample. If a popular library returns exactly 100 matches, you are seeing a truncated slice, not the market. Shard by org, language, or file-size range and confirm each shard returns under 100 before you trust the count.

## 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

| Stage | Figure | Note |
| --- | --- | --- |
| Raw file matches | 100 | capped per query, so shard first |
| Unique repositories | fewer | multiple manifests collapse to one repo |
| Unique orgs | fewer | many repos share one owner |
| 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.

Ask me this: `Companies whose public repos import the competitor package in a runtime package.json dependency, engineering teams in the US.` - [run the search](https://www.refolk.ai/start?q=Companies%20whose%20public%20repos%20import%20the%20competitor%20package%20in%20a%20runtime%20package.json%20dependency%2C%20engineering%20teams%20in%20the%20US.).

*Returns company-resolved accounts that declare the library as a production dependency, not repos that merely mention 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.

> **Rule:** Keep only runtime, direct dependencies
>
> A match is an adopter only if the package sits in the runtime table with no dev or indirect marker. Reject every // indirect line, every dev-dependencies block, and every test-scope entry before you enrich. Enrichment on a dev-only match spends budget resolving a company that never runs your competitor.

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.

> **Tip:** Verify your top targets by hand
>
> The list has structural error concentrated on large firms. Before you route the top decile, open each org page and confirm the domain, the legal name, and that the matching repo is the company's own product, not a fork or an agency's client work.

## 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.

| Country | Matching profiles | US multiple |
|---|---|---|
| United States | 5,362 | 1.0x |
| Germany | 455 | 11.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.

| Skill | Matching profiles | vs React |
|---|---|---|
| React | 5,362 | 1.0x |
| Vue.js | 5,621 | 1.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.

## Frequently asked questions

### 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.

---

*From the Refolk guide library. I revise these guides rather than replacing them, so the current version is always at https://www.refolk.ai/guides/dependency-manifests-ranked-accounts*
