DEV Community

Cover image for Catching Breaking API Changes Before Production (with a Chrome Extension)
Vaishali
Vaishali

Posted on • Edited on

Catching Breaking API Changes Before Production (with a Chrome Extension)

Update: The extension from this article is now live on the Chrome Web Store 🎉

Install it here: https://chromewebstore.google.com/detail/api-inspector/doafolenpklfnnbgaaiapdgmgedcndnd


Have you ever deployed code only to find out the backend changed an array to a string?

Your .map() breaks. Users complain.
You spend the next hour debugging something that was working yesterday.
This happened to me one too many times.

So I built API Inspector — a Chrome DevTools extension that tracks API schema changes while you’re developing, not after production breaks.


🎯 The Problem

Picture this scenario.

Week 1: Everything works

// API response
{
  "projectStatus": ["active", "pending"]
}

// Frontend usage
projectStatus.map(status => ...)
Enter fullscreen mode Exit fullscreen mode

This is reasonable.
The API contract says projectStatus is an array.

Week 2: Silent backend change

The backend gets refactored. Now the API returns:

{
  "projectStatus": "active"
}
Enter fullscreen mode Exit fullscreen mode

You deploy. Everything breaks.💥


“But why didn’t you add an array check?”

Yes — you could write:

Array.isArray(projectStatus) && projectStatus.map(...)
Enter fullscreen mode Exit fullscreen mode

But that only hides the real problem.
The actual bug isn’t:

.map() crashed”

The real bug is:

“The API contract changed and nobody noticed.”

Defensive checks treat the symptom.
They don’t surface breaking changes.
And that’s exactly what I wanted to catch.


💡 The Idea

I wanted something that would:

  • Monitor API responses automatically
  • Detect schema changes
  • Show differences clearly (like a git diff)
  • Work locally, without any third-party service

That’s how API Inspector was born.


🔍 What API Inspector Does

Once enabled in DevTools, it:

  • Captures API requests (customizable by the user)
  • Stores previous response schemas and compares them against new responses
  • Highlights changes:
    • type changes (array → string)
    • added / removed fields
  • Shows a diff view, similar to Git

Screenshot of API Inspector extension showing schema diff

Customization options

  • Default filter: APIs containing "api/"
  • Can be changed to:

    • any keyword
    • all JSON-based APIs
  • No backend. No external storage.

  • Everything runs locally in the browser.

Screenshot of API Inspector extension popup


🧩 Chrome Extension Architecture (At a High Level)

Before building this, I thought Chrome extensions were simple and made of just a few parts:

  • Popup → UI only. Exists only while open. Used for controls and settings.

  • Background Script / Service Worker → Runs separately from the page. Handles storage, listeners, and long-running logic.

  • Content Scripts → Run inside the web page. Can read the DOM, intercept requests, but have limited access.

  • DevTools Panel → A completely separate execution context tied to Chrome DevTools — not the page, not the background.

In practice, this is where things got tricky.

What I initially missed was that:

  • each part runs in isolation
  • each has its own execution context
  • each has its own console
  • they cannot see each other’s logs

This separation is powerful — but also extremely confusing if you don’t know it exists.


😵 The Most Confusing Part: DevTools Debugging

The hardest part wasn't building the UI.
It was debugging DevTools APIs and understanding where my code was actually running.

At one point:

  • I had three DevTools windows open for the same page
  • my extension was running
  • my code was executing
  • but my console logs were nowhere to be found

I kept logging everything… and nothing showed up.

It felt broken.
Or worse — undocumented.


💡 The Moment of Clarity

The breakthrough came when I understood this:

DevTools extensions have their own execution context.

That means:

  • background logs → background context
  • content script logs → page context
  • DevTools panel logs → only the custom DevTools panel

And those logs appear only after the exact action that triggers them is performed.

Once I:

  1. Opened DevTools
  2. Opened my custom DevTools panel
  3. Triggered the exact event that fired the listener …the logs finally appeared.

Not obvious.
But once this mental model clicked, everything made sense.


🧠 What I Actually Learned

This project taught me more than just “how to build a Chrome extension”.

I learned that:

  • API contracts are assumptions, not guarantees
  • DevTools APIs require mental model alignment, not trial-and-error
  • Chrome extensions are less about files — and more about execution boundaries
  • Debugging gets easier once your mental model matches reality

Most importantly:

Catching problems early beats handling them gracefully later.


🌱 Final Thought

API Inspector doesn’t replace tests.
It doesn’t replace type systems.

But it gives you early visibility
the moment something changes, not after users complain.

And honestly, building it taught me more about:

  • debugging
  • architecture
  • and developer experience

than many “perfect” tutorial projects ever did.

Top comments (7)

Collapse
 
verify_backlinks profile image
Ross – Verify Backlinks

Love this. I’ve run into a similar issue with “external truth sources” like live URLs: status codes, canonicals, robots rules can change silently and break downstream decisions. Do you think there’s room for a “contract test” pattern for non-API dependencies (web pages) e.g., continuously asserting invariants like indexability, canonical stability, and response class?

Collapse
 
dev-in-progress profile image
Vaishali

Really like this POV — framing things like canonicals, robots rules, and status codes as “external truth sources” puts the problem in a new light for me.

As a frontend dev, I haven’t personally run into this kind of breakage as often, so I never thought about it in contract-test terms — but it makes a lot of sense when you describe it this way. Invariants silently changing can absolutely break downstream decisions.

It does feel implementable in principle, but for now this extension is intentionally scoped to API schema changes during development. Still, I like the idea of applying the same early-signal / diff-based mindset beyond APIs — definitely an interesting direction to think about.

Collapse
 
verify_backlinks profile image
Ross – Verify Backlinks

That makes sense scoping it to API schemas keeps it focused.
What I like about your approach is that it surfaces change at the assumption layer, not the failure layer.
That’s a powerful pattern in any system where invariants silently drift.

Thread Thread
 
dev-in-progress profile image
Vaishali

That’s a great way to put it — “assumption layer vs failure layer” really captures what I was trying to solve.
Glad the approach resonated. Appreciate the thoughtful feedback! 🙌

Collapse
 
dev-in-progress profile image
Vaishali

Update: The Chrome extension from this article is now live on the Chrome Web Store 🎉

Install it here: chromewebstore.google.com/detail/a...

Some comments may only be visible to logged-in visitors. Sign in to view all comments.