<?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: Vojta Holeš</title>
    <description>The latest articles on DEV Community by Vojta Holeš (@holesvojta).</description>
    <link>https://dev.to/holesvojta</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%2F3964959%2F531cf34d-7e89-4bc8-b771-904952b5c25b.png</url>
      <title>DEV Community: Vojta Holeš</title>
      <link>https://dev.to/holesvojta</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/holesvojta"/>
    <language>en</language>
    <item>
      <title>I Added AI Auto-Fix to My Breaking Change Detector — Here's How /fix Works</title>
      <dc:creator>Vojta Holeš</dc:creator>
      <pubDate>Fri, 05 Jun 2026 13:59:55 +0000</pubDate>
      <link>https://dev.to/holesvojta/i-added-ai-auto-fix-to-my-breaking-change-detector-heres-how-fix-works-1h34</link>
      <guid>https://dev.to/holesvojta/i-added-ai-auto-fix-to-my-breaking-change-detector-heres-how-fix-works-1h34</guid>
      <description>&lt;p&gt;Last week I shipped a feature I've been wanting for months: type /fix in a GitHub PR comment and get a fix PR generated automatically.&lt;/p&gt;

&lt;p&gt;Context&lt;br&gt;
BreakShield CI is a GitHub App I built that detects breaking API changes in PRs using AST analysis. It catches removed fields, changed types, deleted endpoints — the stuff that slips through code review and breaks production.&lt;/p&gt;

&lt;p&gt;But detection without a fix is just a fancy error message. So I added /fix.&lt;/p&gt;

&lt;p&gt;How /fix works&lt;br&gt;
When you comment /fix on a PR that has breaking changes:&lt;/p&gt;

&lt;p&gt;BreakShield reacts with 👀 (acknowledged)&lt;br&gt;
Fetches the affected file from the PR head&lt;br&gt;
Sends it to your configured AI provider with:&lt;br&gt;
The file content&lt;br&gt;
What field/type was removed or changed&lt;br&gt;
The before/after schema&lt;br&gt;
AI generates the fixed file&lt;br&gt;
BreakShield creates a new branch, commits the fix, opens a PR&lt;br&gt;
Reacts with 🚀 (done)&lt;br&gt;
Multi-provider support&lt;br&gt;
You pick the AI:&lt;/p&gt;

&lt;p&gt;Provider    Free?   Best model&lt;br&gt;
Gemini          ✅ 2.5 Flash&lt;br&gt;
OpenAI          ❌ GPT-5.4 mini&lt;br&gt;
Claude          ❌ Haiku 4.5&lt;br&gt;
Groq            ✅ Llama 3.3 70B&lt;br&gt;
Perplexity  ❌ Sonar Pro&lt;br&gt;
Configure in the dashboard. BYOK — your key, your model, your choice.&lt;/p&gt;

&lt;p&gt;Why not just use AI for detection too?&lt;br&gt;
Because LLMs hallucinate. AST analysis doesn't.&lt;/p&gt;

&lt;p&gt;Detection needs to be precise. 92% confidence means "I found this in the syntax tree, it's definitely gone." Not "I think maybe something changed."&lt;/p&gt;

&lt;p&gt;AI is great for generating fixes. Terrible for detection where false positives erode trust.&lt;/p&gt;

&lt;p&gt;Try it&lt;br&gt;
Install: &lt;a href="https://github.com/apps/breakshield-ci" rel="noopener noreferrer"&gt;https://github.com/apps/breakshield-ci&lt;/a&gt;&lt;br&gt;
Add an API key in settings (Groq is free)&lt;br&gt;
Open a PR that removes a field from a TypeScript interface&lt;br&gt;
Wait for BreakShield's comment&lt;br&gt;
Reply with /fix&lt;br&gt;
Watch the magic&lt;br&gt;
Source: &lt;a href="https://github.com/vojtisprime11/BreakShield" rel="noopener noreferrer"&gt;https://github.com/vojtisprime11/BreakShield&lt;/a&gt;&lt;/p&gt;

