Stop Hardcoding Your Portfolio Projects. I Built an API to Turn GitHub into a Headless CMS

Stop Hardcoding Your Portfolio Projects. I Built an API to Turn GitHub into a Headless CMS

posted Originally published at dev.to 2 min read

Every time I finished a new side project, I faced the exact same annoying routine:

  1. Open my portfolio repository.
  2. Find the projects.json or hardcoded array.
  3. Manually type in the new project name, description, and tech stack.
  4. Download a screenshot, put it in the public folder, and link it.
  5. Push changes and wait for the deployment.

As developers, we automate everything, yet we still update our portfolios like it's 2010. I got tired of this, so I built a solution: PortfolioAPI.

What is PortfolioAPI?

It’s a simple tool that turns your GitHub repositories into a Headless CMS for your portfolio. Instead of manually updating your frontend code, your portfolio fetches data directly from your GitHub repos via one fast API call.

Live Link: PortfolioAPI

How it works (It takes 2 minutes)

Step 1: Drop a meta.json in your repo
You just create a meta.json file in the root of any public GitHub repository you want to showcase.

{
  "name": "My Awesome Project",
  "description": "A short description shown on the portfolio page.",
  "imageUrl": "[https://raw.githubusercontent.com/your-username/your-repo/main/assets/screenshot.png](https://raw.githubusercontent.com/your-username/your-repo/main/assets/screenshot.png)",
  "websiteUrl": "[https://my-project.example.com](https://my-project.example.com)",
  "technologies": [
    "React",
    "TypeScript",
    "TailwindCSS"
  ]
}

Step 2: Fetch the data in your frontend
Make a single GET request using your API key. The API scans your GitHub, finds all repos with a meta.json, and returns a clean, structured array of your projects.

const fetchProjects = async () => {
  const response = await fetch('[https://api.portfolioapi.wiktormalyska.ovh/projects](https://api.portfolioapi.wiktormalyska.ovh/projects)', {
    headers: {
      'X-API-KEY': 'your_api_key_here'
    }
  });
  const data = await response.json();
  return data; // Boom! Ready to map over in React/Vue/Svelte
};

Why did I build it this way?

  • Zero Database Needed: Your code lives on GitHub anyway, why not keep its metadata there too?
  • Always Up to Date: Update the meta.json in your project repo, and your portfolio updates instantly.
  • Blazing Fast: I implemented server-side caching so the GitHub data is delivered in milliseconds. No unnecessary noise.
  • Tech Agnostic: It doesn't matter if your portfolio is built in React, Vue, Next.js, or vanilla HTML. It’s just a standard REST API.

What's next?

Right now, the API handles reading GitHub portfolios perfectly. I'm currently working on adding a dedicated Node.js package and an email contact form endpoint to make it an all-in-one backend for developer portfolios.

I’m an indie developer trying to build tools that actually save time. I’d love to hear your feedback. What do you think about managing portfolio content directly from GitHub repos?

Let me know in the comments!

Psst... with code FREETRIAL you can get first month for free! (for first 10 customers)

4 Comments

2 votes
1 vote
0 votes
0 votes

More Posts

I’m a Senior Dev and I’ve Forgotten How to Think Without a Prompt

Karol Modelskiverified - Mar 19

TypeScript Complexity Has Finally Reached the Point of Total Absurdity

Karol Modelskiverified - Apr 23

How I Built a React Portfolio in 7 Days That Landed ₹1.2L in Freelance Work

Dharanidharan - Feb 9

Your Tech Stack Isn’t Your Ceiling. Your Story Is

Karol Modelskiverified - Apr 9

Why Prompt Engineering Is Just an Expensive Way to Be Incompetent

Karol Modelskiverified - May 21
chevron_left

Related Jobs

View all jobs →

Commenters (This Week)

1 comment
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!