<?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: ReadmeForge</title>
    <description>The latest articles on DEV Community by ReadmeForge (@readmeforge).</description>
    <link>https://dev.to/readmeforge</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4133422%2F134bfd38-4b33-41b6-9135-bc5215ef619b.png</url>
      <title>DEV Community: ReadmeForge</title>
      <link>https://dev.to/readmeforge</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/readmeforge"/>
    <language>en</language>
    <item>
      <title>Your README Is Lying to New Contributors</title>
      <dc:creator>ReadmeForge</dc:creator>
      <pubDate>Sat, 19 Sep 2026 21:17:58 +0000</pubDate>
      <link>https://dev.to/readmeforge/your-readme-is-lying-to-new-contributors-33a9</link>
      <guid>https://dev.to/readmeforge/your-readme-is-lying-to-new-contributors-33a9</guid>
      <description>&lt;h1&gt;
  
  
  Your README Is Lying to New Contributors
&lt;/h1&gt;

&lt;p&gt;Here's an experiment: pick five repos you starred in the last year. Clone one. Follow the README's setup instructions exactly. I'll wait.&lt;/p&gt;

&lt;p&gt;How many worked on the first try? In my experience, maybe two. The rest have that familiar smell — an install step that references a script that was renamed three months ago, a config example with fields that no longer exist, a "quickstart" that quietly assumes a version of a dependency from 2024.&lt;/p&gt;

&lt;p&gt;This isn't a moral failing. It's structural. And it's costing us more than we admit.&lt;/p&gt;

&lt;h2&gt;
  
  
  The onboarding tax
&lt;/h2&gt;

&lt;p&gt;A new contributor's first hour with your project is the most fragile hour in open source. They're motivated, curious, and one broken &lt;code&gt;npm install&lt;/code&gt; away from closing the tab. Every stale instruction in your README is a small betrayal of that motivation. Multiply by every person who ever cloned the repo, and README rot is one of the most expensive bugs in software — it just doesn't show up in your issue tracker, because the people it hurt never filed an issue. They just left.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why docs-as-code didn't save us
&lt;/h2&gt;

&lt;p&gt;The docs-as-code movement had the right instinct: treat documentation like code, version it, review it. But it kept the fundamental flaw — a human still has to write the update. We added linting for markdown and called it progress, but the README still goes stale the moment a PR merges that nobody bothered to document. Docs-as-code made docs &lt;em&gt;reviewable&lt;/em&gt;. It never made them &lt;em&gt;automatic&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The uncomfortable truth: documentation that depends on human diligence will always lag behind code that doesn't. Code has tests, CI, and compilers enforcing correctness. Docs have good intentions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docs as a side effect
&lt;/h2&gt;

&lt;p&gt;The way out is to stop treating doc updates as a separate task and start treating them as a side effect of the thing developers already do: pushing code. Every push already contains everything needed to update the docs — the diff &lt;em&gt;is&lt;/em&gt; the changelog, it just needs translating into human language. That's a job AI is genuinely good at, and it's a job that should run in CI, not in someone's head at 11pm.&lt;/p&gt;

