How Mustache Templating Powers Resume Generation in GitHub Resume
Mustache templating generates dynamic résumés by merging static HTML templates with JSON data from the GitHub API, rendering the final page entirely on the client side without server-side processing.
The resume.github.com project transforms GitHub profiles into polished résumés using client-side Mustache templating. Instead of server-side rendering, the application fetches static HTML templates and populates them with data retrieved from the GitHub API, creating a lightweight, dynamic user experience.
The Mustache Templating Architecture
Template Loading Strategy
Located in js/githubresume.js (lines 998-1003), the application determines which template to load based on the GitHub account type. For individual users, it fetches views/resume.html; for organizations, it uses views/resumeOrgs.html.
// githubresume.js – line 998-1003
var resume = (data.type == 'User' ? 'views/resume.html' :
'views/resumeOrgs.html');
$.ajax({
url: resume,
dataType: 'html',
success: function(data) {
var template = data,
html = Mustache.to_html(template, view);
$('#resume').html(html);
});
View Object Construction
Before rendering, the script constructs a view object (lines 22-39 in js/githubresume.js) that maps GitHub API fields to template variables. This object includes user metadata, repository counts, follower statistics, and derived fields like userStatus and since.
// githubresume.js – lines 22-39
var view = {
name: name,
type: data.type,
email: data.email,
gravatar_id: data.gravatar_id,
avatar_url: avatar,
repos: data.public_repos,
reposLabel: data.public_repos > 1 ? 'repositories' : 'repository',
followers: data.followers,
followersLabel: data.followers > 1 ? 'followers' : 'follower',
username: username,
userStatus: getUserStatus(),
since: since,
resume_url: window.location
};
Rendering Process
Main Resume Template
The Mustache.to_html() function merges the template with the view object. In views/resume.html, placeholders like {{name}}, {{userStatus}}, and conditional blocks like {{#gravatar_id}} render user-specific content.
<!-- views/resume.html -->
<h1 class="fn">{{name}}</h1>
<h2>{{userStatus}}</h2>
{{#gravatar_id}}
<img src="https://secure.gravatar.com/avatar/{{gravatar_id}}?s=140&d=…" class="photo"/>
{{/gravatar_id}}
{{#email}}<a href="mailto:{{email}}" class="email">{{email}}</a>{{/email}}
Fragment Templates for Dynamic Content
After the main template renders, the application loads secondary templates for specific sections. Files like views/job.html, views/contrib.html, and views/org.html receive their own view objects containing repository details, contribution statistics, and organization memberships.
Each fragment template is processed using the same Mustache.to_html(template, view) pattern, allowing modular rendering of repository lists, contribution graphs, and organizational affiliations without reloading the page.
Key Source Files and Implementation Details
| File | Role | Link |
|---|---|---|
js/githubresume.js |
Core JavaScript: fetches GitHub data, builds the view objects, loads Mustache templates and renders them. |
githubresume.js |
views/resume.html |
Main Mustache template for a regular user résumé. | resume.html |
views/resumeOrgs.html |
Template used when the target is a GitHub organization. | resumeOrgs.html |
views/job.html |
Fragment template that renders each repository entry (language bar, description, stars, forks). | job.html |
views/contrib.html |
Fragment template for the contributions list (merged PRs). | contrib.html |
views/org.html |
Fragment template for the organizations section. | org.html |
index.html |
Entry point; loads Mustache library (mustache.js) and starts the JavaScript app. |
index.html |
These files together illustrate the full flow: data → view object → Mustache template → rendered résumé.
Summary
- Mustache templating enables fully client-side résumé generation without server-side rendering
- The
viewobject injs/githubresume.jsbridges GitHub API data and HTML templates - Template selection logic distinguishes between individual users (
views/resume.html) and organizations (views/resumeOrgs.html) - Fragment templates (
views/job.html,views/contrib.html) handle dynamic content sections - The
Mustache.to_html()function performs the final template-to-HTML transformation
Frequently Asked Questions
What is Mustache templating and why is it used in resume.github.com?
Mustache is a logic-less template syntax that uses double braces for variable substitution. The resume.github.com project uses it to separate presentation (HTML templates) from data (GitHub API responses), enabling clean client-side rendering without server-side dependencies. This approach keeps the application lightweight and allows the same JavaScript code to serve different layouts for users versus organizations.
How does the application decide which template to load?
The JavaScript code in js/githubresume.js checks the data.type property from the GitHub API response. If the value is "User", it loads views/resume.html; otherwise, it loads views/resumeOrgs.html for organizations. This conditional logic ensures that individuals see repository-focused layouts while organizations display member and team information.
Can I customize the Mustache templates for my own résumé?
Yes, the template files in the views/ directory are standard Mustache HTML files. You can modify resume.html, job.html, or other fragments to change the layout, styling, or content structure, provided you maintain the variable names expected by the view object in githubresume.js. Since rendering happens client-side, any changes to these templates take effect immediately without rebuilding the application.
What happens if a GitHub user has no email or Gravatar configured?
The templates use Mustache sections (e.g., {{#email}}...{{/email}}) to conditionally render content. If the email or gravatar_id properties are missing or empty in the view object, those sections are omitted from the final HTML output, preventing broken links or empty elements. This logic-less conditional rendering ensures the résumé displays only available information.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →