bilannoun, Frencha balance sheet; an assessment of a situation, as in faire le bilan, to take stock.
The pulse of a GitHub repository.
See what is actually moving in a repository: who is contributing, which areas are changing, how reviews flow, and where work gets stuck. And as AI-assisted coding changes how much gets opened, how big it is, and how much of it is really reviewed, this is where you watch that shift over time.
Read-only on your own GitHub token. Open source. No sign-in needed for the examples.
01 / 05
What you see
More, and more useful, numbers than GitHub shows about a repository’s activity, for any window of time. The figures below are withastro/astro’s last 30 days.
Contributors and areas
Who is contributing, and where
Who opens pull requests and who reviews them, which areas of the codebase are moving week by week, down to each package of a monorepo, and which areas rest on a single person.
139pull requests opened by 60 authors
Review flow
How long work waits
Time to a first review and time to merge, as medians and p90s, week by week, so a slow week shows up as a slow week.
1.6hmedian wait for a first review · 75% of pull requests reviewed
Review load
Who carries the reviews
How reviews spread across people, each reviewer’s turnaround, and the reviewer–author pairs that hold most of the knowledge.
169reviews given by 12 reviewers
Bottlenecks
Where work gets stuck
Ready pull requests with no review for days, approved work that never merged, old drafts, and anything else that stands out, flagged as worth a look.
67pull requests still open · p90 time to merge 13d
Understand what AI is doing to your codebase and team
bilan uses no AI. It measures what AI-assisted coding does to a repository: how much gets opened, how big it is, how fast it merges, how much of it carries a real review, and where the review load lands on the people. Compare any window with the one before it and the shift is there in the numbers.
Volume and size
Pull requests opened per week and the size distribution: whether more, larger changes are arriving, and whether the long tail grows.
139opened in 30 days by 60 authors
Review pressure
Reviews per reviewer, the share the top three carry, and the wait for a first review: whether the humans reviewing keep up.
75%of pull requests ever reviewed · first review in 1.6h
Merged unseen
Merges without a review from anyone else, and revert pull requests, week by week: what gets through without a second pair of eyes.
Automation share
Bot-authored pull requests as a share of the whole, with their own merge rate and lead time, kept apart from the people.
02 / 05
Two repositories, measured
Full-history snapshots shipped with bilan, open to anyone. They are not live: sign in to sync a repository of your own.
RepositorySnapshotAboutLast 30 days of the snapshotPRs openedMergedMedian time to mergeMedian time to first review
A number is only useful if the people it describes agree with how it was counted. bilan makes three choices, and shows its working for each.
i.
Review time starts at ready for review
A draft is work in progress, not a request for review. Time to first review and time to merge are measured from the moment a pull request is marked ready; time in draft is reported on its own line.
ii.
Every window is honest
“Last 30 days” means what happened in those 30 days: merges when they merged, reviews when they were given. A comparison with the previous period appears only once that period is synced.
iii.
Process, not people
Per-person numbers are there to show where review load pools, which pairs hold the knowledge, and which areas rest on one person, so a team can change how work flows. It is not a leaderboard, and there is no score.
Where review time starts
The median pull request in withastro/astro over the last 30 days of its snapshot.
In draft1.6h, not counted as review time
Time to first review1.6h
Time to merge21h
Ready for review.Measurement starts here.
opened0h6h12h18h
Medians from the withastro/astro example (snapshot of Sep 28, 2026). Each is taken over its own set of pull requests, so this is a composite, not one pull request. The axis counts hours from ready for review.
Each metric is counted by its own event
A date range scopes every line by its anchor, so a pull request opened in August and merged in September counts as opened in August and merged in September.
Metric
Anchored at
How it is measured
PRs opened
created
Counted when the PR is opened.
Merged, closed unmerged
merged / closed
Counted when it lands or is closed.
Merged PRs by area
merged
Per area and week, or month over all time; a PR counts in every area it touched.
Time in draft
created
Opened → marked ready, for PRs opened as drafts.
Time to first review
ready
Ready → first review by someone other than the author.
Time to merge
merged
Ready → merged.
Reviewer turnaround
review
Review request (or ready, if never requested) → that reviewer’s first review.
Reviews given
review
Counted when submitted; self-reviews excluded.
Review threads per PR
merged
Review threads per merged PR, by size. Threads opened by bot reviewers count too.
Approved with no threads
merged
Every review was an approval, and no review thread was opened.
Time to approval
merged
Ready → first approval, by size.
04 / 05
How it works
Step 1
Sign in with GitHub
bilan is a GitHub App with two read-only permissions, pull requests and metadata. There is no scope to grant and nothing it could write with.
Step 2
Open a repository
Choose Start sync to read the last 30 days and every open pull request on your own token, usually in under a minute. Longer ranges sync when you ask for them.
Step 3
Share the link
The result is cached once. Anyone who can already see the repository on GitHub opens the same dashboard; anyone else gets a page that reveals nothing.
Step 4
Add private repositories
An organization owner installs the app once from GitHub; anyone else can request it. Access is checked against each viewer’s own token.
What bilan reads
+Pull requests: titles, states, labels, sizes, and timestamps.
+Reviews: who reviewed, the verdict, when, and who was asked.
+File paths: up to 30 per pull request, to tell which area it touched.
What it never does
−Write to GitHub. No comments, statuses, labels, or commits.
−Read your code. No file contents, no diffs.
−Hold a token forever. User tokens expire after 8 hours and are stored encrypted.
−Keep what nobody uses. Private repositories nobody opens for 90 days are deleted.
05 / 05
Or run it on your machine
$ npx github-bilan owner/name --open
The CLI syncs a repository into a local cache and writes one self-contained HTML report: styles, script, and data in a single file you can open offline, attach to an issue, or archive.
It talks to the GitHub API and nothing else. Nothing leaves your machine: the cache lives in ~/.cache/bilan, and re-runs only fetch what changed.
The token comes from --token, then GITHUB_TOKEN, GH_TOKEN, or gh auth token. The default depth is the last 30 days plus every open pull request.
Flag
What it does
--open
Open the report in the browser when it is written.
--out FILE
Where to write the report. Default: <name>.report.html.
--since DATE
Reach back to DATE. Coverage only ever widens.
--full
Walk the entire history.
--max-prs N
Stop after N pull requests in this run.
--offline
Render from the local cache without calling GitHub.
--no-cache
Ignore the cache and fetch everything again.
--token T
Use this token instead of the environment.
--areas FILE
List the folders that count as areas, nested ones included.