</description>
      <category>github</category>
      <category>ai</category>
      <category>opensource</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Free and open-source GitHub App for TypeScript teams. Detects breaking API changes in PRs using AST analysis and offers AI auto-fix with /fix command. Just shipped multi-provider support (Gemini, OpenAI, Claude, Groq). Would love feedback from anyone worki</title>
      <dc:creator>Vojta Holeš</dc:creator>
      <pubDate>Thu, 04 Jun 2026 19:41:31 +0000</pubDate>
      <link>https://dev.to/holesvojta/free-and-open-source-github-app-for-typescript-teams-detects-breaking-api-changes-in-prs-using-ast-21eg</link>
      <guid>https://dev.to/holesvojta/free-and-open-source-github-app-for-typescript-teams-detects-breaking-api-changes-in-prs-using-ast-21eg</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/holesvojta/you-shouldnt-need-a-production-incident-to-find-breaking-api-changes-4e70" class="crayons-story__hidden-navigation-link"&gt;You Shouldn't Need a Production Incident to Find Breaking API Changes&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/holesvojta" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F3964959%2F531cf34d-7e89-4bc8-b771-904952b5c25b.png" alt="holesvojta profile" class="crayons-avatar__image" width="96" height="96"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/holesvojta" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Vojta Holeš
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Vojta Holeš
                
              
              &lt;div id="story-author-preview-content-3822023" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/holesvojta" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F3964959%2F531cf34d-7e89-4bc8-b771-904952b5c25b.png" class="crayons-avatar__image" alt="" width="96" height="96"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Vojta Holeš&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/holesvojta/you-shouldnt-need-a-production-incident-to-find-breaking-api-changes-4e70" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jun 4&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/holesvojta/you-shouldnt-need-a-production-incident-to-find-breaking-api-changes-4e70" id="article-link-3822023"&gt;
          You Shouldn't Need a Production Incident to Find Breaking API Changes
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/github"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;github&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/typescript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;typescript&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devtools"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devtools&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/api"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;api&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/holesvojta/you-shouldnt-need-a-production-incident-to-find-breaking-api-changes-4e70" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/raised-hands-74b2099fd66a39f2d7eed9305ee0f4553df0eb7b4f11b01b6b1b499973048fe5.svg" width="24" height="24"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;1&lt;span class="hidden s:inline"&gt;&amp;nbsp;reaction&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/holesvojta/you-shouldnt-need-a-production-incident-to-find-breaking-api-changes-4e70#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            3 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>ai</category>
      <category>opensource</category>
      <category>showdev</category>
      <category>typescript</category>
    </item>
    <item>
      <title>You Shouldn't Need a Production Incident to Find Breaking API Changes</title>
      <dc:creator>Vojta Holeš</dc:creator>
      <pubDate>Thu, 04 Jun 2026 19:39:35 +0000</pubDate>
      <link>https://dev.to/holesvojta/you-shouldnt-need-a-production-incident-to-find-breaking-api-changes-4e70</link>
      <guid>https://dev.to/holesvojta/you-shouldnt-need-a-production-incident-to-find-breaking-api-changes-4e70</guid>
      <description>&lt;p&gt;You open Slack on Monday morning. There's a thread with 43 replies. Someone merged a PR on Friday. A field got removed from an API response. Three services are broken. Customers are affected. Nobody caught it in review.&lt;/p&gt;

&lt;p&gt;It didn't have to happen.&lt;/p&gt;

&lt;p&gt;The Problem Nobody Talks About&lt;br&gt;
Code review catches logic bugs, style issues, missing tests. But it almost never catches API contract violations.&lt;/p&gt;

&lt;p&gt;A required field disappears from a response type&lt;br&gt;
A parameter type changes from string to number&lt;br&gt;
An endpoint gets deleted&lt;br&gt;
A new required field appears in a request body&lt;br&gt;
These are invisible in a diff. The TypeScript compiler won't warn you. Your tests pass because they mock the old contract. ESLint doesn't care.&lt;/p&gt;

&lt;p&gt;And then production cares. A lot.&lt;/p&gt;