&lt;p&gt;This is the bet I made building ReadmeForge: a GitHub Action that watches your pushes, diffs them, and proposes README updates as pull requests — review-first, so nothing merges without a human glance. No API key to configure, because the key lives server-side (I'm a solo dev; I have opinions about secret sprawl). Free for public repos, because the repos that need this most are the ones with the least maintenance budget.&lt;/p&gt;

&lt;p&gt;I'm not going to pretend it's a solved problem. AI-generated docs need review — that's why the default mode opens a PR instead of committing directly. Sometimes the bot updates a section you'd rather rewrite by hand. Fine. The goal was never perfect docs. The goal is docs that are &lt;em&gt;less wrong than yesterday&lt;/em&gt;, automatically, forever.&lt;/p&gt;

&lt;h2&gt;
  
  
  The real fix is cultural, but culture needs tooling
&lt;/h2&gt;

&lt;p&gt;We tell new contributors "PRs welcome, and please update the docs." Then we're surprised when they don't. What if the docs updated themselves and the contributor's job was just to approve? That's a smaller ask, and smaller asks get done.&lt;/p&gt;

&lt;p&gt;Your README is the front door of your project. Right now, for a lot of repos, the front door is stuck and the welcome mat is from 2023. You can keep blaming human nature, or you can automate the part human nature is bad at.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://readmeforge-app.netlify.app/" rel="noopener noreferrer"&gt;https://readmeforge-app.netlify.app/&lt;/a&gt; — if you want to see the side-effect approach in action.&lt;/p&gt;

</description>
      <category>programming</category>
      <category>opensource</category>
      <category>documentation</category>
    </item>
    <item>
      <title>Stop Letting Your README Rot: Auto-Sync It on Every Push</title>
      <dc:creator>ReadmeForge</dc:creator>
      <pubDate>Sat, 19 Sep 2026 21:17:23 +0000</pubDate>
      <link>https://dev.to/readmeforge/stop-letting-your-readme-rot-auto-sync-it-on-every-push-ade</link>
      <guid>https://dev.to/readmeforge/stop-letting-your-readme-rot-auto-sync-it-on-every-push-ade</guid>
      <description>&lt;h1&gt;
  
  
  Stop Letting Your README Rot: Auto-Sync It on Every Push
&lt;/h1&gt;

&lt;p&gt;Every developer has lived this: you clone a repo, follow the README's install instructions, and they don't work. The flags changed. The env vars changed. The quickstart references files that no longer exist. The README is lying to you, and it's nobody's fault — it's just that updating docs is the chore everyone postpones.&lt;/p&gt;

&lt;p&gt;I got tired of it, so I built a GitHub Action that keeps the README in sync automatically. Here's how to set it up in about two minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;READMEs rot because they're maintained by hand. The code moves fast; the docs don't. Code review catches broken logic, but nobody reviews whether the README still describes reality after a PR merges. The result: new contributors bounce, users file "docs are wrong" issues, and maintainers sigh.&lt;/p&gt;

&lt;p&gt;The fix isn't "write docs more diligently." That's a willpower solution, and willpower doesn't scale. The fix is making doc updates a side effect of pushing code.&lt;/p&gt;

&lt;h2&gt;
  
  
  The setup
&lt;/h2&gt;

&lt;p&gt;Add this workflow file to your repo (&lt;code&gt;.github/workflows/readme-sync.yml&lt;/code&gt;):&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="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;readme-sync&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;main&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;sync&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# Prevents the bot from triggering itself&lt;/span&gt;
    &lt;span class="na"&gt;if&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;!contains(github.event.head_commit.message,&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;'[skip&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;readmeforge]')"&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;contents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
      &lt;span class="na"&gt;pull-requests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;write&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;   &lt;span class="c1"&gt;# required — the Action diffs against the previous commit&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;haimhm/readmeforge-action@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pr&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. On every push to &lt;code&gt;main&lt;/code&gt;, the Action:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Computes the diff of the push (handles first pushes too, by diffing against the empty tree)&lt;/li&gt;
&lt;li&gt;Sends the diff plus your current README to the ReadmeForge API&lt;/li&gt;
&lt;li&gt;Opens a pull request with the updated README for you to review&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You merge the PR, or you don't. Nothing lands in your repo without your eyes on it — that's the default &lt;code&gt;pr&lt;/code&gt; mode. It's review-first by design.&lt;/p&gt;

&lt;h2&gt;
  
  
  How it actually works
&lt;/h2&gt;

&lt;p&gt;The Action itself is thin on purpose. It collects the diff, ships it to a hosted API over HTTPS, and applies the returned README. The AI key lives on the server side — you never paste an OpenAI/OpenRouter key into your repo secrets, which is the part of other README-sync tools I always hated. One less secret to rotate, one less thing to leak.&lt;/p&gt;

&lt;p&gt;The API returns the updated README plus a short changelog of what changed, so the PR body tells you exactly what the bot thinks it updated. If nothing doc-relevant changed, the Action exits quietly with &lt;code&gt;updated=false&lt;/code&gt; and touches nothing.&lt;/p&gt;

&lt;p&gt;Two config options worth knowing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;mode: pr&lt;/code&gt; (default) — opens a review PR. &lt;code&gt;mode: commit&lt;/code&gt; pushes directly to the branch (Pro tier only). In commit mode, the bot's commits carry a &lt;code&gt;[skip readmeforge]&lt;/code&gt; marker and the &lt;code&gt;if:&lt;/code&gt; guard in the workflow above prevents infinite loops.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;readme-path&lt;/code&gt; — if your docs live somewhere other than &lt;code&gt;README.md&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The free tier
&lt;/h2&gt;

&lt;p&gt;No key, no signup, no card. The free tier gives you 20 syncs a month on public repos. For most side projects that's plenty — it's roughly one sync per working day. If you need private repos, more volume (1,000 syncs/month), or direct-commit mode, there's a Pro tier at $9/month via Gumroad. You add the license key as a repo secret (&lt;code&gt;READMEFORGE_LICENSE_KEY&lt;/code&gt;) and pass it in:&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="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;haimhm/readmeforge-action@v1&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;commit&lt;/span&gt;
    &lt;span class="na"&gt;license-key&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ secrets.READMEFORGE_LICENSE_KEY }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why this instead of a bot you prompt manually
&lt;/h2&gt;

&lt;p&gt;You could paste your diff into ChatGPT and ask for a README update. That works exactly once, because you'll never do it twice. The whole point is removing the human from the loop: docs update because code moved, not because someone remembered.&lt;/p&gt;

&lt;p&gt;Stale READMEs are a tax every new contributor pays. Two minutes of YAML removes it. Try it: &lt;a href="https://github.com/marketplace/actions/readmeforge-readme-sync" rel="noopener noreferrer"&gt;https://github.com/marketplace/actions/readmeforge-readme-sync&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>ai</category>
      <category>devops</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
