Does Express Work With Cypress?

Fully CompatibleLast verified: 2026-02-26

Express and Cypress work together seamlessly—use Express as your test server and Cypress as your end-to-end testing framework.

Quick Facts

Compatibility
full
Setup Difficulty
Easy
Official Integration
No — community maintained
Confidence
high
Minimum Versions
Express: 4.0.0
Cypress: 3.0.0

How Express Works With Cypress

Express and Cypress are a natural pairing for full-stack JavaScript testing. You'll typically run an Express server (often with a test database) in your test environment, then point Cypress at `localhost:PORT` to test your application's UI and API interactions. Cypress handles all the E2E testing while Express serves your application. The developer experience is smooth: you start your Express server in one terminal, run Cypress in another, and get instant feedback with Cypress's time-travel debugger showing you exactly what happened at each step. Many teams use this combo with a dedicated test database seeded before each test run. The architecture is straightforward—no special integration code needed. Express doesn't need to know about Cypress; Cypress just makes HTTP requests to your running Express server like any other client would. You can also use Cypress's `cy.task()` feature to communicate directly with your test server for database resets or advanced setup, though this requires a custom plugin.

Best Use Cases

→Testing a full CRUD application with a real Express backend and database
→Validating API responses and UI rendering together in integration tests
→Testing authentication flows with real sessions and cookies
→Automated regression testing for microservices built with Express

Quick Setup

bash
npm install express cypress --save-dev
javascript
// server.js - Your Express app
const express = require('express');
const app = express();

app.use(express.json());
app.get('/', (req, res) => res.json({ message: 'Hello' }));

let server;
if (require.main === module) {
  server = app.listen(3000, () => console.log('Listening on 3000'));
}
module.exports = app;

// cypress/e2e/app.cy.js
describe('Express App', () => {
  before(() => {
    cy.visit('http://localhost:3000');
  });

  it('loads the homepage', () => {
    cy.contains('Hello').should('exist');
  });
});

// package.json scripts
"scripts": {
  "start": "node server.js",
  "test:e2e": "cypress open"
}

// Run: npm start (in one terminal), then npm run test:e2e

Known Issues & Gotchas

warning

Port conflicts if your dev server and test server both run on the same port

Fix: Use different ports for development and testing, or run Express on a random available port during tests using `server.listen(0, ...)`

critical

Database state leaking between tests if not properly reset

Fix: Use Cypress hooks (beforeEach/afterEach) with `cy.task()` to reset your test database, or use database transactions that rollback after each test

warning

Timing issues where Cypress tries to hit the server before it's fully started

Fix: Use `cy.visit()` with retries enabled, or implement a health check endpoint that Cypress polls before running tests

info

CORS errors when Cypress runs on a different origin than your Express server

Fix: Configure Express with `cors` middleware to allow requests from `localhost:3000` (or your Cypress port) during testing

Alternatives

  • •Next.js with Cypress—uses Express under the hood with built-in dev server, cleaner for fullstack apps
  • •Django/Flask with Selenium—Python-based alternative if you prefer backend in Python
  • •NestJS with Cypress—more structured Express alternative with better TypeScript support

Resources

Related Compatibility Guides

Explore more compatibility guides