&lt;p&gt;What If Your CI Caught It First?&lt;br&gt;
I built BreakShield CI — a GitHub App that analyzes every PR for breaking API changes.&lt;/p&gt;

&lt;p&gt;Not with an LLM. Not with vibes. With AST analysis.&lt;/p&gt;

&lt;p&gt;It parses your TypeScript code, diffs the abstract syntax tree between base and head, and flags exactly what changed, where it's used, and how dangerous it is.&lt;/p&gt;

&lt;p&gt;What It Detects&lt;br&gt;
Change type Example&lt;br&gt;
Removed field   UserResponse.email deleted&lt;br&gt;
Changed type    id: number → id: string&lt;br&gt;
Removed endpoint    GET /api/users/:id gone&lt;br&gt;
Added required field    New organizationId required in request&lt;br&gt;
Changed return type Function returns Promise instead of Promise&lt;br&gt;
Removed interface   PaymentMethod type deleted entirely&lt;br&gt;
Every finding comes with:&lt;/p&gt;

&lt;p&gt;Confidence score (80%+ = AST-verified, no guessing)&lt;br&gt;
Consumer search — which files in your repo actually use that field&lt;br&gt;
Risk level — CRITICAL / HIGH / MEDIUM / LOW / SAFE&lt;br&gt;
Before/after — what it was, what it is now&lt;br&gt;
AI Auto-Fix. In the PR.&lt;br&gt;
Detection is only half the story. You also need a fix.&lt;/p&gt;

&lt;p&gt;BreakShield CI now supports AI-generated fixes — directly from your PR.&lt;/p&gt;

&lt;p&gt;Type /fix as a comment in your PR. BreakShield:&lt;/p&gt;

&lt;p&gt;Reads the affected file&lt;br&gt;
Sends it to your AI provider with context about what broke&lt;br&gt;
Generates the fix&lt;br&gt;
Opens a new PR with the corrected code&lt;br&gt;
You review. You merge. Done.&lt;/p&gt;

&lt;p&gt;Supported Providers&lt;br&gt;
Provider    Models  Free tier?&lt;br&gt;
Google Gemini   3.5 Flash, 2.5 Pro, 2.5 Flash   ✅&lt;br&gt;
OpenAI  GPT-5.5, GPT-5.4, GPT-5.4 mini  ✅&lt;br&gt;
Anthropic   Claude Opus 4.8, Sonnet 4.6, Haiku 4.5&lt;br&gt;&lt;br&gt;
Groq    GPT-OSS 120B, Llama 3.3 70B, Qwen3 32B  ✅&lt;br&gt;
Perplexity  Sonar Deep Research, Sonar Pro  ✅&lt;br&gt;
BYOK — bring your own key. You pick the provider and model in settings.&lt;/p&gt;

&lt;p&gt;How It Works Under the Hood&lt;br&gt;
No magic. No "AI-powered detection." Here's what actually happens:&lt;/p&gt;

&lt;p&gt;PR opened/updated&lt;br&gt;
       ↓&lt;br&gt;
GitHub webhook fires&lt;br&gt;
       ↓&lt;br&gt;
Fetch changed files (base vs head)&lt;br&gt;
       ↓&lt;br&gt;
Parse both versions with ts-morph (TypeScript AST)&lt;br&gt;
       ↓&lt;br&gt;
Diff exported interfaces, types, functions, endpoints&lt;br&gt;
       ↓&lt;br&gt;
For each breaking change → search repo for consumers&lt;br&gt;
       ↓&lt;br&gt;
Calculate risk score → post PR comment + check run&lt;br&gt;
The detection is deterministic. Same code → same result. Every time.&lt;/p&gt;

&lt;p&gt;AI is only involved when you explicitly ask for a fix.&lt;/p&gt;

&lt;p&gt;What the PR Comment Looks Like&lt;br&gt;
When BreakShield finds something, you get a comment like this:&lt;/p&gt;

&lt;p&gt;🟠 HIGH — 1 breaking change · 3 files with verified usages&lt;/p&gt;

