Upgrading your test suite to a new major version can feel daunting, but it doesn’t have to be. Cypress 15 continues the work started in 14 by moving support toward modern frameworks and current versions of Node.js, while phasing out older dependencies. Alongside these changes, the release ships with an updated Electron/Chromium engine that improves stability and speed across test runs.
Cypress 15 also ships an updated test authoring experience, with Cypress Studio. It now supports inline editing, and the platform has been prepared for cy.prompt()
, a natural language command for generating tests that will arrive later in the 15.x cycle. Together, these updates make Cypress 15 both a modernization of the test runner and a foundation for what comes next.
From Cypress 13 to 14
Moving from Cypress 13 to 14 is a lot like upgrading your operating system. The core experience is still familiar, but the environment around it has been modernized. This release focused on modernizing support and tightening up cross-origin testing, so a few things will work differently than in 13. Let’s walk through what’s changed, why it matters, and how to adjust your test suite.
Environmental Requirements
Cypress 14 updated the baseline for supported environments. This means you will want to make sure that your CI environments and dev machines are operating on:
- Node.js 18 or higher - for macOS users this means Big Sur (11) or newer
- Glibc 2.28+ for Linux users - like Ubuntu 20.04 (or newer) or Debian 10+
Cross-Origin Behavior
Cypress 14 changed how tests handle multiple domains. In 13, you could jump between subdomains in a single test and Cypress would quietly set document.domain
in the background to keep things working. Chrome has deprecated the setter for this property, so Cypress has been updated to reflect this change.
Now, any time a test touches a second domain (even subdomains), you need cy.origin()
.
cy.visit('https://app.example.com')
// Second domain must be wrapped
cy.origin('https://auth.example.com', () => {
cy.get('h1').should('contain', 'Login')
})
Without cy.origin()
, commands after the second cy.visit()
will fail. There is a temporary config flag called injectDocumentDomain
if you need time to migrate all of your visit commands. However, Chrome could completely remove the setter in future versions, so it’s better to update your tests now.
Frameworks & Bundlers
Component testing also shifted in 14:
- Webpack 5 became the default. Webpack 4 is still possible with extra setup, but consider this your sign to move forward.
- Framework support focused on current versions (React 18+, Angular 17.2+, Vue 3, Svelte 5). If you’re on an older version, legacy harness packages (like
@cypress/vue2
or@cypress/angular@2
) are available but marked as temporary.
From Cypress 14 to 15
If moving from 13 to 14 was like installing a new operating system, then going from 14 to 15 is like installing the next service pack. The foundation is already in place, and most of the big changes have been handled. What’s left are smaller adjustments like updating your runtime, cleaning up a few commands, and aligning with the latest tool support, so your setup stays current.
Environment Requirements
The move to Cypress 15 continues the environment upgrade path established in 14.
- Node.js 20, 22, or 24 - for macOS users this means Big Sur (11) or newer
- Glibc 2.31+ for Linux users - like Ubuntu 20.04 (or newer) or Debian 11+
Command Updates
A couple of deprecations from 14 were fully removed in 15:
cy.stub()
— To align with the latest Sinon JS patterns, the three-argument form is no longer supported. For example:
// ❌ Invalid in Cypress 15
cy.stub(Math, 'random', () => 0.42)
// ✅ Valid in Cypress 15
cy.stub(Math, 'random').callsFake(() => 0.42)
// You can also use other Sinon helpers
cy.stub(Math, 'random').returns(0.42)
cy.stub(window, 'fetch').resolves(new Response('{}'))
cy.exec()
- The propertycode
was renamed toexitCode
. For example:
// ❌ Invalid in Cypress 15
cy.exec('npm run build').its('code').should('eq', 0)
// ✅ Valid in Cypress 15
cy.exec('npm run build').its('exitCode').should('eq', 0)
APIs and Bundlers
- API rename —
Cypress.SelectorPlayground
is nowCypress.ElementSelector
. Update any references in your plugins or custom code. - Webpack 4 removal — Webpack 4 is no longer supported at all. If you haven’t migrated, you’ll need to move to Webpack 5 or Vite.
Wrapping Up
Major version upgrades can feel like a lot, but Cypress 15 is really about setting you up for long-term stability. Think of this upgrade path in two parts: Cypress 14 introduced the foundational changes, and Cypress 15 builds on top of them by finalizing deprecations and raising the baseline once more. Together, they put your project on a solid footing.
The end result is a test suite that runs faster, fits cleanly into modern dev environments, and won’t trip over outdated dependencies as you move forward.
Here’s a quick view of what to double-check:
- Node.js
- 13 → 14: move to Node 18+
- 14 → 15: move again to Node 20, 22, or 24
- Cross-origin tests
- Use
cy.origin()
whenever your test touches a second domain
- Use
- Commands
- Drop the three-argument form of
cy.stub()
- Update
cy.exec()
assertions to use exitCode instead of code
- Drop the three-argument form of
- Frameworks and bundlers
- Move forward to current framework versions (React 18+, Angular 17.2+/18, Vue 3, Svelte 5)
- Webpack 5 or Vite only — Webpack 4 is no longer supported
With these upgrades, you increase test reliability, modernize your toolchain, and free your team up from the friction of running outdated dependencies. For full documentation on migration steps and examples, check out our migration guide. Once you land on Cypress 15, you are ready for what comes next.