<?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: Deepak Satyam</title>
    <description>The latest articles on DEV Community by Deepak Satyam (@deepaksatyam).</description>
    <link>https://dev.to/deepaksatyam</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%2F3873472%2F44a11f85-e938-4451-91ab-7b5f3b7c398f.png</url>
      <title>DEV Community: Deepak Satyam</title>
      <link>https://dev.to/deepaksatyam</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/deepaksatyam"/>
    <language>en</language>
    <item>
      <title>Optic is dead. A 2026 migration guide for OpenAPI breaking changes</title>
      <dc:creator>Deepak Satyam</dc:creator>
      <pubDate>Sat, 23 May 2026 18:29:19 +0000</pubDate>
      <link>https://dev.to/deepaksatyam/optic-is-dead-a-2026-migration-guide-for-openapi-breaking-changes-4go2</link>
      <guid>https://dev.to/deepaksatyam/optic-is-dead-a-2026-migration-guide-for-openapi-breaking-changes-4go2</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;This article was originally published on &lt;a href="https://specshield.io/blog/optic-is-dead-migration-guide" rel="noopener noreferrer"&gt;the SpecShield blog&lt;/a&gt;. I'm a co-founder of SpecShield, one of the migration targets discussed below — full disclosure upfront. The post tries to be honest about where SpecShield fits and where other tools fit better.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Optic's GitHub repo was &lt;strong&gt;archived on January 12, 2026&lt;/strong&gt;. Last release: &lt;strong&gt;v1.0.9 in August 2025&lt;/strong&gt;. The &lt;code&gt;useoptic.com&lt;/code&gt; domain no longer resolves.&lt;/li&gt;
&lt;li&gt;Optic was acquired by &lt;strong&gt;Atlassian in April 2024&lt;/strong&gt; but was never folded into Atlassian Compass.&lt;/li&gt;
&lt;li&gt;The MIT-licensed source is still on GitHub, but &lt;strong&gt;abandoned&lt;/strong&gt; — no security patches, no new rules, no support, and your CI will eventually break when a transitive dependency goes EOL.&lt;/li&gt;
&lt;li&gt;If you used Optic primarily for &lt;strong&gt;spec-to-spec diffing and breaking-change checks in CI&lt;/strong&gt;, the most direct migration path is to &lt;strong&gt;&lt;a href="https://specshield.io" rel="noopener noreferrer"&gt;SpecShield&lt;/a&gt;&lt;/strong&gt; (Web UI + CLI + GitHub App + free GitHub Action) or &lt;strong&gt;&lt;a href="https://github.com/oasdiff/oasdiff" rel="noopener noreferrer"&gt;oasdiff&lt;/a&gt;&lt;/strong&gt; (open-source CLI, no UI).&lt;/li&gt;
&lt;li&gt;If you used Optic for &lt;strong&gt;OpenAPI generation from test traffic&lt;/strong&gt; — there is no direct replacement. You'll need to change workflow.&lt;/li&gt;
&lt;li&gt;Below: a feature-by-feature comparison table, a step-by-step migration walkthrough, and an honest list of what's hard to replace.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  What actually happened to Optic
&lt;/h2&gt;

&lt;p&gt;For the last six years, Optic was the open-source default for OpenAPI breaking-change detection. It had what most developer-tool startups don't: a clean CLI, a sensible rule system, MIT licensing, deep CI integration, and a small but devoted community.&lt;/p&gt;

&lt;p&gt;Here's the timeline of how it ended:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Date&lt;/th&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;April 2024&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Atlassian acquires Optic Labs. Optic team joins Atlassian.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;April 2024 – August 2025&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Release cadence slows. Most commits become dependency bumps. Issues pile up unanswered.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;August 10, 2025&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Final release: &lt;strong&gt;v1.0.9&lt;/strong&gt;. No release notes hint that it's the last.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;August 2025 – January 2026&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Silence. No releases, no maintainer responses. The community asks "is Optic still maintained?" — no official answer.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;January 12, 2026&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;The &lt;code&gt;opticdev/optic&lt;/code&gt; GitHub repo is archived (made read-only). The &lt;code&gt;useoptic.com&lt;/code&gt; domain stops resolving shortly after.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;There was no formal sunset announcement, no migration guide from the Optic team, no archived-but-here's-a-fork blessing. It just stopped.&lt;/p&gt;

&lt;p&gt;The expectation in the community after the Atlassian acquisition was that Optic would become part of &lt;a href="https://www.atlassian.com/software/compass" rel="noopener noreferrer"&gt;Atlassian Compass&lt;/a&gt; — Atlassian's developer-experience product. That integration never shipped. As of May 2026, Compass remains focused on service catalogs and DORA metrics, with no API drift detection capability.&lt;/p&gt;

