<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sébastien Doom</title>
    <description>The latest articles on DEV Community by Sébastien Doom (@zansuken).</description>
    <link>https://dev.to/zansuken</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3825569%2Fb45bdc6e-e164-477f-a261-23a67f82023c.webp</url>
      <title>DEV Community: Sébastien Doom</title>
      <link>https://dev.to/zansuken</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/zansuken"/>
    <language>en</language>
    <item>
      <title>I Rebuilt My Portfolio's Backend Three Times Before Landing on This Stack</title>
      <dc:creator>Sébastien Doom</dc:creator>
      <pubDate>Wed, 08 Apr 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/zansuken/i-rebuilt-my-portfolios-backend-three-times-before-landing-on-this-stack-2659</link>
      <guid>https://dev.to/zansuken/i-rebuilt-my-portfolios-backend-three-times-before-landing-on-this-stack-2659</guid>
      <description>&lt;p&gt;The first version used a cron job. Every six hours, it would hit the GitHub API, pull repo data, and write it to a JSON file that got committed back to the repo. It worked for about a week.&lt;/p&gt;

&lt;p&gt;Then I hit GitHub's rate limit. Then the cron silently failed for three days and nobody noticed. Then I realized the JSON file had grown to 4MB because I was storing every commit message for every repo.&lt;/p&gt;

&lt;p&gt;I was building &lt;a href="https://getfolio.dev" rel="noopener noreferrer"&gt;getfolio.dev&lt;/a&gt;, a service that generates developer portfolios synced live with GitHub. The whole point was that your portfolio would never go stale. Which meant the data layer couldn't be fragile. It had to actually work at scale, for hundreds of users, without me babysitting a cron tab.&lt;/p&gt;

&lt;p&gt;So I rewrote it. And then I rewrote it again.&lt;/p&gt;

&lt;h2&gt;
  
  
  Version 1: Static JSON + GitHub Actions
&lt;/h2&gt;

&lt;p&gt;The appeal was simplicity. GitHub Actions triggers on a schedule, fetches API data, commits a JSON file, Vercel rebuilds. Zero infrastructure.&lt;/p&gt;

&lt;p&gt;Problems showed up fast. Rate limiting was the obvious one. But the deeper issue was latency. A user signs up, connects their GitHub, and then waits up to six hours to see their repos populate. That's not a product. That's a broken promise.&lt;/p&gt;

&lt;h2&gt;
  
  
  Version 2: Serverless Functions + Direct API Calls
&lt;/h2&gt;

&lt;p&gt;Next attempt: call GitHub's API on every page load through a Next.js API route. Fresh data every time.&lt;/p&gt;

&lt;p&gt;This solved the staleness problem and created a new one. GitHub's REST API isn't slow exactly, but when you're fetching repos, languages, contribution data, and pinned items, you're looking at 4-5 sequential requests. Page loads went from 200ms to 2+ seconds. Some users had 80+ repos. That made it worse.&lt;/p&gt;

&lt;p&gt;I tried parallelizing the requests with &lt;code&gt;Promise.all&lt;/code&gt;. Got it down to about 900ms on a good day. Still too slow for a portfolio that someone might bounce from in under three seconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Version 3: Firebase + Smart Caching (What Actually Shipped)
&lt;/h2&gt;

&lt;p&gt;The solution that stuck uses Firebase as a caching and sync layer between GitHub and the portfolio.&lt;/p&gt;

&lt;p&gt;When a user connects their account, we do a full initial fetch and store the processed data in Firestore. After that, we use a combination of webhooks (when available) and intelligent polling to keep things current. The polling interval adapts. If you pushed code today, we check more frequently. If your last commit was three weeks ago, we back off.&lt;/p&gt;

&lt;p&gt;Page loads hit Firestore, not GitHub. Response times dropped back to ~150ms.&lt;/p&gt;

&lt;p&gt;The schema looks roughly like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3txwd8wivo8jkkin99ba.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3txwd8wivo8jkkin99ba.png" alt=" " width="696" height="530"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;users/&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;github_profile:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;repos/&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="err"&gt;repo_id&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;stars&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;forks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;languages:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;TypeScript:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;14500&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;CSS:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3200&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;last_pushed:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="err"&gt;pinned:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;boolean&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="err"&gt;sync_meta:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;last_full_sync:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;next_scheduled:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;timestamp&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="err"&gt;poll_interval_minutes:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The adaptive polling was the part that took the longest to get right. Too aggressive and you burn through API quota across all users. Too passive and someone pushes a cool project and their portfolio doesn't reflect it for a day.&lt;/p&gt;