&lt;p&gt;UserResponse.name&lt;br&gt;
Change  removed field&lt;br&gt;
File&lt;br&gt;&lt;br&gt;
user.ts&lt;br&gt;
Confidence  92% · AST-verified&lt;br&gt;
Before  name: string&lt;br&gt;
💡 Auto-fix available — comment /fix src/types/user.ts to generate a fix PR.&lt;/p&gt;

&lt;p&gt;Zero Config Setup&lt;br&gt;
Install the GitHub App: github.com/apps/breakshield-ci&lt;br&gt;
Open a PR with API changes&lt;br&gt;
BreakShield analyzes automatically&lt;br&gt;
That's it. No YAML. No config files. No CI pipeline changes.&lt;/p&gt;

&lt;p&gt;For AI auto-fix, go to the dashboard and add your API key: → breakshield-ci.vercel.app&lt;/p&gt;

&lt;p&gt;Why Not Just Use TypeScript?&lt;br&gt;
TypeScript catches type errors within a project. It doesn't catch:&lt;/p&gt;

&lt;p&gt;Removing a field that external services depend on&lt;br&gt;
Changing a response type that a mobile app consumes&lt;br&gt;
Deleting an endpoint that 12 microservices call&lt;br&gt;
TypeScript sees your repo. BreakShield sees your API contract.&lt;/p&gt;

&lt;p&gt;Why Not an LLM for Detection?&lt;br&gt;
LLMs hallucinate. They miss things. They have different results on different runs.&lt;/p&gt;

&lt;p&gt;AST analysis is:&lt;/p&gt;

&lt;p&gt;Deterministic — same input, same output&lt;br&gt;
Fast — 500ms-2s per PR, not 30s&lt;br&gt;
Precise — 92-95% confidence, not "probably breaking"&lt;br&gt;
Explainable — exact file, line, usage type&lt;br&gt;
LLMs are great for generating fixes. Terrible for detection where precision matters.&lt;/p&gt;

&lt;p&gt;Try It&lt;br&gt;
→ Install: github.com/apps/breakshield-ci → Dashboard: breakshield-ci.vercel.app&lt;/p&gt;

&lt;p&gt;Open a PR. Remove a field from an interface. Watch it get caught.&lt;/p&gt;

&lt;p&gt;Then type /fix and watch it get fixed.&lt;/p&gt;

</description>
      <category>github</category>
      <category>typescript</category>
      <category>devtools</category>
      <category>api</category>
    </item>
    <item>
      <title>Just published: the 3am production incident that made me build BreakShield CI. If you've ever debugged a breaking change at 3am — this one's for you 🛡️</title>
      <dc:creator>Vojta Holeš</dc:creator>
      <pubDate>Tue, 02 Jun 2026 18:56:34 +0000</pubDate>
      <link>https://dev.to/holesvojta/just-published-the-3am-production-incident-that-made-me-build-breakshield-ci-if-youve-ever-3e75</link>
      <guid>https://dev.to/holesvojta/just-published-the-3am-production-incident-that-made-me-build-breakshield-ci-if-youve-ever-3e75</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/holesvojta/the-3am-production-incident-that-made-me-build-breakshield-ci-3c9k" class="crayons-story__hidden-navigation-link"&gt;The 3am Production Incident That Made Me Build BreakShield CI&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/holesvojta" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F3964959%2F531cf34d-7e89-4bc8-b771-904952b5c25b.png" alt="holesvojta profile" class="crayons-avatar__image" width="96" height="96"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/holesvojta" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Vojta Holeš
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Vojta Holeš
                
              
              &lt;div id="story-author-preview-content-3805237" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/holesvojta" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F3964959%2F531cf34d-7e89-4bc8-b771-904952b5c25b.png" class="crayons-avatar__image" alt="" width="96" height="96"&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Vojta Holeš&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/holesvojta/the-3am-production-incident-that-made-me-build-breakshield-ci-3c9k" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jun 2&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/holesvojta/the-3am-production-incident-that-made-me-build-breakshield-ci-3c9k" id="article-link-3805237"&gt;
          The 3am Production Incident That Made Me Build BreakShield CI
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/typescript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;typescript&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/github"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;github&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/webdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;webdev&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/devops"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;devops&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
            &lt;a href="https://dev.to/holesvojta/the-3am-production-incident-that-made-me-build-breakshield-ci-3c9k#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            2 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
    </item>
    <item>
      <title>The 3am Production Incident That Made Me Build BreakShield CI</title>
      <dc:creator>Vojta Holeš</dc:creator>
      <pubDate>Tue, 02 Jun 2026 18:55:34 +0000</pubDate>
      <link>https://dev.to/holesvojta/the-3am-production-incident-that-made-me-build-breakshield-ci-3c9k</link>
      <guid>https://dev.to/holesvojta/the-3am-production-incident-that-made-me-build-breakshield-ci-3c9k</guid>
      <description>&lt;p&gt;It was 3am when my phone started ringing.&lt;/p&gt;

