GitHub User Finder with HTML, CSS & JavaScript
30 DAYS 30 PROJECT CHALLENGE
Day #23
Project Overview
GitHub User Finder is a beginner-friendly project built with HTML, CSS, and JavaScript that allows users to search for GitHub profiles using their usernames. The project connects directly to the GitHub public API and retrieves real-time information for the requested profile. After the user enters a GitHub username, the application sends a request to the GitHub API and receives the user’s public profile data. It then displays important details such as the profile avatar, name, bio, number of public repositories, followers etc.
Additionally, the project handles empty input and invalid usernames with clear error messages. It also shows a loading message while the API request is running. Therefore, this project gives beginners practical experience with API integration, fetch(), JSON data and basic error handling.
Key Features
- GitHub User Search: Users can enter any GitHub username into the search field and click the Search button to find the corresponding public profile.
- GitHub API Integration: The project uses the GitHub public API to fetch real-time user information. Therefore, it does not need a manually maintained list of GitHub users or profile data.
- Real-Time Profile Data: After a successful search, the application displays information directly from the API response. It includes the user’s avatar, name, bio, repository count, followers, and following count.
- User Name and Bio: The application displays the user’s name when it is available. If the API does not provide a name, it uses the GitHub login instead, while a fallback message appears when no bio is available.
- Repository Statistics: Profile card shows the number of public repositories owned by the searched user. This value comes directly from the
public_reposproperty returned by the GitHub API. - Followers and Following: The project also displays the user’s follower and following counts. These values appear together with the repository count in a simple statistics section.
- View GitHub Profile: Each successful result includes a View Profile link that points to the user’s actual GitHub profile. The link opens in a new browser tab so users can continue browsing without losing the search result.
- Input Validation: Before sending the API request, the
getUser()function checks whether the username field contains a value. If the field is empty, the application asks the user to enter a username. - Loading State: The result area displays
"Loading..."immediately after a valid search begins. This gives users feedback while the application waits for the GitHub API response. - Error Handling: If GitHub does not find the requested username or the API request fails, the application displays
"User not found". As a result, users receive a clear response instead of an empty profile area. - No API Key Required: The project uses the public GitHub user endpoint directly, so this implementation does not require an API key. This keeps the setup simple for beginners.
- Clean User Interface: The project uses a centered white card with a search area and profile section. As a result, the important GitHub information remains easy to find and read.
What You'll Learn
- How to connect a frontend project with the GitHub public API.
- How to use
fetch()to request user information. - How to create API URLs dynamically with a username.
- How to check
res.okbefore processing an API response. - How to convert an API response into JSON using
res.json(). - How to access properties from returned GitHub user data.
- How to use fallback values with the
||operator. - How to display API data dynamically with
innerHTML. - How to show loading and error messages.
- How to validate user input before making an API request.
- How to create profile cards using template literals.
- How to create links dynamically using API-provided URLs.
HTML Code
HTML creates the basic structure of the GitHub User Finder. The .container holds the complete application, while the <h2> displays the project title. Inside the .search-box, the #username input allows users to enter a GitHub username, and the Search button calls the getUser() function when clicked.
Additionally, the #result div starts empty and provides the area where JavaScript displays the GitHub profile or an error message. Finally, the page loads script.js after the main HTML structure so the JavaScript can access the required elements.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>GitHub User Finder</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="container">
<h2>GitHub User Finder</h2>
<div class="search-box">
<input
type="text"
id="username"
placeholder="Enter GitHub username"
/>
<button onclick="getUser()">Search</button>
</div>
<div id="result"></div>
</div>
<script src="script.js"></script>
</body>
</html>
CSS Code
CSS controls the layout and appearance of the GitHub User Finder. The body uses Flexbox to center the application vertically and horizontally, while .container creates the main white card with padding, rounded corners, and a shadow. Next, .search-box uses Flexbox to keep the username input and Search button together. The input uses flex: 1 so it takes the available space, while the button provides the main search action.
The .profile class adds spacing around the returned GitHub profile. The .profile img selector creates the circular avatar, while .stats arranges the repository, follower, and following values in a row. Finally, .profile a styles the profile link, and .error displays invalid-search messages in red.
* {
box-sizing: border-box;
font-family: "Segoe UI", sans-serif;
}
body {
min-height: 100vh;
background: #042453;
display: flex;
justify-content: center;
align-items: center;
}
.container {
background: #ffffff;
width: 360px;
padding: 25px;
border-radius: 14px;
text-align: center;
box-shadow: 0 20px 40px rgba(0,0,0,0.25);
}
h2 {
margin-bottom: 15px;
}
.search-box {
display: flex;
margin-bottom: 15px;
}
.search-box input {
flex: 1;
padding: 10px;
border-radius: 6px 0 0 6px;
border: 1px solid #ccc;
}
.search-box button {
padding: 10px 16px;
border: none;
border-radius: 0 6px 6px 0;
background: #4f46e5;
color: white;
cursor: pointer;
}
.profile {
margin-top: 15px;
}
.profile img {
width: 90px;
height: 90px;
border-radius: 50%;
margin-bottom: 10px;
}
.profile h3 {
margin-bottom: 5px;
}
.profile p {
font-size: 13px;
color: #555;
}
.stats {
display: flex;
justify-content: space-between;
margin-top: 10px;
font-size: 13px;
}
.stats div {
background: #f3f4f6;
padding: 6px;
border-radius: 6px;
width: 30%;
}
.profile a {
display: inline-block;
margin-top: 10px;
font-size: 13px;
color: #4f46e5;
text-decoration: none;
}
.error {
color: red;
font-size: 14px;
}
Javascript Code
JavaScript handles the complete GitHub user search process. The getUser() function first reads and trims the username from the #username input. If the field is empty, it displays "Please enter a username" and stops the function. Otherwise, it shows "Loading..." before sending a request to https://api.github.com/users/${username}.
Next, fetch() sends the request to the GitHub API. The first .then() checks res.ok; if the response is not successful, the code throws a "User not found" error. Otherwise, res.json() converts the response into JavaScript data.
After that, the second .then() uses the returned user object to create the profile content. It displays avatar_url, name or login, bio or a fallback message, public_repos, followers, and following. It also creates a View Profile link using html_url. Finally, the .catch() block handles failed requests and displays "User not found" in the result area.
const result = document.getElementById("result");
function getUser() {
const username = document.getElementById("username").value.trim();
if (!username) {
result.innerHTML = `<p class="error">Please enter a username</p>`;
return;
}
result.innerHTML = "Loading...";
fetch(`https://api.github.com/users/${username}`)
.then(res => {
if (!res.ok) throw new Error("User not found");
return res.json();
})
.then(user => {
result.innerHTML = `
<div class="profile">
<img src="${user.avatar_url}" alt="Avatar">
<h3>${user.name || user.login}</h3>
<p>${user.bio || "No bio available"}</p>
<div class="stats">
<div>Repos<br><strong>${user.public_repos}</strong></div>
<div>Followers<br><strong>${user.followers}</strong></div>
<div>Following<br><strong>${user.following}</strong></div>
</div>
<a href="${user.html_url}" target="_blank">View Profile</a>
</div>
`;
})
.catch(() => {
result.innerHTML = `<p class="error">User not found</p>`;
});
}
Related Projects
Day 21 : Country Info Finder (API)
Fetches and displays real-time country information using a public REST API.
Concepts: API integration, fetch API, async data handling, dynamic UI rendering.
Day 25 : Stock Price UI (Mock / API)
Displays stock prices and daily changes using mock data with API-ready structure.
Concepts: UI state management, dynamic rendering, data simulation.
Day 26 : Job Search App (API)
Searches and displays job listings dynamically using a public jobs API.
Concepts: API integration, async data fetching, dynamic UI rendering.