Guide

How to get your open-source work noticed (honestly)

Almost every guide on this subject is a distribution guide: post here, tweet that, submit to this list. This one starts somewhere else, because the measured evidence keeps pointing somewhere else. The highest-leverage fix is usually not marketing. It is making the thing usable.

The thesis, stated plainly

A repository that people star and then abandon does not have a distribution problem. It has a product defect. Distribution already worked — the visitors arrived, read the pitch, and liked it enough to bookmark it. What failed came after: they tried to use it, or looked at what using it would cost, and left.

That distinction matters because the two failures have opposite remedies. If nobody arrives, you need reach. If people arrive and leave, more reach makes it worse: you spend the credibility you have on a larger audience for the same disappointment. Diagnose first.

Every figure on this page was measured, most of it against the author’s own account, and the measurements are unflattering. That is deliberate. A guide that only shows you upside is selling something.

The one thing to take away

Rank your problems by where people drop off, not by which fix is most fun. Fixing an install that does not work is boring, unglamorous, and worth more than every launch post you will ever write.

1. Start with the uncomfortable one: is your repository actually usable?

Before topics, before READMEs, before a single post anywhere. Can a stranger on ordinary hardware get it to run?

The build-from-clean test

Take a machine that is not yours — a fresh container, a colleague’s laptop, a free CI runner. Clone the repository. Follow your own README literally, typing only what it says, installing only what it tells you to install. Do not use knowledge that lives in your head and not in the file.

Most projects fail this in under two minutes, and they fail on something the author cannot see, because the author’s machine has been quietly accumulating the missing pieces for years. The undeclared system package. The environment variable set in your shell profile. The header that only exists on your architecture.

A worked example: 154 stars, and it would not compile

Scottcjn/ram-coffers is this site operator’s own repository. It is a NUMA-aware weight-banking layer for LLM inference on IBM POWER8. On 4 August 2026 it held 154 stars, placing it in the top 1.07% of starred public repositories. It has a description, thirteen topics, and a declared licence. By every conventional checklist it was doing well.

Here is what the traffic actually looked like in the fourteen days ending 5 August 2026:

Scottcjn/ram-coffers, GitHub traffic API, 14 days ending 2026-08-05
MeasureTotalUnique
Stars (lifetime)154
Page views1817
Clones11173

Roughly three-quarters of a clone for every star ever awarded, against eighteen human page views. People admired it and walked away.

The honest reason, found by running the build-from-clean test on an ordinary x86 laptop:

  • #include <altivec.h> appeared unconditionally in four files — ggml-intelligent-collapse.h, ggml-topk-collapse-vsx.h, ggml-vcipher-collapse.h, and bench_vcipher_collapse.c. That header does not exist on x86. The compiler stops at the include line.
  • #include <numa.h> was guarded by #ifdef __linux__, which sounds careful and is not. Every Linux machine without libnuma-dev installed still failed, and that is most laptops.

So the project could not be built by the people looking at it. Not built badly — not built at all. Every one of those 154 stars was awarded by someone who never got a compiler past line 26.

It was fixed on 5 August 2026 on the branch feat/non-numa-fallback: a coffers-portability.h shim that does capability detection at compile time, a uniform-memory fallback for machines with one memory node, and a build matrix that compiles the headers in eleven configurations. The interesting part is what the fix was not. It was not a blog post. It was not a launch. It was removing the reason people were leaving.

Why this example is worth generalising

ram-coffers had already passed every findability test on this page. Description: present. Topics: thirteen of them. Licence: declared. README: substantial. It was discovered, understood, and admired — and the funnel still ended at the compiler. If you only fix the marketing layer of a project like this, the marketing works and the outcome does not change.

A repository that cannot build for its audience gets starred and abandoned. That is a product defect, not a distribution problem.

The one-command bar

The standard to aim at is a single command that takes a stranger from nothing to a working result. pip install yourthing && yourthing --demo. npx yourthing. docker run yourorg/yourthing. If the answer involves cloning, installing four system packages, exporting three variables, and editing a config file, then the answer is that most people will not do it.