&lt;p&gt;Our API was down. Half the app was broken. Users were angry. The on-call engineer was panicking.&lt;/p&gt;

&lt;p&gt;After two hours of debugging we found it. Someone had removed the &lt;code&gt;email&lt;/code&gt; field from &lt;code&gt;UserResponse&lt;/code&gt;. Three other services were using it. Nobody caught it in code review. Nobody even knew those services existed.&lt;/p&gt;

&lt;p&gt;We fixed it. Deployed at 5am. Wrote the post-mortem. Added it to the "lessons learned" doc that nobody reads.&lt;/p&gt;

&lt;p&gt;Three months later it happened again.&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem nobody talks about
&lt;/h2&gt;

&lt;p&gt;Every team I've worked with has the same issue.&lt;/p&gt;

&lt;p&gt;You have a TypeScript interface. It's used in 6 places across 4 different files. You remove one field. You open a PR. Your teammates review it. Nobody catches it because nobody knows about those 6 places.&lt;/p&gt;

&lt;p&gt;The tests pass. The build passes. You merge.&lt;/p&gt;

&lt;p&gt;And then production breaks.&lt;/p&gt;

&lt;p&gt;The scary part? This isn't a skill issue. Senior engineers with 10 years of experience make this mistake. It's a tooling problem. Code review wasn't designed to catch this.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I built
&lt;/h2&gt;

&lt;p&gt;I spent a weekend building BreakShield CI — a GitHub App that does one thing:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Catches breaking API changes before you merge.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you open a pull request, it automatically:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Parses your TypeScript interfaces and OpenAPI specs with a full AST&lt;/li&gt;
&lt;li&gt;Finds every place in your codebase that uses the changed API&lt;/li&gt;
&lt;li&gt;Shows you exactly which file and which line will break&lt;/li&gt;
&lt;li&gt;Posts a report directly in your PR&lt;/li&gt;
&lt;li&gt;Blocks merge if the risk is HIGH or CRITICAL&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No config. No CLI. No YAML. Install once, works on every PR forever.&lt;/p&gt;




&lt;h2&gt;
  
  
  What it looks like in practice
&lt;/h2&gt;

&lt;p&gt;You remove &lt;code&gt;email&lt;/code&gt; from &lt;code&gt;UserResponse&lt;/code&gt;. BreakShield CI posts this in your PR:&lt;/p&gt;

&lt;p&gt;🔴 HIGH RISK — 1 breaking change&lt;/p&gt;

&lt;p&gt;UserResponse.email — removed field File: src/types/user.ts Confidence: 94% — AST-verified&lt;/p&gt;

&lt;p&gt;2 consumers affected:&lt;/p&gt;

&lt;p&gt;src/components/UserCard.tsx:23 return ${user.name} &amp;lt;${user.email}&amp;gt;&lt;/p&gt;

&lt;p&gt;src/pages/profile.tsx:41 const { email, name } = user&lt;/p&gt;

&lt;p&gt;Your teammate sees this. They don't need to know the codebase. They don't need to grep for usages. The information is right there.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why AST and not regex
&lt;/h2&gt;

&lt;p&gt;Most tools use regex to find breaking changes. Regex lies.&lt;/p&gt;

&lt;p&gt;If your interface has a field called &lt;code&gt;emailAddress&lt;/code&gt; and you search for &lt;code&gt;email&lt;/code&gt;, regex will find it. AST won't — because AST actually understands your code.&lt;/p&gt;

&lt;p&gt;BreakShield CI uses ts-morph to parse a full TypeScript AST. It knows the difference between a property access, a destructuring, and a type annotation. Every finding is verified at the compiler level.&lt;/p&gt;

&lt;p&gt;If there's no evidence — there's no warning. No noise, no false positives.&lt;/p&gt;




&lt;h2&gt;
  
  
  The 3am call I didn't get
&lt;/h2&gt;

&lt;p&gt;Last week a teammate removed a field from a shared interface. BreakShield CI caught it. The PR comment listed 4 consumer files. We updated them before merging.&lt;/p&gt;

&lt;p&gt;I didn't get a 3am call.&lt;/p&gt;

&lt;p&gt;That's the whole point.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;BreakShield CI is free during beta. It takes 30 seconds to install.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://breakshield-ci.vercel.app" rel="noopener noreferrer"&gt;breakshield-ci.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you've ever had a 3am production incident caused by a breaking change — you know exactly why I built this.&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>github</category>
      <category>webdev</category>
      <category>devops</category>
    </item>
    <item>
      <title>Just launched BreakShield CI — a free GitHub App that catches breaking API changes in PRs using AST analysis. Would love feedback from the TypeScript community!</title>
      <dc:creator>Vojta Holeš</dc:creator>
      <pubDate>Tue, 02 Jun 2026 15:57:39 +0000</pubDate>
      <link>https://dev.to/holesvojta/just-launched-breakshield-ci-a-free-github-app-that-catches-breaking-api-changes-in-prs-using-ast-4k63</link>
      <guid>https://dev.to/holesvojta/just-launched-breakshield-ci-a-free-github-app-that-catches-breaking-api-changes-in-prs-using-ast-4k63</guid>
      <description>&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/holesvojta/i-built-a-github-app-that-catches-breaking-api-changes-before-they-ship-57p4" class="crayons-story__hidden-navigation-link"&gt;I Built a GitHub App That Catches Breaking API Changes Before They Ship&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/holesvojta" class="crayons-avatar  crayons-avatar--l  "&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%2Fuser%2Fprofile_image%2F3964959%2F531cf34d-7e89-4bc8-b771-904952b5c25b.png" alt="holesvojta profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/holesvojta" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Vojta Holeš
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Vojta Holeš
                
              
              &lt;div id="story-author-preview-content-3804387" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/holesvojta" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&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%2Fuser%2Fprofile_image%2F3964959%2F531cf34d-7e89-4bc8-b771-904952b5c25b.png" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Vojta Holeš&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/holesvojta/i-built-a-github-app-that-catches-breaking-api-changes-before-they-ship-57p4" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Jun 2&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/holesvojta/i-built-a-github-app-that-catches-breaking-api-changes-before-they-ship-57p4" id="article-link-3804387"&gt;
          I Built a GitHub App That Catches Breaking API Changes Before They Ship
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag crayons-tag--filled  " href="/t/showdev"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;showdev&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/api"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;api&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/github"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;github&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/typescript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;typescript&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/holesvojta/i-built-a-github-app-that-catches-breaking-api-changes-before-they-ship-57p4" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;2&lt;span class="hidden s:inline"&gt;&amp;nbsp;reactions&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/holesvojta/i-built-a-github-app-that-catches-breaking-api-changes-before-they-ship-57p4#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            2 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;


</description>
      <category>api</category>
      <category>cicd</category>
      <category>showdev</category>
      <category>typescript</category>
    </item>
    <item>
      <title>I Built a GitHub App That Catches Breaking API Changes Before They Ship</title>
      <dc:creator>Vojta Holeš</dc:creator>
      <pubDate>Tue, 02 Jun 2026 15:55:11 +0000</pubDate>
      <link>https://dev.to/holesvojta/i-built-a-github-app-that-catches-breaking-api-changes-before-they-ship-57p4</link>
      <guid>https://dev.to/holesvojta/i-built-a-github-app-that-catches-breaking-api-changes-before-they-ship-57p4</guid>
      <description>&lt;p&gt;Last week I spent 10 hours debugging a production issue. Someone had removed a field from a TypeScript interface. Three other files were using it. Nobody caught it in code review because nobody knew those files existed.&lt;/p&gt;

&lt;p&gt;That's when I decided to build BreakShield CI.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;BreakShield CI is a GitHub App that automatically analyzes every pull request for breaking API changes. It runs in the background — no config, no CLI, no YAML.&lt;/p&gt;

&lt;p&gt;When it finds something, it posts a comment directly in your PR:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which interface or endpoint changed&lt;/li&gt;
&lt;li&gt;What exactly changed (removed field, type change, optional → required)&lt;/li&gt;
&lt;li&gt;Which files and lines in your codebase actually use the changed API&lt;/li&gt;
&lt;li&gt;A risk level: SAFE / LOW / MEDIUM / HIGH / CRITICAL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;HIGH and CRITICAL risk PRs get a failing Check Run that blocks merge.&lt;/p&gt;

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

&lt;p&gt;The interesting part is the analysis engine.&lt;/p&gt;

&lt;p&gt;Most tools use regex to find breaking changes. BreakShield CI uses a full TypeScript AST via &lt;a href="https://ts-morph.com" rel="noopener noreferrer"&gt;ts-morph&lt;/a&gt;. This means it actually understands your code — not just searches for strings.&lt;/p&gt;

&lt;p&gt;For every changed &lt;code&gt;.ts&lt;/code&gt; file in a PR it:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Parses both the before and after version into an in-memory AST&lt;/li&gt;
&lt;li&gt;Extracts all exported interfaces, type aliases, and functions&lt;/li&gt;
&lt;li&gt;Diffs them to find breaking changes&lt;/li&gt;
&lt;li&gt;Searches the codebase for files that use the changed API&lt;/li&gt;
&lt;li&gt;AST-verifies each match — direct access, destructuring, type annotations&lt;/li&gt;
&lt;li&gt;Scores each finding by confidence (0–100)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For OpenAPI specs it uses &lt;code&gt;@apidevtools/swagger-parser&lt;/code&gt; to dereference all &lt;code&gt;$ref&lt;/code&gt; pointers and diffs paths, parameters, request bodies, and response schemas.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it detects
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Breaking (blocks merge on HIGH/CRITICAL):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Removed field from interface&lt;/li&gt;
&lt;li&gt;Changed field type&lt;/li&gt;
&lt;li&gt;Optional → required&lt;/li&gt;
&lt;li&gt;Removed endpoint&lt;/li&gt;
&lt;li&gt;Removed function parameter&lt;/li&gt;
&lt;li&gt;Added required field to request body&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Safe (informational only):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Added optional field&lt;/li&gt;
&lt;li&gt;New endpoint added&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The confidence scoring
&lt;/h2&gt;

&lt;p&gt;Every finding needs evidence. No evidence = no warning.&lt;/p&gt;

&lt;p&gt;Evidence is scored by usage type:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;obj.field&lt;/code&gt; direct access → 90%&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;const { field } = obj&lt;/code&gt; destructuring → 80%&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;: UserResponse&lt;/code&gt; type annotation → 80%&lt;/li&gt;
&lt;li&gt;GitHub Search hit without AST verification → 35%&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Low confidence noise is filtered automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;p&gt;BreakShield CI is free during beta. Install it in 30 seconds:&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://breakshield-ci.vercel.app" rel="noopener noreferrer"&gt;breakshield-ci.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Would love feedback from anyone working with TypeScript APIs or microservices.&lt;br&gt;
`&lt;/p&gt;

&lt;p&gt;`&lt;/p&gt;

</description>
      <category>api</category>
      <category>github</category>
      <category>showdev</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
