Podcast Title

Author Name

0:00
0:00
Album Art

How to Create a Dynamic GitHub Profile README

By 10xdev team July 14, 2025

Since July 2020, GitHub has enabled developers to create profile-level repositories, using a README file to add a personal touch to their pages. I've been aware of this feature for some time, but only recently delved into it, and perhaps I got a little carried away.

Getting Started: The Profile Repository

To get started, navigate to GitHub and create a new repository with the exact same name as your GitHub username. For instance, if your username is mvndr, the repository should also be named mvndr. Once the repository is created, I clone it to my local machine and open it in my preferred code editor.

Setting Up the Script

We will utilize a third-party module called isomorphic-fetch, which intelligently switches between unfetch for the client and node-fetch for the server. I imported the necessary dependencies into an index.js file.

To begin, I declared an async function called main. Inside this function, I first read a template file and stored its contents in a variable named readmeTemplate.

The next step involves making an API request. I made a request to 'The Office API' and assigned the resulting quote to a variable called officeQuote. Then, I replaced a specific placeholder pattern within the template file with the dynamic content received from the API.

Finally, the script overwrites the actual README.md file with the updated content from the readmeTemplate variable.

Here is a simplified example of what the script looks like:

import fetch from 'isomorphic-fetch';
import fs from 'fs';

const main = async () => {
  // 1. Read the template file
  const readmeTemplate = fs.readFileSync('./README.template.md', 'utf-8');

  // 2. Make the API request
  const officeQuoteResponse = await fetch('https://officeapi.dev/api/quotes/random');
  const { quote, character } = await officeQuoteResponse.json();
  const officeQuote = `> ${quote.content}\n> \n>  ${quote.character.firstname} ${quote.character.lastname}`;

  // 3. Replace the placeholder
  const newReadme = readmeTemplate.replace('%', officeQuote);

  // 4. Write to the actual README file
  fs.writeFileSync('./README.md', newReadme);
};

main();

Enhancing the Profile's Visuals

I manually added a file to greet visitors with an attractive banner image that links to my portfolio. To create various badges, I used shields.io, where I could customize the badge labels, colors, and destination URLs. For a bit of fun, I decided to track profile visits, so I created a visitor counter badge and placed it alongside my social media badges.

In addition to the introduction, I included sections for my latest blog posts, repositories, and Git statistics. To provide a unique and personal touch, I added a placeholder for a quote from 'The Office' in its own dedicated section. The assets directory contains two files: one for my banner and another spare image that could be used as a profile picture.

Automating with GitHub Actions

Next, I opened a dynamic-inject-workflow.yml file. I named the workflow and specified the triggers for when it should run. I scheduled a cron job to execute this workflow hourly. This ensures that new blog posts are fetched frequently and visitors are greeted with a fresh quote from 'The Office' on a regular basis.

With the basic workflow structure in place, I needed to define the jobs. The order of execution is important, so I created the first job specifically to fetch the quote. The dynamic-inject-workflow.yml file was then complete.

Here is an example of the workflow configuration:

name: Dynamic Inject Workflow

on:
  schedule:
    - cron: '0 * * * *' # Runs every hour
  workflow_dispatch:

jobs:
  inject:
    runs-on: ubuntu-latest
    steps:
      - name: Check out repository
        uses: actions/checkout@v2

      - name: Set up Node.js
        uses: actions/setup-node@v2
        with:
          node-version: '18'

      - name: Install dependencies
        run: npm install

      - name: Run injection script
        run: node ./index.js

      - name: Commit and push changes
        uses: stefanzweifel/git-auto-commit-action@v4
        with:
          commit_message: "Automated: Update README with latest data"
          branch: main
          file_pattern: README.md

Deployment and Verification

I committed my changes and pushed them to my GitHub profile repository. GitHub automatically recognized the new workflow file, and it appeared under the 'Actions' tab of the repository. To test it, I manually triggered the workflow by clicking the 'Run workflow' button and observed its execution on the main branch.

After the workflow successfully completed both of its jobs, I returned to my profile page to see the dynamic results in action.

Join the 10xdev Community

Subscribe and get 8+ free PDFs that contain detailed roadmaps with recommended learning periods for each programming language or field, along with links to free resources such as books, YouTube tutorials, and courses with certificates.

Recommended For You

Up Next