Three things buy most of the distance:

  • Declare every dependency, including the system ones. If your project needs libnuma-dev or cmake or a specific compiler version, say so in the README and, where the ecosystem supports it, in machine-readable metadata.
  • Guard everything platform-specific behind capability detection, and provide a slower generic path rather than a compile error. A fallback that runs at half speed is infinitely better than a fast path that does not exist on the reader’s machine.
  • Put the build-from-clean test in CI, on the cheapest, most ordinary runner available. If your CI only ever builds on your exotic target, it is testing your machine, not your project.

2. The six signals, and the lever attached to each

Every row is a measurement you can take today with the GitHub API and a package registry. The point of the table is that a signal on its own is not actionable — the lever is.

Measured signal, diagnosis, and the corresponding lever
SignalWhat it meansThe lever
High stars, low clones Admired, not used. The pitch converted; the product did not. Make it install and run in one command. Build from clean on a machine you do not own.
Zero human page views Undiscoverable. Nobody is bouncing, because nobody arrived. Topics, a real description, and a README whose first sentence says what it does.
No releases, zero downloads No distribution channel. Using it requires a clone and a build. Publish to PyPI, npm, or crates.io. Cut releases with real, runnable artifacts.
Stale pushed_at Reads abandoned, whether or not it is. Nobody adopts a dependency that looks dead. Archive it honestly, or show a heartbeat: dependency bumps, a dated maintenance note.
No README Immediate bounce. The visitor has nothing to evaluate. Lead with what it does, for whom, and what it costs to try. Not how it is built.
Many repositories, no traffic Portfolio dilution. Attention divided by fifty is attention nobody notices. Consolidate. Fewer, deeper. Archive the rest with an honest note.

What portfolio dilution looks like when you measure it

These are the operator’s own numbers, measured 4 August 2026 and published in full in the Scottcjn case study:

45%

67 of 150 repositories received zero human page views in a fourteen-day window.

78%

of all portfolio page views land on just five repositories.

400

lifetime release-asset downloads across the entire portfolio, summed over every published release.

The portfolio is not 150 assets. It is about five assets and a long tail nobody is reading. If that describes your account, publishing repository 151 is not the move.

Read clone counts carefully; they are mostly robots

Across that same portfolio, GitHub reported 12,840 clones against 3,891 page views in a single fourteen-day window — a 3.3:1 inversion. Sixty-six repositories recorded zero page views but non-zero clones, which is the exact fingerprint of CI runners, mirrors, package indexes, and scrapers rather than developers.

Humans look before they clone. When clones exceed views, the surplus is automation. The honest adoption figure for that portfolio was not 12,840; it was 1,890 unique visitors. A big clone number is not a win, and treating it as one will send you optimising for an audience of bots.

This cuts both ways, and it is why the ram-coffers example above is stated as clones per star rather than as raw adoption. Its 111 clones against 18 page views are, on this same reasoning, mostly automated too. The signal is not the clone count. The signal is that a repository with 154 stars drew seventeen unique human visitors in two weeks.

3. Make it findable

This is the cheap layer. It takes about fifteen minutes per repository and it is genuinely necessary — it just is not usually the binding constraint.

The first sentence of the README is the whole pitch

It is what appears in search results, in social previews, in aggregator listings, and in AI-generated summaries. Write it as a complete, self-contained declarative sentence that names the thing, says what it does, and says who it is for. Not “A fast, modern, zero-dependency toolkit” — that describes ten thousand projects. Something closer to “X converts Y files into Z for people who need W.”

The failure mode is leading with architecture. Readers do not arrive caring how it is built. They arrive asking whether it solves their problem, and they leave in seconds if the answer is not visible.

Description and topics