&lt;p&gt;Current logic: base interval of 360 minutes. If &lt;code&gt;last_pushed&lt;/code&gt; is within 24 hours, drop to 60 minutes. Within the last hour, drop to 15. It's simple and it works.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Rest of the Stack
&lt;/h2&gt;

&lt;p&gt;For anyone curious about the full picture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Next.js 14 App Router&lt;/strong&gt; for the portfolio rendering and the dashboard. Server components handle the data-heavy portfolio pages. Client components for the drag-drop editor and theme preview.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tailwind + Framer Motion&lt;/strong&gt; for styling and animations across the five themes (DarkPro, Terminal, Minimal, Glass, Editorial). Each theme is a separate component tree, not a CSS swap.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stripe&lt;/strong&gt; for billing. Pro plan unlocks custom domains and analytics.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vercel&lt;/strong&gt; for hosting. Edge functions for the custom domain resolution.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I'd Do Differently
&lt;/h2&gt;

&lt;p&gt;I'd skip version 1 and 2 entirely and start with the caching layer. The instinct to keep things simple by avoiding a database was wrong. The database &lt;em&gt;is&lt;/em&gt; what made it simple. Without it, I was fighting the GitHub API's constraints on every request.&lt;/p&gt;

&lt;p&gt;If you're building anything that depends on a third-party API as a primary data source, put a cache in front of it from day one. Not as an optimization. As architecture.&lt;/p&gt;

&lt;p&gt;Getfolio launches soon. The early version is live at &lt;a href="https://getfolio.dev" rel="noopener noreferrer"&gt;getfolio.dev&lt;/a&gt; if you want to see how your GitHub data looks across different themes.&lt;/p&gt;

&lt;p&gt;What's a technical decision in your projects that you got wrong twice before finding the right approach? Curious what other people's version 1 → version 3 journeys looked like 🛠️&lt;/p&gt;




&lt;p&gt;Originally published on &lt;a href="https://getfolio.dev" rel="noopener noreferrer"&gt;getfolio.dev&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>nextjs</category>
      <category>firebase</category>
      <category>portfolio</category>
    </item>
    <item>
      <title>How to Build a Developer Portfolio That Updates Itself From Your GitHub Profile</title>
      <dc:creator>Sébastien Doom</dc:creator>
      <pubDate>Wed, 01 Apr 2026 10:00:00 +0000</pubDate>
      <link>https://dev.to/zansuken/how-to-build-a-developer-portfolio-that-updates-itself-from-your-github-profile-53bk</link>
      <guid>https://dev.to/zansuken/how-to-build-a-developer-portfolio-that-updates-itself-from-your-github-profile-53bk</guid>
      <description>&lt;p&gt;Your GitHub profile already tells a detailed story about you as a developer. The languages you use most, the repos you've contributed to recently, your commit frequency, the projects you've starred. All of it is there, structured and current.&lt;/p&gt;

&lt;p&gt;The weird part is that most developer portfolios ignore all of this. They're static sites that repeat a fraction of what GitHub already knows, manually maintained, and quietly drifting out of date.&lt;/p&gt;

&lt;p&gt;What if your portfolio just read from GitHub directly and kept itself current?&lt;/p&gt;

&lt;p&gt;That's what this article walks through. The end result: a live portfolio that reflects your actual GitHub activity without you touching it after setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  What "GitHub as Identity" Actually Means in Practice
&lt;/h2&gt;

&lt;p&gt;Recruiters and hiring managers already look at your GitHub. A 2023 Stack Overflow survey showed that 85% of developers have a GitHub account, and many hiring processes include a profile review before or during interviews.&lt;/p&gt;

&lt;p&gt;But GitHub's native profile page wasn't designed to sell you. It's a project management interface. There's no hierarchy telling a visitor "look at this project first" or "these are the languages I'm strongest in." And there's no way to add context like blog posts, contact info, or a personal statement alongside the code.&lt;/p&gt;

