<?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: Antarr Byrd</title>
    <description>The latest articles on DEV Community by Antarr Byrd (@antarr).</description>
    <link>https://dev.to/antarr</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%2F502135%2F3f7ef983-41b2-4fc5-92d5-8b50e0cf893e.png</url>
      <title>DEV Community: Antarr Byrd</title>
      <link>https://dev.to/antarr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/antarr"/>
    <language>en</language>
    <item>
      <title>How I Built My Portfolio Site</title>
      <dc:creator>Antarr Byrd</dc:creator>
      <pubDate>Sun, 01 Mar 2026 18:24:51 +0000</pubDate>
      <link>https://dev.to/antarr/how-i-built-my-portfolio-site-4ap9</link>
      <guid>https://dev.to/antarr/how-i-built-my-portfolio-site-4ap9</guid>
      <description>&lt;h2&gt;
  
  
  From a Gatsby Fork to a Custom Next.js Stack
&lt;/h2&gt;

&lt;p&gt;Like a lot of developers, I'd been putting off rebuilding my portfolio for years. The old site was a fork of &lt;a href="https://brittanychiang.com" rel="noopener noreferrer"&gt;Brittany Chiang's v4 portfolio&lt;/a&gt; — a beautiful Gatsby setup that I'd been patching and personalizing for a while. It worked, but the codebase was aging. Dependencies were years out of date, Node 10 was the pinned version, and getting a clean local build required jumping through hoops.&lt;/p&gt;

&lt;p&gt;Eventually I decided to start fresh and build something I actually understood end-to-end. Here's what I used and why.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Stack
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Next.js 16
&lt;/h3&gt;

&lt;p&gt;I chose &lt;a href="https://nextjs.org" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt; for the rebuild. It's what I'm most productive in for React-based sites, and the App Router makes server-side rendering and metadata management straightforward. The portfolio is a static-ish site — no database, no auth — so Next.js might feel like overkill, but the ecosystem tooling (image optimization, font loading, structured data in &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt;) made it worth it.&lt;/p&gt;

&lt;p&gt;One gotcha: Netlify blocked deployment because the initial version used a Next.js release affected by &lt;a href="https://ntl.fyi/cve-2025-55182" rel="noopener noreferrer"&gt;CVE-2025-55182&lt;/a&gt;. Keeping dependencies up to date matters even on personal projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tailwind CSS 4
&lt;/h3&gt;

&lt;p&gt;Styling is handled entirely with &lt;a href="https://tailwindcss.com" rel="noopener noreferrer"&gt;Tailwind CSS&lt;/a&gt;. Version 4 drops the &lt;code&gt;tailwind.config.js&lt;/code&gt; file in favor of CSS-native configuration, which I found cleaner. The utility-first approach lets me move fast without context-switching between files.&lt;/p&gt;

&lt;h3&gt;
  
  
  Framer Motion
&lt;/h3&gt;

&lt;p&gt;Animations are handled by &lt;a href="https://www.framer.com/motion/" rel="noopener noreferrer"&gt;Framer Motion&lt;/a&gt;. The hero section fades and slides in on load — nothing too aggressive, just enough to give the page some life. The &lt;code&gt;motion&lt;/code&gt; component API keeps animations colocated with the markup rather than scattered across stylesheets.&lt;/p&gt;

&lt;h3&gt;
  
  
  YAML Content Files
&lt;/h3&gt;

&lt;p&gt;All projects and experience entries live in YAML files under &lt;code&gt;content/&lt;/code&gt;. A &lt;code&gt;js-yaml&lt;/code&gt; utility reads them at build time and passes the data into the page components. This keeps content completely separate from presentation — adding or removing a project is just editing a file, no component changes needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# content/projects/example.yaml&lt;/span&gt;
&lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;My&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Project"&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;|"&lt;/span&gt;
  &lt;span class="s"&gt;A short description of what this does.&lt;/span&gt;
&lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;Ruby on Rails&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;PostgreSQL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  TypeScript
&lt;/h3&gt;

&lt;p&gt;The whole codebase is TypeScript. Nothing exotic — mostly typed props and API response shapes. It pays for itself quickly when you're refactoring content structures.&lt;/p&gt;




&lt;h2&gt;
  
  
  Deployment: Netlify
&lt;/h2&gt;

&lt;p&gt;The site deploys automatically via &lt;a href="https://netlify.com" rel="noopener noreferrer"&gt;Netlify&lt;/a&gt; on every push to &lt;code&gt;main&lt;/code&gt;. Build settings are defined in &lt;code&gt;netlify.toml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[build]&lt;/span&gt;
  &lt;span class="py"&gt;command&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"npm run build"&lt;/span&gt;
  &lt;span class="py"&gt;publish&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;".next"&lt;/span&gt;

&lt;span class="nn"&gt;[build.environment]&lt;/span&gt;
  &lt;span class="py"&gt;NODE_VERSION&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"22"&lt;/span&gt;

&lt;span class="nn"&gt;[[plugins]]&lt;/span&gt;
  &lt;span class="py"&gt;package&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"@netlify/plugin-nextjs"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pinning the Node version in &lt;code&gt;netlify.toml&lt;/code&gt; is important — without it, Netlify defaults to an older version that may not match your local environment.&lt;/p&gt;




&lt;h2&gt;
  
  
  SEO &amp;amp; Structured Data
&lt;/h2&gt;

&lt;p&gt;I added a &lt;code&gt;Person&lt;/code&gt; JSON-LD block in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; to help Google's Knowledge Graph associate my professional profiles with my domain:&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="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@context"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://schema.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Person"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Antarr Byrd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"url"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://antarr.dev"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sameAs"&lt;/span&gt;&lt;span class="p"&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="s2"&gt;"https://www.linkedin.com/in/antarrbyrd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"https://github.com/antarr"&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="nl"&gt;"worksFor"&lt;/span&gt;&lt;span class="p"&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="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Organization"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Jay Bird Consulting Group LLC"&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="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;You can validate your own with Google's &lt;a href="https://search.google.com/test/rich-results" rel="noopener noreferrer"&gt;Rich Results Test&lt;/a&gt;. Note: &lt;code&gt;Person&lt;/code&gt; schema won't show as a "rich result" in that tool — use the legacy &lt;a href="https://validator.schema.org" rel="noopener noreferrer"&gt;Structured Data Testing Tool&lt;/a&gt; to see it parsed correctly.&lt;/p&gt;




&lt;h2&gt;
  
  
  Node Version Management: fnm
&lt;/h2&gt;

&lt;p&gt;I use &lt;a href="https://github.com/Schniz/fnm" rel="noopener noreferrer"&gt;fnm&lt;/a&gt; (Fast Node Manager) instead of nvm. It's faster, written in Rust, and reads &lt;code&gt;.nvmrc&lt;/code&gt; files automatically. The project pins Node 22 in &lt;code&gt;.nvmrc&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;22.20.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Start with a clean repo.&lt;/strong&gt; The old site was a GitHub fork, which meant I couldn't fully detach from the upstream fork network. Starting fresh in a new repo avoided all that overhead.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pin Node early.&lt;/strong&gt; A lot of early build failures came down to running the wrong Node version locally versus what Netlify expected.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use YAML for content from day one.&lt;/strong&gt; Keeping content in structured files rather than hardcoded JSX made it easy to iterate on what to show publicly.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;The full source is private, but feel free to reach out if you have questions about any part of the setup.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>portfolio</category>
      <category>tailwindcss</category>
      <category>nextjs</category>
    </item>
  </channel>
</rss>
