Setup a Dynamic GitHub User Profile README

j12y

Jayson DeLancey

Posted on March 18, 2023

Setup a Dynamic GitHub User Profile README

Introduced in 2020, the GitHub user profile README allow individuals to give a long-form introduction. This multi-part tutorial explains how I setup my own profile to create dynamic content to aid discovery of my projects:

You can visit github.com/j12y to see the final result of what I came up with for my own profile page.

My GitHub Profile

Getting Started with Profile README

A profile on GitHub consists of standard attributes like profile name, picture, location, bio and status. Also included on a profile page are dynamic elements such as pinned repositories, stars, followers, contribution graph and activity feed.

The GitHub profile README file adds the capability to provide additional flair and free-form content. It is a specific file and repository that will render on your profile by following the proper conventions.

To get your profile to hello world you need to follow a few steps:

  1. Create a repository named identical to your username. So for example, my repos name is "j12y" because my GitHub login is "j12y". If your login is "octocato" then the repository would be named "octocato".
  2. Create a file README.md in the repository.
  3. Put any markdown or HTML you'd like such as # Hello World in the file and commit it to the main branch.

This is the convention for individuals. For organizations, the repo is called .github and the file profile/README.md.

The result is rendered on your profile page like so:

Location of Profile README

Generally, anything that is in the README.md is what will be rendered to your profile much like it would be in the README.md within an individual repository.

I stumbled upon a list of awesome GitHub Profile READMEs and spent quite some time reviewing them for inspiration. There are some very creative folks out there that have found interesting ways to express themselves and their projects. Those and other resources go into more examples of the things you can do:

  • putting in banner images
  • collapsible sections for details
  • changing fonts
  • making tables
  • etc.

Check those resources out for some basic formatting tutorials.

Generating a README from a Template

To support the idea I had in mind for my own profile README I wanted to use a template engine. That is, I wanted to be able to fetch dynamic data and then substitute it into a template that generates the final README.md as the output.

    ┌────────────┐            ┌─────────────┐
    │            │            │             │
    │ template.a ├────────────►  README.md  │
    │            │            │             │
    └───┬────────┘            └─────────────┘
        │
        │  ┌────────────┐
        │  │            │
        ├──┤ template.b │  <----- DATA
        │  │            │
        │  └────────────┘
        │
        │  ┌────────────┐
        │  │            │
        │  │ template.c │
        └──┤            │
           └────────────┘
Enter fullscreen mode Exit fullscreen mode

I spent some time researching options:

  • handlebars
  • mustache
  • pug
  • smarty
  • liquid
  • etc.

I had used handlebars and mustache on web projects in the past and evaluated pug which was new to me and had never used before just for the sake of learning more about it. I planned this project to be a node script using TypeScript for reasons. Finding an easy to use example of Liquid + TypeScript that worked out of the box was the primary deciding factor in choosing it given I only have a few basic requirements.

Initializing the TypeScript Project

I initialized my TypeScript project:

npm init -y
npm install --save-dev typescript
npx tsc --init --rootDir src --outDir build
npm install -D @types/node 
npm install -D ts-node
Enter fullscreen mode Exit fullscreen mode

and configured tsconfig.json and package.json to run my build with npm start by executing:

ts-node ./src/app.ts
Enter fullscreen mode Exit fullscreen mode

Getting Started with a Simple Liquid Template

The source directory project is minimimalistic boilerplate and structured like this:

├── package-lock.json
├── package.json
├── src
│   ├── app.ts
│   └── template
│       ├── README.liquid
│       └── contact.liquid
└── tsconfig.json
Enter fullscreen mode Exit fullscreen mode

When src/app.ts is executed, it resolves the paths of the templates in order to generate the output README.md from the entry point of the README.liquid template.

// src/app.js
import path from 'path'
import { Liquid } from 'liquidjs'
import { writeFileSync } from 'fs'

export async function main() {
  let scope = {};

  const engine = new Liquid({
    root: path.resolve(__dirname, 'template/'),
    extname: '.liquid'
  });

  engine.renderFile('README', scope).then((content) => {
    writeFileSync(path.join(__dirname, '../README.md'), content, {flag: 'w'});
  });
}

main();
Enter fullscreen mode Exit fullscreen mode

The liquid template contains any markdown or html that should appear in the final README.md that will be generated into the root of the project.

<!-- src/template/README.liquid -->
# Hello World
Enter fullscreen mode Exit fullscreen mode

Using Shields for Visual Flair

If you've spent time on GitHub exploring repositories you've likely encountered shields. These status boxes can be either static or dynamic but provide a nice visual callout to things like build status, code coverage, downloads, follower counts, etc.

They can also serve as a helpful visualization for social links. The docs explain that any logo provided in simple-icons can be used.

So defining what you want can be used to construct a URL:

  • Label: LinkedIn
  • Message: none
  • Logo: linkedin
  • logoColor: #0077B5

Putting this together, the main entry point to the templates is src/template/README.liquid:

<!-- src/template/README.liquid -->

{% include 'contact' %}
Enter fullscreen mode Exit fullscreen mode

This includes a second template to store all of the contact information such as social profiles in src/template/contact.liquid:

<!-- src/template/contact.liquid -->
# Hello World

<div id="social" align="center">
  <a href="https://www.linkedin.com/in/jaysondelancey/" target="_blank"><img src="https://img.shields.io/badge/LinkedIn-0077B5?style=flat-square&logo=linkedin&logoColor=white" alt="@jaysondelancey on LinkedIn"/></a>
</div>
Enter fullscreen mode Exit fullscreen mode

Now we have badges that can be used for a bit more pop than HTML text anchors.

social shields

Learn More About GitHub Readme Profiles

As you let this introduction to setup of a GitHub Profile Readme marinate, the next articles will dive into some of the more interesting applications of GitHub features.

Did this help you get your own profile started? Let me know and follow to get notified about updates.

💖 💪 🙅 🚩
j12y
Jayson DeLancey

Posted on March 18, 2023

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related