&lt;p&gt;A portfolio that pulls from GitHub fills that gap. It takes the raw signal (repos, languages, contribution graphs, star counts) and presents it in a format that's designed for humans evaluating you. Not other developers browsing code.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Decide What Data Should Be Live vs. Curated
&lt;/h2&gt;

&lt;p&gt;Not everything from GitHub belongs on your portfolio. You probably want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live data&lt;/strong&gt;: contribution graph, top languages by usage, star counts, recent activity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Curated&lt;/strong&gt;: which repos to feature, what order they appear in, project descriptions rewritten for a non-technical audience&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The live stuff keeps your portfolio feeling current. The curated stuff gives you editorial control. A good portfolio setup handles both.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Connect GitHub and Generate the Base
&lt;/h2&gt;

&lt;p&gt;You can build this yourself with the GitHub API, a static site generator, and a cron job. That works. It's also a side project you'll maintain for approximately two weekends before it joins the graveyard.&lt;/p&gt;

&lt;p&gt;The faster path is a tool built specifically for this. &lt;a href="https://getfolio.dev" rel="noopener noreferrer"&gt;Getfolio&lt;/a&gt; connects to your GitHub account, pulls your repos, languages, contribution data, and stars, then generates a portfolio from it in about 60 seconds. You pick a theme (there are 5, ranging from a terminal aesthetic to a clean editorial layout), and the data stays synced automatically going forward.&lt;/p&gt;

&lt;p&gt;No cron jobs. No rebuilds. Push a commit to a featured repo on Tuesday, and your portfolio reflects it on Tuesday.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Add the Stuff GitHub Doesn't Have
&lt;/h2&gt;

&lt;p&gt;GitHub knows your code. It doesn't know your blog posts, your preferred contact method, or the two-sentence summary of why you built that CLI tool.&lt;/p&gt;

&lt;p&gt;Getfolio has a drag-and-drop editor for arranging sections, and it syncs blog posts from DEV.to and Hashnode if you write on either platform. So the portfolio becomes a single page that combines your code activity with your writing and your contact info. All of it updating without manual intervention.&lt;/p&gt;

&lt;p&gt;You can also connect a custom domain on the Pro plan, which matters more than people think. &lt;code&gt;yourname.dev&lt;/code&gt; in a recruiter's browser tab reads differently than a subdomain on someone else's platform.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Set It and Check Back Monthly
&lt;/h2&gt;

&lt;p&gt;The whole point of a GitHub-synced portfolio is that you stop maintaining it as a separate project. Your real work updates it.&lt;/p&gt;

&lt;p&gt;That said, it's worth checking in once a month to reorder featured repos if your focus has shifted, or to add a new blog post section. Five minutes, not five hours.&lt;/p&gt;

&lt;h2&gt;
  
  
  What This Looks Like Over Time
&lt;/h2&gt;

&lt;p&gt;After 3 months of normal development work, a synced portfolio will show:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Updated language percentages as you pick up new tools&lt;/li&gt;
&lt;li&gt;Fresh contribution activity proving you're actively building&lt;/li&gt;
&lt;li&gt;New repos appearing automatically&lt;/li&gt;
&lt;li&gt;Recent blog posts pulled in without copy-pasting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Compare that to a static portfolio from 3 months ago, which looks exactly like it did the day you deployed it. That delta is visible to anyone reviewing candidates.&lt;/p&gt;




&lt;p&gt;The least interesting thing about your portfolio should be maintaining it. If your GitHub already represents what you build, let it do the heavy lifting.&lt;/p&gt;

&lt;p&gt;You can try it free at &lt;a href="https://getfolio.dev/#waitlist" rel="noopener noreferrer"&gt;getfolio.dev&lt;/a&gt; 🛠️&lt;/p&gt;

</description>
      <category>github</category>
      <category>webdev</category>
      <category>career</category>
      <category>portfolio</category>
    </item>
    <item>
      <title>Your Portfolio Says React 16 But Your GitHub Says Next.js 14</title>
      <dc:creator>Sébastien Doom</dc:creator>
      <pubDate>Wed, 25 Mar 2026 16:00:00 +0000</pubDate>
      <link>https://dev.to/zansuken/your-portfolio-says-react-16-but-your-github-says-nextjs-14-51li</link>
      <guid>https://dev.to/zansuken/your-portfolio-says-react-16-but-your-github-says-nextjs-14-51li</guid>
      <description>&lt;h2&gt;
  
  
  The tech stack credibility gap