GitHub’s repository description and topic tags feed GitHub’s own search, which is where a large share of discovery actually happens. On the portfolio measured above, 92.6% of all referred traffic came from github.com itself plus Google. Whatever you think your distribution channel is, in practice it is those two.

Topics should be the words a stranger would type, not the words you use internally. Include the language, the platform, the domain, and the problem. Ten to fifteen is reasonable; a hundred is keyword stuffing and is treated as spam.

Licence metadata, not just a licence file

An unlicensed repository is legally unusable inside most companies, and a licence that GitHub cannot detect is nearly as bad, because it does not populate the licence field that downstream tools read. Use a recognised SPDX identifier in a standard LICENSE file at the repository root. This is a five-minute fix that silently unblocks an entire class of adopter.

What findability cannot fix

ram-coffers had all of this. Description, thirteen topics, AGPL-3.0 detected, substantial README. It still ended at the compiler. Do the findability work — it is cheap — but do not mistake it for the diagnosis.

4. Distribution beats promotion

A promotion campaign produces a spike and decays. A package registry entry produces a baseline and compounds.

Why a download is worth more than a star

A star costs one click and commits the person to nothing. A download means somebody put your code into their environment, which is the first step of every real adoption path there is. The two are not comparable units of the same currency.

The measured contrast on the portfolio above is stark. Lifetime release-asset downloads across all published releases: 400. Monthly downloads across published PyPI and npm packages: approximately 5,000. The registry channel produces more distribution in a month than the entire GitHub-releases channel has produced in its lifetime, by more than an order of magnitude. It is the strongest genuine adoption signal anywhere in that portfolio.

Registry download counts include mirrors and CI, exactly like clone counts, so treat them as an upper bound on human usage rather than a user count. The comparison above survives that caveat because both sides are inflated by the same kind of automation.

Publish to the registry your users already use

Python people run pip install. JavaScript people run npm i. Rust people run cargo add. Every one of those is a channel where your project can be found and installed by someone who has never visited your repository, and where the install is one line. Meeting users inside the tool they already have beats asking them to come to you.

Practical minimums: a package name a person could guess, a one-line summary that matches your README’s first sentence, a declared licence, a link back to the repository, and a version number that increments. Automate the publish from a tag so releasing costs nothing and therefore keeps happening.

Releases with artifacts people can actually run

A release that contains only auto-generated source tarballs is a formality. A release that contains a compiled binary, a wheel, a container digest, or a signed archive removes a build step from the adopter’s path. Add a changelog entry a human can read, note the platforms the artifacts were built for, and note the ones they were not.

5. Earned links, not bought ones

There are exactly two kinds of link: one that someone chose to give you, and one you arranged. Only the first is durable, and the second carries the risk.

Four channels that earn links honestly

  • Package registries. Your PyPI, npm, or crates.io page is a real page on a real high-authority domain that links to your repository, and it exists because you shipped something. It is the single most defensible link most projects will ever get.
  • Genuinely relevant curated lists. If your project actually belongs in an awesome-list, propose it, disclose that it is yours, and accept the maintainer’s answer. If it does not belong there, the link is worth nothing to you anyway, because nobody in that audience wants it.
  • Answering the question your library solves. Find the Stack Overflow question your project genuinely answers. Write the answer — a real answer that stands alone and helps even if the reader ignores your link — and disclose your affiliation. This is slow, it does not scale, and it reaches precisely the people with the problem you solved.
  • Writing the post that explains the problem. Not a launch announcement. The article that explains the underlying problem well enough that people cite it for the explanation. That post keeps earning links for years, and your project is the natural illustration inside it.

All four share a shape: you produce something of independent value, and the link is a by-product. That is also, not coincidentally, what search engines and answer engines are built to reward.

What you must not do, and why the risk lands on you

Google’s spam policies define link spam to include “buying or selling links for ranking purposes,” and spell out that this covers “exchanging money for links, or posts that contain links,” “exchanging goods or services for links,” and “sending someone a product in exchange for them writing about it and including a link.” Excessive reciprocal linking arrangements are named in the same policy. Google states that sites violating its policies “may rank lower in results or not appear in results at all.”

GitHub’s Acceptable Use Policies prohibit inauthentic interactions, including fake accounts and automated inauthentic activity, and name “rank abuse, such as automated starring or following” explicitly. Star exchanges and follow-for-follow rings are that. GitHub states it retains full discretion to respond to violations, including account suspension, account termination, or removal of content.

Now the part these warnings usually leave out: the risk is asymmetric, and it lands on you. The seller of links or stars has no reputation invested in your project and loses nothing when the scheme is detected. You lose the ranking, or the account, or both — and if you are a maintainer, your account is your professional record. Deleting a bad blog post costs an afternoon. Rebuilding a suspended eight-year commit history is not possible at all.

There is a second cost that has nothing to do with enforcement. Bought attention destroys your ability to measure. Once the numbers contain purchased units, you cannot tell whether the last change you shipped helped, because the noise now dwarfs the signal. You gave up your instrumentation to buy a number that was never the goal.

Paid attention is not automatically dishonest — undisclosed paid attention is. A bounty programme, a sponsored post, or a paid ad is a real transaction. The requirement is that it be disclosed and counted separately from unpaid demand, never blended into one headline figure. That is the same terms-of-sale adjustment this site applies when appraising an account, and it is why an incentivized funnel is disclosed here rather than called fraud.

6. GEO: getting cited by AI answer engines

A growing share of the people evaluating your project will never see your README. They will read a summary of it, generated by a model, and decide from that.

Generative engine optimisation is not a separate discipline from writing clearly; it is what happens when you write clearly enough that a machine can extract a claim without mangling it. Almost all of the practical advice reduces to one idea: make each factual claim survive being lifted out of its paragraph.

Write self-contained factual sentences

Answer engines extract short declarative claims and re-serve them without your surrounding context. A sentence that depends on the previous one to be true will be quoted alone and become false.

  • Weak: “It supports that too, as of the latest version.” Extracted alone, this names nothing and dates nothing.
  • Strong: “Version 2.1 of Foo added support for big-endian PowerPC.” This survives extraction, because the subject, the fact, and the version are all inside it.

The same rule applies to numbers. Put the unit, the date, and the population inside the sentence: not “we handle 40,000 a second,” but “in a benchmark on a 16-core POWER8 running Ubuntu 20.04, Foo processed 40,000 records per second.”

llms.txt

llms.txt is a markdown file served at the root of a site, proposed by Jeremy Howard and published on 3 September 2024, that gives language models a concise, expert-level summary of what the site contains. The format is deliberately simple: an H1 with the project name, a blockquote summarising it, optional prose, and H2-delimited sections holding lists of links with one-line descriptions.

Be accurate about its status. llms.txt is a proposal, not an adopted standard. Nobody is obliged to read it and its long-run adoption is unsettled. It is cheap, it is honest, and it does not damage anything if ignored — but if someone sells you on it as a required standard, they are overselling.

A cautionary tale, from this site

Because an llms.txt compresses each thing you own into a single line, an error in one of those lines is an error with unusual reach. It is the highest-leverage sentence you will write about a project, and nobody proofreads it, because nobody reads it.

This site’s own llms.txt described a sibling product as “Pi Network video platformlication” — a mangled string produced by a bad edit, sitting in the canonical machine-readable description of an entire product. It was corrected on 5 August 2026. For as long as it was live it was the exact sentence a model would have pulled to answer “what is PiTube?”, and a model quoting it would have produced a confidently wrong answer with no way for the reader to tell.

The lesson generalises past typos. If the one-line description of your project is subtly wrong — overclaims a capability, names the wrong platform, describes a feature you removed — that error is now the version of your project that circulates, and you will not see it happen. Proofread the machine-readable descriptions with the same care as the headline, and re-read them whenever the product changes.

Structured data, used honestly

