Full Stack · Developer Tools
RepoSignal
Software that evaluates how software is being engineered.
- 477 tests + 22 e2e specs
- deterministic scoring
- MIT
01The problem
Star counts measure popularity, not health.
Judging an unfamiliar repository usually means skimming the README, glancing at the commit graph, and guessing. Most “repo score” tools replace the guess with a number you cannot interrogate — which is worse, because it looks like knowledge.
RepoSignal is built on the opposite premise: a score you cannot audit is not worth showing. Every category expands to reveal the metrics examined, their raw values, the weights applied, the thresholds used, and links to the evidence on GitHub.
02The rule that shaped the architecture
Missing data is not evidence of poor health.
A repository whose commit statistics GitHub has not computed is not unhealthy — it is unmeasured. So an unobservable metric is null, a category with too little data scores
null rather than zero, and a null category is excluded from the overall score with
its weight redistributed.
Silently turning missing data into a zero is the easiest way to make a health score dishonest.
Avoiding it drove most of the type design — score: number | null appears throughout,
and the UI renders “insufficient data” rather than a fabricated number. The invariant is enforced
by a test: adding a null category can never lower the overall score.
03How an analysis happens
01
GitHub REST API
auth · retry · timeouts · request budget
A hand-written client collects public evidence — commits, pull requests, issues, workflow runs, community files — under a hard per-analysis request budget. Rate limits fail fast with a reset time instead of retrying into the wall.
02
Normalization
GitHub payloads → domain types
GitHub response shapes never escape this layer. Nothing downstream references a GitHub field name, so an API change is contained to one directory — and the scoring engine can be tested with plain object literals instead of recorded HTTP fixtures.
03
RepositorySnapshot
the only input scoring ever sees
Everything observable about the repository lands in one immutable snapshot. If a metric could not be observed, it is null here — not zero, not a default. That distinction survives all the way to the screen.
04
Scoring engine
pure functions per category
Seven categories score the snapshot with documented weights and thresholds. A category without enough data scores null and is excluded, its weight redistributed. A test asserts the invariant directly: adding a null category can never lower the overall score.
05
Explainable result
versioned · serializable · cacheable
The UI calculates nothing. Every number on screen expands into the metrics examined, the raw values, the weights applied, and links back to the evidence on GitHub.
04What it measures
What it measures
Repository activity
Commit cadence, last push, release recency and regularity
Pull request health
Open PR ages, merge velocity, long-lived open PRs
Issue health
Backlog age, stale issues, open/close rates
CI health
Workflows present, recent run outcomes, repeated failures
Documentation
README, CONTRIBUTING, LICENSE, templates, docs directory
Repository hygiene
Lockfiles, CODEOWNERS, dependency automation, release tags
Security hygiene
SECURITY.md, dependency automation, scanning in CI
Deliberately “hygiene”, not “security score”
RepoSignal observes practices; it does not scan for vulnerabilities and will never claim a repository is secure. A test collects every user-facing string in that module and asserts none of them says so.
05Engineering decisions
Engineering decisions
- Deterministic scoring instead of an LLM
- The same snapshot always yields the same result, every threshold can be unit tested, and a user who disagrees can be shown the exact rule that produced the number. An LLM-generated score is none of those things — AI stays a possible presentation layer, never the calculator.
- A hand-written GitHub client instead of Octokit
-
Three policies shaped the client’s public signatures: a hard per-analysis request budget,
sample truncation surfaced to the caller (
paginate returns { items, truncated }), and rate-limit handling that fails fast with a reset time. Expressing those on top of a general-purpose client meant fighting it. - Repository identity is the numeric ID
-
Repositories get renamed and transferred — while building this,
facebook/reactbecamereact/react. GitHub’s numeric id is the stable identity, so a rename resolves cleanly instead of forking history into two records. - A strict CSP, paid for honestly
-
Next.js streams Suspense boundaries through inline scripts, which a strict
script-srcblocks. RepoSignal takes a per-request nonce and gives up prerendering, since nonces are injected at render time. A real trade, recorded as one rather than presented as a free win. - No charting library
- The charts are static distributions. Server-rendered SVG ships zero client JavaScript and makes the accessible text alternative part of the markup rather than a retrofit.
- Private repositories via a GitHub App, not OAuth
-
A classic OAuth app would demand the
reposcope — read and write — on everything. A GitHub App grants read-only access to explicitly selected repositories. Tokens are minted per use, expire in an hour, and never touch the database or a log.
06Testing
No test contacts the live GitHub API.
477 unit, integration and component tests plus 22 Playwright specs run against MSW-mocked responses and bundled fixture snapshots — an unhandled request fails the test rather than escaping. CI is therefore immune to rate limits and outages.
- Unit — every threshold and null path, in isolation
- Integration — the layers compose, network mocked with MSW
- Component — every UI state renders correctly
- E2E — the journey works in a browser, against a real build
07The methodology, on screen
The methodology, on screen
08Stack and links
Stack and links
Next.js 16 (App Router) · React 19 · TypeScript strict with noUncheckedIndexedAccess and exactOptionalPropertyTypes · Tailwind CSS 4 · PostgreSQL + Prisma · Zod · Vitest
· React Testing Library · Playwright · MSW · GitHub Actions.
Repository · Live demo · Scoring methodology · Architecture notes