GitHub Profile Viewer
Every profile tells a story.
What it is
GitHub Profile Viewer turns any GitHub username into a profile worth reading. Enter a username and it pulls together the person's avatar, bio, location and links, a breakdown of the languages they use most, and their most notable repositories, all on one page you can share as a link.
Built with plain HTML, CSS and JavaScript, it uses GitHub's public API with no login, no framework and no build step.
It is the smallest project in this portfolio, and the one where the goal was to treat something that could have been a throwaway search box as though every detail mattered.
The problem
GitHub already exposes all of this information, so the challenge wasn't finding the data. It was presenting it in a way that felt more useful than a collection of API responses.
Three things stood in the way.
Profile details and repositories come from different endpoints, so two separate requests have to become one page. GitHub also doesn't provide a language breakdown for a user, only the primary language of each repository, so that picture has to be built rather than retrieved. Finally, because the app runs without authentication, every request lives under GitHub's public rate limit, meaning failure isn't an edge case, it's something the interface has to expect.
The decisions
Two requests, one profile
Profile information and repositories are fetched in parallel rather than one after the other, so the slower request sets the waiting time instead of both requests adding together. The page only renders once both have finished, avoiding a profile that appears piece by piece.
Building a language fingerprint
GitHub assigns each repository a single primary language. By counting those across every public repository, the app builds a simple picture of the languages someone works with most, displaying the top results as proportional bars.
The most-used language does one more job: its colour becomes the ring around the avatar, quietly giving each profile its own visual identity.
It's an intentional approximation. Repository counts don't reflect the amount of code written in each language, but they provide a quick, honest overview without requiring dozens of additional API requests.
Expecting to be told no
Every request is written to expect failure, with each common case returning a clear explanation instead of a blank screen.
| GitHub returns | What you see |
|---|---|
| 404, no such user | User not found. Check the username and try again. |
| 403, rate limit hit | GitHub API rate limit reached. Try again in a moment. |
| anything else | Something went wrong. Please try again. |
A profile worth sharing
Successful searches update the page URL with the username. Opening that link automatically rebuilds the same profile, turning a one-off search into something that can be bookmarked or shared.
What I'd do differently
The language breakdown is the biggest compromise, and I'd rather acknowledge it than pretend otherwise. Counting repositories overrepresents developers with lots of small projects in one language while undervaluing larger projects written in another. Calculating language usage from GitHub's byte counts would paint a more accurate picture, but it would also require an extra request for every repository, quickly running into the public rate limit.
The rate limit itself is the other limitation. Without authentication, GitHub only allows a certain number of requests from the same address before temporarily refusing new ones. Today the app simply explains what's happened and asks the visitor to try again.
Allowing users to provide their own API token would largely remove that restriction, but it would also turn something that works immediately into something that needs setting up. For a project intended to be simple and accessible, that felt like the wrong trade-off.
It may be the smallest project in this portfolio, but it's also the clearest example of something I care about: treating even the simplest interface as though it deserves thoughtful design.