Inspiration

I kept hearing the same complaint from people who work on bigger codebases : you change one file and everything looks fine but then something completely unrelated breaks. Every dependency graph tool I checked out (Madge, Dependency Cruiser and even GitHub's own graph) only shows you the import structure which is what technically calls what. That's useful but it's not the whole story. Sometimes two files have zero code connection but somehow always get edited together because of some shared assumption nobody wrote down. I wanted to see if git history could expose that.

What it does

You paste in a public GitHub repo. RepoPulse builds the real import graph first in the same way existing tools do. Then it goes through the last 25 commits and checks which files keep showing up together in the same commit even though neither imports the other. If a pair does that more than once, it gets flagged as "hidden coupling" and drawn as a dashed line instead of a solid one. Click any file and you get a breakdown : what it imports, what imports it and what it's quietly coupled to based on actual commit history.

How we built it

It's a single HTML file. There's no backend, no build step. It calls the GitHub REST API directly from the browser to get the repo's file tree, pulls raw file contents from raw.githubusercontent.com and uses regex to pull out import/require statements. I resolve those relative paths manually against the file list to build the import edges. For the commit side, it pulls the last 25 commits and diffs which files got touched in each one counting how often each pair shows up together. The graph itself is rendered with D3's force simulation. There's also an optional layer where if you give it a Claude API key it writes a plain English summary of the riskiest pairs instead of just listing them.

Challenges we ran into

The file selection was trickier than expected. My first version just took the first 30 files alphabetically, which meant repos like Express ended up showing mostly the 'examples/' folder instead of the actual 'lib/' source because "e" comes before "l". I had to add a priority sort so core source folders get pulled in first. The bigger bug was in path resolution. When a file did something like require('../') to reach a package's root index.js, my resolver was tacking on an extra slash and never matching it. So a bunch of real import edges were silently getting dropped. I only caught it by running the actual logic against real repos (Express, Chart.js) outside the browser and printing out every import that failed to resolve. It turned out to be a one character bug in how I built the index-file candidate path. I also learned that hidden coupling doesn't show up on every repo and that's not a bug. It's just true. A 25-commit window on a quiet repo might not have any co-changes at all. I had to actually test against a few different repos to find ones where the feature had something real to show.

Accomplishments that we're proud of

Getting the hidden coupling detection to actually work on real repos not just a hand-picked example. It's easy to fake something like this with data you made up but running it against Express and Chart.js and watching it correctly separate real import edges from git-history coupling felt like the moment this stopped being a mockup and became a real tool. Catching the path resolution bug before it shipped. If I hadn't tested against live repos I would've demoed something that silently missed a third of its real import edges and never known it. Making the whole thing work with zero backend and zero required setup. Someone can open the live link, paste any public repo and get a real result in seconds. No signup, no API key required unless they want the AI summary.

What we learned

Testing against live data early saved me from shipping a broken core feature. It would've looked fine in the browser with a small handwritten example but real repos have edge cases (root-level imports, index file conventions, deeply nested paths) that you don't think of until you throw real data at it.

What's next for RepoPulse

Right now it caps at 30 files and 25 commits to stay within GitHub's public API rate limit. With an auth token or GitHub's GraphQL API, I could scan a lot more history and get a much fuller picture especially on larger repos. I'd also like to let people choose which files get analyzed instead of it being automatic.

Built With

Share this project:

Updates

Submission history