&lt;p&gt;The 1.5k-star repo has 92 forks, but &lt;strong&gt;no fork has emerged as a community successor&lt;/strong&gt;. If you keep depending on &lt;code&gt;@useoptic/optic&lt;/code&gt; from npm, you're depending on unmaintained code that will eventually break when its TypeScript / Node / npm peer dependencies hit EOL.&lt;/p&gt;

&lt;p&gt;You need to migrate. The good news: this is a four-hour job for most teams, not a four-week project.&lt;/p&gt;




&lt;h2&gt;
  
  
  What you actually used Optic for (and what you'll need to replace)
&lt;/h2&gt;

&lt;p&gt;Optic had five distinct capabilities. Different teams used different subsets. Identify which ones applied to you before picking a replacement — choosing wrong is the single biggest migration mistake.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Spec-to-spec diffing and breaking-change detection
&lt;/h3&gt;

&lt;p&gt;The most common use case. You had &lt;code&gt;openapi.yaml&lt;/code&gt; in your repo, you ran &lt;code&gt;optic diff&lt;/code&gt; in CI on every PR, and the action commented on the PR with breaking-change warnings.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Replacement difficulty:&lt;/strong&gt; Easy. Multiple drop-in alternatives exist.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. OpenAPI rule-based linting
&lt;/h3&gt;

&lt;p&gt;Optic had its own ruleset format (&lt;code&gt;.optic.dev.yml&lt;/code&gt;) for things like "all paths must be kebab-case" or "every endpoint needs a description".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Replacement difficulty:&lt;/strong&gt; Medium. You'll switch to &lt;a href="https://github.com/stoplightio/spectral" rel="noopener noreferrer"&gt;Spectral&lt;/a&gt;, which is the de-facto standard for OpenAPI linting and has a much larger ecosystem of rulesets. Your custom rules will need to be re-expressed in Spectral's format.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. OpenAPI generation from captured traffic (&lt;code&gt;optic capture&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;This was Optic's most novel feature. You'd run your test suite with the Optic proxy in front of it, and Optic would generate (or update) the OpenAPI spec from observed traffic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Replacement difficulty:&lt;/strong&gt; Hard. There is no direct open-source replacement with the same maturity. Alternatives include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://netflix.github.io/pollyjs/" rel="noopener noreferrer"&gt;Pollyjs&lt;/a&gt; (record/replay HTTP, generic)&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.speakeasy.com/docs" rel="noopener noreferrer"&gt;Speakeasy&lt;/a&gt; (different workflow — spec drives SDK, not traffic drives spec)&lt;/li&gt;
&lt;li&gt;Hand-maintaining the OpenAPI spec (which is what most teams end up doing)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you relied heavily on &lt;code&gt;optic capture&lt;/code&gt;, your migration is more painful than spec-diff users. Plan accordingly.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. CI integration via GitHub Action
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;useoptic/optic-action&lt;/code&gt; GitHub Action posted PR comments with diff results.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Replacement difficulty:&lt;/strong&gt; Easy. Several drop-in alternatives exist with similar or better PR comment design.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Hosted UI for browsing diffs and history
&lt;/h3&gt;

&lt;p&gt;Optic Cloud (the SaaS layer) gave you a web UI to browse diffs across releases and share them with non-developer stakeholders.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Replacement difficulty:&lt;/strong&gt; Medium. The hosted UI tools available today either cost more (Bump.sh, Stoplight) or look less polished. SpecShield's web UI is a direct equivalent in scope and is in active development.&lt;/p&gt;




&lt;h2&gt;
  
  
  Your migration options at a glance
&lt;/h2&gt;

&lt;p&gt;Honest comparison of the realistic alternatives, as of May 2026:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;What it replaces&lt;/th&gt;
&lt;th&gt;Pricing&lt;/th&gt;
&lt;th&gt;Hosted UI&lt;/th&gt;
&lt;th&gt;OSS engine&lt;/th&gt;
&lt;th&gt;PR comments&lt;/th&gt;
&lt;th&gt;Active development&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;a href="https://specshield.io" rel="noopener noreferrer"&gt;SpecShield&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Optic's spec-diff, breaking-change detection, hosted UI, CI integration, BDCT (bonus)&lt;/td&gt;
&lt;td&gt;Free tier; paid from $29/mo&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;Closed core, free GitHub Action coming&lt;/td&gt;
&lt;td&gt;✅ Yes (GitHub App + Action)&lt;/td&gt;
&lt;td&gt;✅ Active&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;a href="https://github.com/oasdiff/oasdiff" rel="noopener noreferrer"&gt;oasdiff&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Spec-diff and breaking-change detection (CLI only)&lt;/td&gt;
&lt;td&gt;Free / OSS (Apache 2.0)&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;td&gt;✅ Yes (Go)&lt;/td&gt;
&lt;td&gt;✅ Via official GitHub Action&lt;/td&gt;
&lt;td&gt;✅ Active&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;a href="https://github.com/stoplightio/spectral" rel="noopener noreferrer"&gt;Spectral&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Optic's linting (not diffing)&lt;/td&gt;
&lt;td&gt;Free / OSS (Apache 2.0)&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;td&gt;✅ Yes (TS)&lt;/td&gt;
&lt;td&gt;Via custom integration&lt;/td&gt;
&lt;td&gt;Active but slower post-SmartBear acquisition&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;a href="https://bump.sh" rel="noopener noreferrer"&gt;Bump.sh&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Hosted docs + changelog (a different workflow than Optic's CI flow)&lt;/td&gt;
&lt;td&gt;From $50/mo&lt;/td&gt;
&lt;td&gt;✅ Yes&lt;/td&gt;
&lt;td&gt;❌ No&lt;/td&gt;
&lt;td&gt;❌ No native PR comments&lt;/td&gt;
&lt;td&gt;✅ Active&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;&lt;a href="https://redocly.com/docs/cli/" rel="noopener noreferrer"&gt;Redocly CLI&lt;/a&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Linting + diff (basic)&lt;/td&gt;
&lt;td&gt;Free CLI; paid platform&lt;/td&gt;
&lt;td&gt;✅ Yes (paid)&lt;/td&gt;
&lt;td&gt;Partial OSS&lt;/td&gt;
&lt;td&gt;Via custom integration&lt;/td&gt;
&lt;td&gt;✅ Active&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Three patterns will cover ~95% of Optic migrations:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;You used Optic for spec-diff in CI + you want a UI&lt;/strong&gt; → &lt;strong&gt;SpecShield&lt;/strong&gt; (most direct replacement, smallest mental model shift)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You used Optic for spec-diff in CI + you don't need a UI&lt;/strong&gt; → &lt;strong&gt;oasdiff&lt;/strong&gt; (CLI-only, Apache 2.0, will outlive any SaaS company)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You used Optic for linting&lt;/strong&gt; → &lt;strong&gt;Spectral&lt;/strong&gt; (regardless of which diff tool you pick)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The rest of this post focuses on path #1, because it's the most common and the least documented. If you're on path #2 or #3, the official docs for &lt;a href="https://github.com/oasdiff/oasdiff" rel="noopener noreferrer"&gt;oasdiff&lt;/a&gt; and &lt;a href="https://meta.stoplight.io/docs/spectral/" rel="noopener noreferrer"&gt;Spectral&lt;/a&gt; are excellent and you don't need a migration guide.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why SpecShield is the most direct replacement for Optic users
&lt;/h2&gt;

&lt;p&gt;I built SpecShield specifically for the spec-first, CI-driven workflow Optic championed. The mental model is identical:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You commit your OpenAPI spec to git&lt;/li&gt;
&lt;li&gt;On every PR, the new spec is compared to the base branch&lt;/li&gt;
&lt;li&gt;Breaking changes are flagged before merge&lt;/li&gt;
&lt;li&gt;You get a beautiful diff report (in the UI, the CLI, &lt;em&gt;and&lt;/em&gt; as a PR comment)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What's the same as Optic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OpenAPI 3.0 and 3.1 support&lt;/li&gt;
&lt;li&gt;Multi-file spec support (with &lt;code&gt;$ref&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Breaking-change classification (removed paths, type changes, new required fields, etc.)&lt;/li&gt;
&lt;li&gt;CI/CD integration via GitHub App and (soon) free GitHub Action&lt;/li&gt;
&lt;li&gt;CLI distributed via npm (&lt;code&gt;npx specshield compare ...&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What's better than Optic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Bi-Directional Contract Testing (BDCT)&lt;/strong&gt; — verify provider/consumer compatibility, with a &lt;code&gt;can-i-deploy&lt;/code&gt; gate. Optic never had this.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compatibility matrix&lt;/strong&gt; for multi-service architectures&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Beautiful, screenshot-worthy PR comments&lt;/strong&gt; (Optic's were utilitarian)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Active development&lt;/strong&gt; — we ship roughly weekly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free tier&lt;/strong&gt; with no time limit (Optic Cloud's free tier was always limited)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What's different (some teams will see these as downgrades):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SpecShield is a SaaS product with a free tier. Optic was BYO-infrastructure if you stayed on the open-source CLI.&lt;/li&gt;
&lt;li&gt;The core diff engine isn't open-source today (the free GitHub Action will be, when it ships later in 2026).&lt;/li&gt;
&lt;li&gt;We're a smaller team than Optic was at its peak — though we ship faster.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're moving primarily because Optic stopped getting maintained and you want something that &lt;em&gt;will&lt;/em&gt; be maintained, those tradeoffs probably work in your favor. If you fundamentally need OSS-or-nothing, see oasdiff.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step-by-step migration: Optic → SpecShield
&lt;/h2&gt;

&lt;p&gt;Here's the actual migration for a team that was using Optic's CLI and GitHub Action. Expect this to take 30–60 minutes end-to-end, including PR review time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 0 — Audit what you're currently using
&lt;/h3&gt;

&lt;p&gt;Before deleting anything, find every place Optic is referenced in your repo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Find Optic config files&lt;/span&gt;
find &lt;span class="nb"&gt;.&lt;/span&gt; &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;".optic.dev.yml"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"optic.yml"&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;".optic*"&lt;/span&gt;

&lt;span class="c"&gt;# Find Optic CI workflows&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-rE&lt;/span&gt; &lt;span class="s2"&gt;"useoptic/optic-action|optic diff|optic lint"&lt;/span&gt; .github/

&lt;span class="c"&gt;# Find Optic CLI invocations in scripts&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-rE&lt;/span&gt; &lt;span class="s2"&gt;"@useoptic/optic|optic capture|optic verify"&lt;/span&gt; package.json scripts/

&lt;span class="c"&gt;# Find references in docs&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-ri&lt;/span&gt; &lt;span class="s2"&gt;"optic"&lt;/span&gt; README.md docs/ 2&amp;gt;/dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make a checklist of every file you found. You'll touch each one.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1 — Install the SpecShield CLI
&lt;/h3&gt;

&lt;p&gt;The SpecShield CLI is published to npm as &lt;code&gt;specshield&lt;/code&gt;. You don't need to globally install it — &lt;code&gt;npx&lt;/code&gt; is fine for CI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Test it locally — no signup needed for the diff command&lt;/span&gt;
npx specshield compare old-openapi.yaml new-openapi.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You'll see output that includes the same categories Optic produced (breaking, non-breaking, additions), formatted as a clean terminal table.&lt;/p&gt;

&lt;p&gt;If you want JSON output for CI scripting, use the &lt;code&gt;--json&lt;/code&gt; flag (with &lt;code&gt;--output&lt;/code&gt; to also write to a file):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Print JSON to stdout AND save to a file&lt;/span&gt;
npx specshield compare old.yaml new.yaml &lt;span class="nt"&gt;--json&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; diff.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The JSON shape is:&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;"summary"&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;"breaking"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"additions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"modifications"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"warnings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;0&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;"breakingChanges"&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="err"&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;"additions"&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="err"&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;"modifications"&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="err"&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;"warnings"&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="err"&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;h3&gt;
  
  
  Step 2 — Replace your Optic GitHub workflow
&lt;/h3&gt;

&lt;p&gt;If you had something like this &lt;code&gt;.github/workflows/api-check.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="c1"&gt;# OLD — Optic workflow&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;API contract check&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;pull_request&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;check&lt;/span&gt;&lt;span class="pi"&gt;:&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;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="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;useoptic/optic-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;spec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openapi.yaml&lt;/span&gt;
          &lt;span class="na"&gt;base_ref&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ github.event.pull_request.base.ref }}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace it with this:&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;# NEW — SpecShield CLI workflow&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;API contract check&lt;/span&gt;
&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;pull_request&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;check&lt;/span&gt;&lt;span class="pi"&gt;:&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;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="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Extract base spec from base branch&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;git show origin/${{ github.event.pull_request.base.ref }}:openapi.yaml &amp;gt; /tmp/base.yaml&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Compare specs&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;compare&lt;/span&gt;
        &lt;span class="na"&gt;continue-on-error&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
          &lt;span class="s"&gt;{&lt;/span&gt;
            &lt;span class="s"&gt;echo '## 🛡️ SpecShield · API contract check'&lt;/span&gt;
            &lt;span class="s"&gt;echo ''&lt;/span&gt;
            &lt;span class="s"&gt;echo '```&lt;/span&gt;
&lt;span class="pi"&gt;{&lt;/span&gt;&lt;span class="err"&gt;%&lt;/span&gt; &lt;span class="nv"&gt;endraw %&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;
&lt;span class="s1"&gt;'&lt;/span&gt;
            &lt;span class="s"&gt;npx&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;specshield&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;compare&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;/tmp/base.yaml&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;openapi.yaml&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;--fail-on-breaking&lt;/span&gt;
            &lt;span class="s"&gt;echo&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;'&lt;/span&gt;
&lt;span class="pi"&gt;{&lt;/span&gt;&lt;span class="err"&gt;%&lt;/span&gt; &lt;span class="nv"&gt;raw %&lt;/span&gt;&lt;span class="pi"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;```&lt;/span&gt;&lt;span class="s1"&gt;'&lt;/span&gt;
          &lt;span class="s"&gt;}&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;/tmp/comment.md&lt;/span&gt;

      &lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;name:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Comment&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;on&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;PR&lt;/span&gt;
        &lt;span class="s"&gt;if:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;always()&lt;/span&gt;
        &lt;span class="s"&gt;uses:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;marocchino/sticky-pull-request-comment@v2&lt;/span&gt;
        &lt;span class="s"&gt;with:&lt;/span&gt;
          &lt;span class="s"&gt;path:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;/tmp/comment.md&lt;/span&gt;

      &lt;span class="s"&gt;-&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;name:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Fail&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;the&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;build&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;if&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;breaking&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;changes&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;were&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;found&lt;/span&gt;
        &lt;span class="s"&gt;if:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;steps.compare.outcome&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;==&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;'failure'&lt;/span&gt;
        &lt;span class="s"&gt;run&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;exit &lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A few notes on this pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The CLI auto-disables ANSI color codes when not running in a TTY, so the output inside the fenced code block renders cleanly on GitHub.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;continue-on-error: true&lt;/code&gt; on the compare step lets the PR comment post even when breaking changes are detected. The final step then fails the build explicitly so PR checks still gate the merge.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;marocchino/sticky-pull-request-comment&lt;/code&gt; updates the existing comment in place on subsequent commits rather than spamming the PR.&lt;/li&gt;
&lt;li&gt;A dedicated SpecShield Action (in development) will render a richer markdown comment with a color-coded summary table and collapsible per-endpoint diffs. Until that ships, the fenced-code-block approach above is the cleanest path.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3 — Migrate your custom rules (if you had any)
&lt;/h3&gt;

&lt;p&gt;This is the step that takes the longest if you'd customized Optic's rule engine. Optic rules looked like this:&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;# OLD — .optic.dev.yml&lt;/span&gt;
&lt;span class="na"&gt;ruleset&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;breaking-changes&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;examples&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kebab-case-paths&lt;/span&gt;
    &lt;span class="na"&gt;where&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;operation&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;in&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;any&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
    &lt;span class="na"&gt;rule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;after&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;must&lt;/span&gt;
      &lt;span class="na"&gt;assert&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;|&lt;/span&gt;
        &lt;span class="s"&gt;operation.path.split('/').every(s =&amp;gt; /^[a-z0-9-]*$/.test(s))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SpecShield doesn't currently expose a Spectral-compatible custom rule API. For now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Breaking-change rules&lt;/strong&gt;: covered by SpecShield's built-in detector — no migration needed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Style/lint rules&lt;/strong&gt; (kebab-case paths, required descriptions, etc.): migrate these to a separate Spectral step in your CI:
&lt;/li&gt;
&lt;/ul&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;OpenAPI lint&lt;/span&gt;
  &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npx @stoplight/spectral-cli lint openapi.yaml --ruleset .spectral.yaml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With a &lt;code&gt;.spectral.yaml&lt;/code&gt; like:&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;extends&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;spectral:oas&lt;/span&gt;
&lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;paths-kebab-case&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Paths should be kebab-case&lt;/span&gt;
    &lt;span class="na"&gt;given&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;$.paths.*~&lt;/span&gt;
    &lt;span class="na"&gt;severity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;warn&lt;/span&gt;
    &lt;span class="na"&gt;then&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;function&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pattern&lt;/span&gt;
      &lt;span class="na"&gt;functionOptions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^(\/[a-z0-9-]*)+$&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We're working on first-class custom-rule support in SpecShield. Until then, the two-step approach above is the cleanest path.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4 — Remove Optic dependencies
&lt;/h3&gt;

&lt;p&gt;Once your new workflow is green:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Remove npm dep&lt;/span&gt;
npm uninstall @useoptic/optic

&lt;span class="c"&gt;# Remove config&lt;/span&gt;
&lt;span class="nb"&gt;rm&lt;/span&gt; .optic.dev.yml

&lt;span class="c"&gt;# Remove the old workflow (or just edit it)&lt;/span&gt;
&lt;span class="nb"&gt;rm&lt;/span&gt; .github/workflows/optic-check.yml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Commit the migration as a single PR — easier to review, easier to revert if anything's off.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5 — Set up the dashboard (optional but recommended)
&lt;/h3&gt;

&lt;p&gt;If you want history, team collaboration, BDCT, and a &lt;code&gt;can-i-deploy&lt;/code&gt; gate beyond the per-PR diff:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Sign up free at &lt;a href="https://specshield.io" rel="noopener noreferrer"&gt;specshield.io&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Install the SpecShield GitHub App on your repo&lt;/li&gt;
&lt;li&gt;Your existing CLI runs will automatically appear in your dashboard's compare history&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No re-configuration needed — the GitHub App and CLI write to the same backend.&lt;/p&gt;




&lt;h2&gt;
  
  
  What SpecShield does NOT replace from Optic (being honest)
&lt;/h2&gt;

&lt;p&gt;Three Optic capabilities don't have a clean SpecShield replacement today. If you depended on these, you need a plan.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;code&gt;optic capture&lt;/code&gt; — generating specs from traffic
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;No direct replacement in SpecShield.&lt;/strong&gt; Our model assumes you maintain the spec by hand (or generate it from code via a framework annotation library). If &lt;code&gt;optic capture&lt;/code&gt; was central to your workflow, evaluate:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Continuing to use Optic's archived &lt;code&gt;capture&lt;/code&gt; command standalone (it'll keep working for a while — it's not network-dependent)&lt;/li&gt;
&lt;li&gt;Replacing with &lt;a href="https://netflix.github.io/pollyjs/" rel="noopener noreferrer"&gt;Pollyjs&lt;/a&gt; for record/replay&lt;/li&gt;
&lt;li&gt;Switching to a spec-first workflow (which is where the industry has moved, for what it's worth)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;optic capture&lt;/code&gt;-style functionality is on our roadmap but isn't shipping in 2026.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The MIT-licensed core
&lt;/h3&gt;

&lt;p&gt;Optic's diff engine was MIT. SpecShield's core engine is closed-source as of May 2026. The free GitHub Action will be Apache 2.0 when it ships, but the engine behind the hosted product is proprietary.&lt;/p&gt;

&lt;p&gt;If "must be fully open-source" is a non-negotiable requirement, &lt;strong&gt;use oasdiff&lt;/strong&gt; — it's the most mature open-source option and is unaffected by Optic's shutdown.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The exact ruleset format
&lt;/h3&gt;

&lt;p&gt;Optic's rule DSL is unique. Your rules don't port 1:1 to anything. You'll re-author them in either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SpecShield's built-in rules (which cover ~80% of the common cases by default)&lt;/li&gt;
&lt;li&gt;Spectral's rule DSL (for the remaining 20% of custom style rules)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Plan ~1 hour per custom rule for the rewrite.&lt;/p&gt;




&lt;h2&gt;
  
  
  When SpecShield is NOT the right migration target
&lt;/h2&gt;

&lt;p&gt;Honest recommendations for the cases where another tool is better:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Your situation&lt;/th&gt;
&lt;th&gt;Recommended migration target&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;"I just want a CLI that does breaking-change detection, no SaaS"&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;oasdiff&lt;/strong&gt;. It will outlive every SaaS in this list.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"We had thousands of dollars of Optic Cloud customization and need a high-touch enterprise vendor"&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Bump.sh&lt;/strong&gt; or &lt;strong&gt;Stoplight&lt;/strong&gt; for documentation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"We need OpenAPI capture from traffic"&lt;/td&gt;
&lt;td&gt;Stay on Optic's archived CLI for now; &lt;strong&gt;Speakeasy&lt;/strong&gt; if you can shift to spec-first&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"We need OpenAPI linting and nothing else"&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;Spectral&lt;/strong&gt; (standalone, free)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"We want a fully self-hosted option with no cloud component"&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;oasdiff&lt;/strong&gt; + &lt;strong&gt;Spectral&lt;/strong&gt;, both run on your own infra&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;"We're a microservice org with consumer/provider contracts"&lt;/td&gt;
&lt;td&gt;
&lt;strong&gt;SpecShield&lt;/strong&gt; (has BDCT built in) or &lt;strong&gt;PactFlow&lt;/strong&gt; (the dedicated Pact-broker SaaS)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The honest read on the post-Optic landscape: there's no single tool that covers everything Optic did. Most teams will end up with &lt;strong&gt;two tools&lt;/strong&gt; in their pipeline — one for diff/breaking-change detection, one for linting — where they had one before.&lt;/p&gt;




&lt;h2&gt;
  
  
  What we learned from Optic's end
&lt;/h2&gt;

&lt;p&gt;A few takeaways worth sitting with, especially if you build or pay for developer tools:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;OSS + VC is a fragile combination.&lt;/strong&gt; Optic raised funding, was acquired, and shut down within a typical VC fund lifecycle. The OSS code still exists but nobody is paid to maintain it. If a tool is mission-critical to your CI, weight its funding model and sustainability &lt;em&gt;along with&lt;/em&gt; its features.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Acquisition isn't continuity.&lt;/strong&gt; "Acquired by [BigCo]" sounds reassuring at the time. It almost never is. Plan for the acquired tool to be gone within 18 months unless its product roadmap is publicly aligned with the acquirer's stated direction.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Spec-first won.&lt;/strong&gt; Optic's bet was that you should auto-generate specs from traffic. The industry consensus has moved the other way — the spec is the source of truth, code and tests are generated from it. That shift is part of why the spec-from-capture approach didn't become indispensable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Beauty matters.&lt;/strong&gt; Optic's PR comments were functional but plain. The tools that have taken its place (and the ones that will replace whatever replaces them) compete heavily on UI/UX. Engineers screenshot and share comments that look good. That's distribution.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Migrate today, not next quarter
&lt;/h2&gt;

&lt;p&gt;Three reasons to do this migration &lt;em&gt;now&lt;/em&gt;, not after your next release:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Optic's npm package will eventually break.&lt;/strong&gt; &lt;code&gt;@useoptic/optic&lt;/code&gt; depends on TypeScript, Node, and dozens of transitive packages, several of which will hit EOL within 12 months. When that happens, your CI will silently start failing in ways that are hard to debug because the underlying tool is unmaintained.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Your team is forgetting Optic's quirks.&lt;/strong&gt; The longer you wait, the harder the migration. The engineer who set up your Optic workflow may not be at the company in 12 months.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;The migration is small if you do it now.&lt;/strong&gt; Most teams can complete the steps above in under an hour. Wait until a CI break forces it, and you'll be doing it in a panic on a Friday afternoon.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Try SpecShield in 5 minutes
&lt;/h2&gt;

&lt;p&gt;If you've read this far and want to try SpecShield as your Optic replacement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# No signup needed for the CLI diff command&lt;/span&gt;
npx specshield compare old-openapi.yaml new-openapi.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the dashboard, history, GitHub App, and BDCT: sign up free at &lt;a href="https://specshield.io/signup" rel="noopener noreferrer"&gt;specshield.io/signup&lt;/a&gt; — no credit card, generous free tier. Pricing details at &lt;a href="https://specshield.io/pricing" rel="noopener noreferrer"&gt;specshield.io/pricing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For migration support, email me at &lt;a href="mailto:founder@specshield.io"&gt;founder@specshield.io&lt;/a&gt; — happy to help any Optic refugee migrate, gratis, regardless of whether you end up using SpecShield. The migration matters more than the tool.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Was this guide helpful? It's part of a series on the post-Optic API tooling landscape. Next post: a deep technical comparison of the breaking-change rules across SpecShield, oasdiff, and Optic's archived ruleset — including the edge cases each catches that the others miss.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Have feedback or corrections? Drop a comment below or email me directly. I'd rather get this right than get this fast.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>openapi</category>
      <category>api</category>
      <category>devops</category>
      <category>testing</category>
    </item>
    <item>
      <title>How to Detect API Breaking Changes in OpenAPI (Step-by-Step Guide)</title>
      <dc:creator>Deepak Satyam</dc:creator>
      <pubDate>Sat, 11 Apr 2026 12:14:50 +0000</pubDate>
      <link>https://dev.to/deepaksatyam/how-to-detect-api-breaking-changes-in-openapi-step-by-step-guide-28i</link>
      <guid>https://dev.to/deepaksatyam/how-to-detect-api-breaking-changes-in-openapi-step-by-step-guide-28i</guid>
      <description>&lt;p&gt;APIs are the backbone of modern applications. But one small change in your API can silently break production systems.&lt;/p&gt;

&lt;p&gt;If you’re working with microservices or public APIs, detecting breaking changes is &lt;strong&gt;not optional — it’s critical&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this guide, you’ll learn:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What API breaking changes are&lt;/li&gt;
&lt;li&gt;Why they are dangerous&lt;/li&gt;
&lt;li&gt;How to detect them in OpenAPI/Swagger&lt;/li&gt;
&lt;li&gt;How to automate detection in CI/CD&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔍 What is an API Breaking Change?
&lt;/h2&gt;

&lt;p&gt;An API breaking change is any modification that causes existing clients to fail.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Examples:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Removing a field from response&lt;/li&gt;
&lt;li&gt;Changing data type (e.g., &lt;code&gt;string&lt;/code&gt; → &lt;code&gt;integer&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Renaming endpoints&lt;/li&gt;
&lt;li&gt;Making optional fields required&lt;/li&gt;
&lt;li&gt;Removing query parameters&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Even a small change can break mobile apps, frontend apps, or partner integrations.&lt;/p&gt;




&lt;h2&gt;
  
  
  💥 Why Breaking Changes Are Dangerous
&lt;/h2&gt;

&lt;p&gt;Most API failures in production happen because of &lt;strong&gt;undetected contract changes&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Real-world impact:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🚫 Frontend crashes&lt;/li&gt;
&lt;li&gt;📉 Partner integrations fail&lt;/li&gt;
&lt;li&gt;🔥 Production incidents&lt;/li&gt;
&lt;li&gt;😡 Bad user experience&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧩 Traditional Approach (Problem)
&lt;/h2&gt;

&lt;p&gt;Most teams rely on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Manual reviews ❌&lt;/li&gt;
&lt;li&gt;Post-deployment testing ❌&lt;/li&gt;
&lt;li&gt;Consumer-driven contract tools (complex setup) ⚠️&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 These approaches are either &lt;strong&gt;slow or unreliable&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🚀 Better Approach: OpenAPI Diff
&lt;/h2&gt;

&lt;p&gt;If you are already using OpenAPI/Swagger:&lt;/p&gt;

&lt;p&gt;👉 You can compare two API specs&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Old version (base)&lt;/li&gt;
&lt;li&gt;New version (target)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 Detect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Breaking changes&lt;/li&gt;
&lt;li&gt;Non-breaking changes&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🛠️ How to Detect API Breaking Changes (Step-by-Step)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Get Your OpenAPI Specs
&lt;/h3&gt;

&lt;p&gt;Example:&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;# base.yaml&lt;/span&gt;
&lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;/user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;responses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;200&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;OK&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 2: Modify API (Simulate Change)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# target.yaml&lt;/span&gt;
&lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;/user&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;responses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;200&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;OK&lt;/span&gt;
          &lt;span class="c1"&gt;# field removed or changed&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 3: Compare Specs
&lt;/h3&gt;

&lt;p&gt;Use a CLI tool like SpecShield:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;specshield compare base.yaml target.yaml &lt;span class="nt"&gt;--fail-on-breaking&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Step 4: Detect Issues
&lt;/h3&gt;

&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;❌ Breaking Change Detected:
- Response schema changed for /user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  ⚡ Automate in CI/CD
&lt;/h2&gt;

&lt;p&gt;You can integrate this into your pipeline:&lt;/p&gt;

&lt;h3&gt;
  
  
  Example: GitHub Actions
&lt;/h3&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Detect API Breaking Changes&lt;/span&gt;
  &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;specshield compare base.yaml target.yaml --fail-on-breaking&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;👉 If breaking change detected → build fails&lt;/p&gt;




&lt;h2&gt;
  
  
  🔥 Why Use SpecShield?
&lt;/h2&gt;

&lt;p&gt;SpecShield is a CLI tool designed specifically for OpenAPI-based API validation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Benefits:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;🚀 Simple CLI (no complex setup)&lt;/li&gt;
&lt;li&gt;🔍 Detect breaking changes instantly&lt;/li&gt;
&lt;li&gt;⚡ CI/CD friendly&lt;/li&gt;
&lt;li&gt;🧩 Works with OpenAPI/Swagger&lt;/li&gt;
&lt;li&gt;🔄 Lightweight alternative to Pact&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ⚔️ SpecShield vs Pact
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;SpecShield&lt;/th&gt;
&lt;th&gt;Pact&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Setup&lt;/td&gt;
&lt;td&gt;Simple CLI&lt;/td&gt;
&lt;td&gt;Complex&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Focus&lt;/td&gt;
&lt;td&gt;OpenAPI diff&lt;/td&gt;
&lt;td&gt;Consumer contracts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speed&lt;/td&gt;
&lt;td&gt;Fast&lt;/td&gt;
&lt;td&gt;Moderate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Use case&lt;/td&gt;
&lt;td&gt;API schema validation&lt;/td&gt;
&lt;td&gt;Consumer testing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;👉 If you use OpenAPI → SpecShield is faster and simpler&lt;/p&gt;




&lt;h2&gt;
  
  
  🎯 Best Practices
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Always version your API&lt;/li&gt;
&lt;li&gt;Never deploy without diff check&lt;/li&gt;
&lt;li&gt;Automate in CI/CD&lt;/li&gt;
&lt;li&gt;Monitor breaking changes&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🧠 Final Thoughts
&lt;/h2&gt;

&lt;p&gt;API breaking changes are one of the most common causes of production issues.&lt;/p&gt;

&lt;p&gt;👉 The solution is simple:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use OpenAPI&lt;/li&gt;
&lt;li&gt;Compare versions&lt;/li&gt;
&lt;li&gt;Automate detection&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🚀 Get Started
&lt;/h2&gt;

&lt;p&gt;Install SpecShield:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; specshield
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run your first check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;specshield compare base.yaml target.yaml &lt;span class="nt"&gt;--fail-on-breaking&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🔗 Learn More
&lt;/h2&gt;

&lt;p&gt;Visit: &lt;a href="https://specshield.io" rel="noopener noreferrer"&gt;https://specshield.io&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  💬 Conclusion
&lt;/h2&gt;

&lt;p&gt;If you're serious about API reliability, detecting breaking changes should be part of your workflow.&lt;/p&gt;

&lt;p&gt;👉 Start small&lt;br&gt;
👉 Automate early&lt;br&gt;
👉 Prevent production failures&lt;/p&gt;




&lt;p&gt;Happy coding 🚀&lt;/p&gt;

</description>
      <category>openapi</category>
      <category>api</category>
      <category>npm</category>
      <category>specshield</category>
    </item>
  </channel>
</rss>