Schema.org JSON-LD helps machines read a page’s structure: what kind of document it is, who wrote it, when it changed, and which questions it answers. Two rules make it safe:

  • Never mark up text that a human visitor cannot see. Structured data describing content that is not on the page is misrepresentation, and every major search engine treats it as a violation.
  • Keep the marked-up answer identical to the visible answer. If the two drift, the version that gets quoted is the one you stopped proofreading. Every FAQ answer in the machine-readable block on this page appears verbatim in the visible text below it.

The same honesty test applies to everything in this section: if a technique only works because a machine sees something a person does not, it is not optimisation. It is a discrepancy, and discrepancies are what detection systems are built to find.

7. What not to do

Listed with the reason attached, because a rule without a reason is just superstition and gets abandoned under pressure.

Buying stars, followers, or links

Named in GitHub’s Acceptable Use Policies as rank abuse and in Google’s spam policies as link spam. Enforcement risk aside, it destroys your ability to measure whether anything you ship is working.

Star-for-star and follow-for-follow exchanges

Inauthentic engagement under the same policy, whether money changes hands or not. It also produces a follower base with zero interest in your subject, which means your next real announcement reaches fewer relevant people than before you started.

Hidden text and hidden links

White-on-white text, off-screen positioning, display:none on link blocks. This is the oldest spam technique on the web and the easiest to detect, because detection is just comparing the rendered page to the source.

Keyword stuffing in topics, descriptions, and READMEs

A hundred topic tags, or a README footer listing every adjacent technology. It reads as spam to machines and as desperation to humans, and it dilutes the terms you actually rank for.

Doorway repositories

Near-duplicate repositories created to occupy more search results, each a thin wrapper pointing at the real one. This is the classic doorway-page pattern, and it is the mechanism behind the portfolio dilution measured in section 2: it costs you concentration and gains nothing.

AI-generated pull requests sprayed at strangers

Low-value drive-by PRs to accumulate a contribution record impose review cost on maintainers who did not consent to it. Increasingly they are labelled as such publicly, which converts the tactic from a neutral into an actively negative signal attached to your name.

Undisclosed self-promotion

Adding your own project to a curated list, recommending it in a forum, or answering a question with it are all fine — while disclosing that it is yours. Without the disclosure the same actions are a credibility loss that is permanent and public once noticed, in exchange for a link.

A guide that tells you only what to do is selling upside. The reason this section exists is that the tactics above all work briefly, which is precisely why people keep trying them, and all of them transfer risk onto the one asset you cannot replace: your account and your name.

8. Measure it: what to re-check in 30 days

Fix one thing, wait, re-measure. Changing five variables at once means learning nothing from any of them.

GitHub’s traffic endpoints return a rolling fourteen-day window and require push access to the repository, so you can run these on your own projects and not on anyone else’s. These are the exact commands used to produce the ram-coffers and portfolio figures on this page:

gh api repos/OWNER/REPO/traffic/views --jq '{count:.count,uniques:.uniques}'
gh api repos/OWNER/REPO/traffic/clones --jq '{count:.count,uniques:.uniques}'
gh api repos/OWNER/REPO/traffic/popular/referrers
gh api repos/OWNER/REPO/releases --jq '[.[].assets[].download_count] | add // 0'

Record the baseline before you change anything. Without it you will be arguing with yourself in a month about whether the number moved.

The thirty-day checklist

  • Unique page views. Rising means findability improved. Use uniques, not total views, and never use the clone count for this.
  • Clone-to-view ratio. Should trend down toward and below 1:1 as real humans arrive. A ratio that stays inverted means your new traffic is still automation.
  • Referrer mix. The goal is any meaningful source that is not github.com or Google. On the portfolio measured here those two accounted for 92.6% of referred traffic, which is the numerical definition of having no audience of your own.
  • Registry downloads. The clearest adoption signal available, and the one that compounds rather than spiking.
  • Issues opened by strangers. An issue from someone you have never met is proof that a person ran your code and cared enough to report back. One of these is worth more than a hundred stars.
  • Time-to-first-run, measured on a clean machine. The only metric on this list you control completely, and the one most likely to be the binding constraint.

