Cucumber for JavaScript 8.0.0
  April 06, 2022

Cucumber 8.0.0 has been released and is available now on npm! It's been a while since the last major version, and we've made some big changes since then. If there's one theme for this release it’s the changing JavaScript ecosystem. If there’s a second, it’s making Cucumber easier to work with, especially for power users.

Before we get into it, huge thanks to the core team plus these contributors for making this release possible: Nico Jansen, Ludek Novy, Marju Tubli, Dmytro Shpakovskyi, abelalmeida, deepziem, Joaquín Sorianello, Jan Molak, Tomer Ben-Rachel, Emmanuel Ola, Blaise Pabon, Karla Justen, Manny, Kate Dames, Michael Morris, plocket, Arti Mathanda, and eman2673.


We keep our Node.js support in line with their LTS schedule; as such this release removes support for version 10. On that subject, whilst we already populate the engines field with our supported versions, it’s only advisory metadata and didn’t stop you from running with an unsupported version and erroring ungracefully. Now, if you run cucumber-js with an unsupported Node.js version, it’ll exit straight away and tell you why.

ES Modules

Speaking of Node.js, this release adds support for ES Modules (ESM). In case you haven’t noticed, the JavaScript ecosystem is going through a transition from CommonJS to ESM. Most packages will just switch to writing/outputting ESM and cut a major release (a lot already have). Cucumber has an extra fun angle on this, because consumers don’t just import our code, we also import their code (which in turn imports our code).

Cucumber is now a hybrid package, so you can write your support code in CommonJS or ESM. TLDR on how this works today:

  • If your support code is written in ESM, you’ll need to use the --import option instead of --require so Cucumber uses the right mechanism to load it
  • CommonJS code should also work with --import and we’d encourage you to try switching to that and let us know if you hit any issues
  • The exception is with on-the-fly transpilation of TypeScript etc, which we don’t support with ESM yet (but we’re working on it)

Read the full documentation on ESM support.


This release aims to make configuration easier. Up to now, to avoid passing options and flags on the CLI all the time you could keep them as profiles in a cucumber.js file:

module.exports = {
  default: '--parallel 2 --format html:cucumber-report.html'

The existing syntax of CLI arguments is still supported, but you can now express the configuration values in object form as well:

module.exports = {
  default: {
    parallel: 2,
    format: ['html:cucumber-report.html']

Those examples are CommonJS, but you can also use ESM and JSON - we now auto-detect cucumber.js, cucumber.cjs, cucumber.mjs and cucumber.json files and use the first one we find.

Also, you can now put your file somewhere else and tell Cucumber via the --config CLI option:

$ cucumber-js --config ./config/cucumber.js

Read the full documentation on Configuration.

JavaScript API

Whilst the vast majority of users run Cucumber via the CLI, there are some use cases for running programmatically - for example where Cucumber is one component in a larger testing framework. Up to now, doing this has meant using internal functions that weren’t really designed with consumers in mind. To address this, we’re introducing a new JavaScript API for running Cucumber. Here’s a brief example:

import { loadConfiguration, runCucumber } from '@cucumber/cucumber/api'

export async function runTests() {
  const { runConfiguration } = await loadConfiguration()
  const { success } = await runCucumber(runConfiguration)
  return success

These new functions are designed to be stable and ergonomic, and we’re dogfooding most of them internally too.

Read the full documentation on the new JavaScript API.

Custom work assignment

Cucumber’s parallel option is a widely-used mechanism for shortening the time taken to do a test run by spreading the tests across several worker processes executing in parallel.

This release adds the setParallelCanAssign support code function to allow control of how tests are assigned to workers, which might enable you make your test run more efficient if you can identify e.g. your fast-running vs slow-running tests.

Read the full documentation on parallel.


Whilst all of these technical changes have been going on, we’ve also been improving our documentation. There are now more examples and guidance than before, with extra detail around topics like formatters, filtering and profiles, plus a refreshed README and a more helpful --help command on the CLI.

See all the current documentation.

These are the headlines, but there’s more - check the changelog for a full list, and the upgrading guide to see how to handle breaking changes (don’t worry, there aren’t many).