&lt;/h2&gt;

&lt;p&gt;Here's something that happens more often than anyone admits: a developer lists "React, Node.js, Express, MongoDB" on their portfolio because that's what they knew when they built it. Meanwhile, their actual GitHub activity from the last six months tells a completely different story — Next.js App Router, tRPC, Drizzle ORM, maybe some Rust creeping in on the side.&lt;/p&gt;

&lt;p&gt;The portfolio becomes a fossil record of who you were, not who you are.&lt;/p&gt;

&lt;p&gt;And the awkward part? Recruiters and hiring managers actually look at this stuff. They compare what you claim against what they can find. When your portfolio says one thing and your recent commits say another, it doesn't read as "oh, they just forgot to update it." It reads as inconsistency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why tech stack sections rot so fast
&lt;/h2&gt;

&lt;p&gt;Developers pick up new tools constantly. That's literally the job. But updating a portfolio is a manual, disconnected process:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You learn TypeScript deeply over three months of real project work, but your portfolio still says "JavaScript" because you built the site before the switch&lt;/li&gt;
&lt;li&gt;You move from REST to GraphQL to tRPC, but the skills grid hasn't changed since you copy-pasted it from a template&lt;/li&gt;
&lt;li&gt;Your most-used language on GitHub shifted from JavaScript to TypeScript eight months ago, and your portfolio has no idea&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The data already exists. GitHub tracks your languages by repo, by percentage, by recent activity. The contribution graph shows when and how much you code. Stars and forks signal which projects resonated with other developers.&lt;/p&gt;

&lt;p&gt;None of that makes it to your portfolio unless you manually go update it. Which means it almost never happens.&lt;/p&gt;

&lt;h2&gt;
  
  
  What an honest tech stack section would actually show
&lt;/h2&gt;

&lt;p&gt;Imagine your portfolio's tech stack section worked like your GitHub language breakdown — automatically weighted by actual usage, updated every time you push code. Not a self-reported list of logos you picked from a grid, but a real reflection of what you've been building with.&lt;/p&gt;

&lt;p&gt;That's the core idea behind &lt;a href="https://getfolio.dev" rel="noopener noreferrer"&gt;Getfolio&lt;/a&gt;. It pulls your GitHub data — languages, repos, contribution activity, stars — and keeps your portfolio in sync automatically. Your tech stack section reflects your actual recent work, not a snapshot from whenever you last had the energy to edit HTML.&lt;/p&gt;

&lt;p&gt;Setup takes about 60 seconds. Connect GitHub, pick a theme, and your portfolio stays current from that point forward.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real cost of an outdated tech stack section
&lt;/h2&gt;

&lt;p&gt;This isn't just about aesthetics. Consider what happens in practice:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You undersell yourself.&lt;/strong&gt; You've been writing TypeScript for a year, but your portfolio doesn't mention it. A recruiter searching for TypeScript developers never finds you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You invite skepticism.&lt;/strong&gt; A hiring manager sees "Node.js, Express" on your portfolio but your pinned repos are all Bun and Hono. Now they're wondering what else is inaccurate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You miss the specificity that matters.&lt;/strong&gt; Saying "React" is almost meaningless in 2024. Are you writing RSCs? Using Server Actions? Still on Create React App? Your GitHub knows. Your portfolio should too.&lt;/p&gt;

&lt;h2&gt;
  
  
  The low-effort fix
&lt;/h2&gt;

&lt;p&gt;The developers who look most credible online aren't necessarily the best engineers. They're the ones whose public presence accurately reflects their current work. That's it.&lt;/p&gt;

&lt;p&gt;The gap between "what I actually know" and "what my portfolio says I know" shouldn't require a weekend project to close. If your code is already on GitHub, the data is already there — it just needs to show up where people are actually evaluating you.&lt;/p&gt;

&lt;p&gt;Five themes are available (including a Terminal theme that feels right for the DEV.to crowd 🖥️), plus custom domains and a drag-drop editor on the Pro plan. But honestly, the part that matters most is the sync. Update your portfolio by doing what you already do: writing code and pushing it.&lt;/p&gt;