A note on honest attribution

One figure in the underlying appraisal — that Hacker News had sent a single view — was measured on 4 August 2026 and cannot be reproduced now, because the traffic window rolls and old windows are not retrievable from the API. A re-measurement on 5 August 2026 found Hacker News absent from the referrer list of all eight of the most-viewed repositories, which is consistent but is not the same measurement. Snapshot your numbers when you take them. GitHub will not hold them for you, and a figure you cannot reproduce is a figure you should label as a snapshot rather than restate as current.

Frequently asked questions

Why do repositories get lots of stars but no users?

Usually because the project is admired rather than adopted. A star costs one click and commits the visitor to nothing, so it measures the quality of the pitch, not the quality of the experience that follows. The most common concrete cause is that the project does not build or install cleanly on the hardware and operating system its audience actually uses. Test it by cloning onto a machine that is not yours and following your own README literally.

Are GitHub clone counts a good measure of adoption?

No. Clone counts include continuous-integration runners, mirrors, package indexes, and scrapers. When clones exceed page views, the surplus is automation, because humans look before they clone. In one measured portfolio GitHub reported 12,840 clones against 3,891 page views in the same fourteen-day window, and 66 repositories recorded zero page views alongside non-zero clones. Unique visitors are the more honest adoption figure.

Is buying GitHub stars against the rules?

Yes. GitHub's Acceptable Use Policies prohibit inauthentic interactions, including fake accounts and automated inauthentic activity, and name rank abuse such as automated starring or following. GitHub states it retains full discretion to respond, including account suspension, account termination, or removal of content. The risk is asymmetric: the seller has nothing invested and loses nothing, while the buyer risks the account that holds their entire professional record.

Does buying links help a project rank in search?

No, and it carries real risk. Google's spam policies define link spam to include buying or selling links for ranking purposes, which explicitly covers exchanging money for links, exchanging goods or services for links, and sending someone a product in exchange for a post containing a link. Google states that sites violating its policies may rank lower in results or not appear in results at all.

What is llms.txt and should I add one?

llms.txt is a markdown file served at the root of a site that gives language models a concise summary of what the site contains. It was proposed by Jeremy Howard and published on 3 September 2024, and its structure is an H1 with the project name, a blockquote summary, optional prose, and H2 sections listing links with one-line descriptions. It is a proposal rather than an adopted standard, so treat it as cheap and harmless rather than as a requirement, and proofread it carefully, because each line is the sentence a model will quote about that project.

How do I get cited by AI answer engines?

Write factual claims as self-contained declarative sentences that stay true when they are lifted out of the surrounding paragraph, with the subject, the version, the date, and the units inside the sentence itself. Keep structured data honest by marking up only text a human visitor can see and by keeping the marked-up wording identical to the visible wording. Anything that works only because a machine sees something a person does not is a discrepancy, and discrepancies are what detection systems look for.

Should I promote my project or improve it first?

Diagnose before you choose. If nobody is arriving, the problem is reach and promotion is the right lever. If people arrive and leave, promotion makes it worse, because you spend credibility on a larger audience for the same disappointment. Zero page views points at findability. High stars with almost no human visitors and no downloads points at the product.

What should I measure 30 days after making a change?

Unique page views rather than total views, the clone-to-view ratio, the referrer mix, registry download counts, and issues opened by people you have never met. Change one thing at a time and record the baseline first, otherwise you cannot attribute the movement to anything. Snapshot the numbers when you take them, because GitHub's traffic endpoints only return a rolling fourteen-day window and old windows cannot be retrieved later.

This guide is the published advice library behind RepoAppraisal’s coaching work. The measurement method behind every figure on this page is documented in the methodology, and the full appraisal the portfolio figures come from is published as the Scottcjn case study, adverse findings first.