&lt;p&gt;Originally published on &lt;a href="https://getfolio.dev" rel="noopener noreferrer"&gt;getfolio.dev&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>github</category>
      <category>career</category>
      <category>portfolio</category>
    </item>
    <item>
      <title>Your GitHub is Your Portfolio — But It's Hard to Share</title>
      <dc:creator>Sébastien Doom</dc:creator>
      <pubDate>Wed, 18 Mar 2026 15:59:32 +0000</pubDate>
      <link>https://dev.to/zansuken/your-github-is-your-portfolio-but-its-hard-to-share-3e12</link>
      <guid>https://dev.to/zansuken/your-github-is-your-portfolio-but-its-hard-to-share-3e12</guid>
      <description>&lt;p&gt;Your GitHub profile is the most honest thing about you as a developer.&lt;/p&gt;

&lt;p&gt;It's not a resume with buzzwords. It's not a cover letter optimized for HR keywords. It's code you actually wrote, decisions you made, problems you solved. The commit history, the languages you reach for, the projects you care enough to maintain — that's real.&lt;/p&gt;

&lt;p&gt;And yet most developers still treat their portfolio like a separate project they'll "get to eventually."&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem With Portfolios
&lt;/h2&gt;

&lt;p&gt;Here's what usually happens:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You build a portfolio site. Maybe it's a Next.js template, maybe you hand-code something beautiful. It takes a weekend.&lt;/li&gt;
&lt;li&gt;You add your best projects. You write descriptions. You pick your favorite screenshot.&lt;/li&gt;
&lt;li&gt;You deploy it. It's live. You feel good.&lt;/li&gt;
&lt;li&gt;Three weeks later, you ship a new project on GitHub. Your portfolio is now out of date.&lt;/li&gt;
&lt;li&gt;Six months pass. Your portfolio shows projects you don't maintain anymore. Your most interesting recent work isn't there. Anyone who looks at it sees a frozen snapshot from last spring.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Meanwhile, your actual GitHub profile keeps evolving. You're shipping things. You're learning new tech. You're contributing. But none of that automatically makes it to your portfolio.&lt;/p&gt;

&lt;p&gt;So you end up choosing: keep the portfolio in sync (which means rebuilding it every time something changes), or let it become stale (which is what most developers do).&lt;/p&gt;

&lt;p&gt;There's a third option, though.&lt;/p&gt;

&lt;h2&gt;
  
  
  What If Your Portfolio Stayed in Sync Automatically?
&lt;/h2&gt;

&lt;p&gt;The boring fact is: you already have the data. GitHub knows what you've built. It knows your languages, your most-starred projects, the repos you care about, the ones that are active vs. dormant. It knows the graph of what you've actually done.&lt;/p&gt;

&lt;p&gt;What if a portfolio didn't require separate maintenance? What if it lived off your GitHub data, updating automatically as you push code?&lt;/p&gt;

&lt;p&gt;That changes the equation. Your portfolio becomes a window into what you actually build — not what you built once and froze in time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://getfolio.dev" rel="noopener noreferrer"&gt;Getfolio&lt;/a&gt; will do that. You connect your GitHub, pick a theme, optionally customize it, and your portfolio syncs live with your activity. Your top languages update. Your repo list updates. Your contribution graph is always current. You can add a blog if you want, or link one from DEV.to or Hashnode. You get a custom domain if you need it. But the portfolio itself — the signal, the proof of what you build — that's always live.&lt;/p&gt;

&lt;p&gt;It's not about removing the work from your portfolio. It's about removing the wrong work: the busywork of keeping a separate site in sync, the anxiety about it being outdated, the pressure to make it "perfect."&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;When someone lands on your portfolio, they should see you. Not a best-of reel from 2023. Not a polished version of you. You.&lt;/p&gt;

&lt;p&gt;GitHub is honest because it's where you actually work. A portfolio that pulls from GitHub is honest too.&lt;/p&gt;

&lt;p&gt;The setup takes about a minute. You can use the free plan right now if you want to try it. The idea is simple: show what you actually build, and let your portfolio prove it.&lt;/p&gt;

</description>
      <category>github</category>
      <category>portfolio</category>
      <category>career</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
