---
title: 'Jest 27: New Defaults for Jest, 2021 edition ⏩'
authors: jeysal
---

In the [Jest 26 blog post](/blog/2020/05/05/jest-26) about a year ago, we announced that after two major releases with few breaking changes, Jest 27 will flip some switches to set better defaults for projects that are new or can migrate smoothly. This gives us the opportunity to remove some packages from the default distribution of Jest 28 and publish them as separately installable and pluggable modules instead. Everyone on the new defaults can benefit from a smaller install size, while people needing these packages can still install them separately.

With the first major change of defaults since the [New Defaults for Jest](/blog/2016/09/01/jest-15) that came with the seminal version 15, Jest 27 is now here, to keep Jest fast, lean, and relevant in the future. We will explain those changes of defaults and other notable breaking changes in this post, but first, let's get into some exciting new features!

<!--truncate-->

## Feature updates

Firstly, the interactive mode you may know from reviewing and updating failed snapshots can now also be used to **step through failed tests** one at a time. Credit goes to first-time contributor [@NullDivision](https://github.com/NullDivision) for [implementing](https://github.com/jestjs/jest/pull/10858) this feature!

![Interactive failed test run](/img/blog/27-interactive-failures.png)

Speaking of snapshots, one of the more exciting features we've shipped in recent years are Inline Snapshots, which [landed](https://github.com/jestjs/jest/pull/6380) in a minor release of Jest 23 almost three years ago. However, they came with the restriction that projects wanting to utilize them must be using [Prettier](https://prettier.io/) to format their code, because that's what Jest would use to make sure the file it writes the snapshots into remains properly formatted.  
And so for most of these years, we've had a [pull request](https://github.com/jestjs/jest/pull/7792) in the pipeline to eliminate this restriction and allow using **Inline Snapshots without Prettier**. It has amassed well above a hundred comments, not even taking into account PRs split out from it and landed first, and even changed owner once after the initial submission by another first-time contributor, [@mmkal](https://github.com/mmkal) under the hilarious working title 'Uglier Inline Snapshots'. With the stellar rise of Prettier in recent times, this improvement is now maybe less needed than back in 2018, but still, we know that feeling of getting into a project that does not use Prettier, and suddenly not being able to use inline snapshots anymore. Nevermore!

The main reason why it took us so long to land this was, somewhat surprisingly, an out of memory error on our build pipeline. It turns out that the dependencies we load for each test file to perform the parsing, snapshot insertion, and printing do incur a significant time and memory overhead.  
So with some [tricks](https://github.com/jestjs/jest/issues/9898), we've **speed up the initialization per test file** by roughly 70% compared to Jest 26. Note that you will almost certainly not see this big of a performance improvement on your project—you would need a lot of test files that each run very quickly to best notice this, and the overhead when using a [JSDOM environment](/docs/configuration#testenvironment-string) dwarfs any such improvement.

In other news, the [native ESM support](https://github.com/jestjs/jest/issues/9430) is progressing, but some major complexities, for instance around mocking, are still ahead of us, and we continue to observe the migration to ESM as a huge ecosystem effort, where Node and a lot of crucial tools and packages all have to rely on each other to deliver an overall compelling experience.  
ESM support [for plugging modules into Jest](https://github.com/jestjs/jest/issues/11167) is more advanced—custom runners, reporters, watch plugins, and many other modules can already be loaded as ES modules.

We've also merged [a PR](https://github.com/jestjs/jest/pull/9351) to be able to deal with test files symlinked into the test directory, a feature much wanted by users of [Bazel](https://bazel.build/).

[Another PR](https://github.com/jestjs/jest/issues/9504) enabled [`transform`s](/docs/configuration#transform-objectstring-pathtotransformer--pathtotransformer-object) to be asynchronous, a requirement to support transpilation through tools such as [esbuild](https://esbuild.github.io/), [Snowpack](https://www.snowpack.dev/), and [Vite](https://vitejs.dev/) effectively.

## Flipping defaults

Up until now, if you were using Jest in its default configuration, you were—perhaps unknowingly—running some code forked many years ago from the test runner [Jasmine 2.0](https://jasmine.github.io/2.0/introduction) that provides test framework functions such as `describe`, `it`, and `beforeEach`. In 2017, [Aaron Abramov](https://github.com/aaronabramov) [initially wrote](https://github.com/jestjs/jest/pull/3668) a **replacement for the Jasmine code** called `jest-circus`, meant to improve error messages, maintainability, and extensibility.  
After years of large-scale use at Facebook and of course in Jest itself, as well as recent adoption in `create-react-app`, we are now confident that `jest-circus` is highly compatible with `jest-jasmine2` and should work in most environments with little to no migration work. There may be minor differences in execution order and strictness, but we expect no major upgrade difficulties other than for code relying on Jasmine-specific APIs such as `jasmine.getEnv()`. If you rely extensively on such APIs, you can opt back in to the Jasmine-based test runner by [configuring](/docs/configuration#testrunner-string) `"testRunner": "jest-jasmine2"`.

Running tests in a [JSDOM environment](/docs/configuration#testenvironment-string) incurs a significant performance overhead. Because this was the default behavior of Jest unless otherwise configured up until now, users who are writing Node apps, for example, may not even know they are given an expensive DOM environment that they do not even need.  
For this reason, we are **changing the default test environment** from `"jsdom"` to `"node"`. If you are affected by this change because you use DOM APIs and do not have the test environment explicitly configured, you should be receiving an error when e.g. `document` is accessed, and you can configure `"testEnvironment": "jsdom"` or use [per-file environment configuration](/docs/configuration#testenvironment-string) to resolve this.  
For mixed projects where some tests require a DOM environment but others don't, we recommend using the fast `"node"` environment by default and declaring exactly those tests that need the DOM using [docblocks](/docs/configuration#testenvironment-string).  
In the next major, we plan to also eliminate `jest-jasmine2` and `jest-environment-jsdom` from the Jest dependency tree and require them to be installed explicitly, so that many users can profit from a smaller install size with less clutter that they don't need.

Another default that we are changing affects Fake Timers aka [Timer Mocks](/docs/timer-mocks). We introduced an opt-in "modern" implementation of Fake Timers in Jest 26 accessed transparently through the same API, but with much more comprehensive mocking, such as for `Date` and `queueMicrotask`.  
This **modern fake timers implementation will now be the default**. If you are among the unlucky few who are affected by the subtle implementation differences too heavily to migrate, you can get back the old implementation using `jest.useFakeTimers("legacy")` or, if you are enabling fake timers globally via [configuration](/docs/configuration#timers-string), `"timers": "legacy"`.

## Features coming with breaking changes

We introduced a few more small breaking changes to help you avoid mistakes by disallowing some things that can easily happen unintentionally:

- The same `done` test callback may not be called more than once,
- calling `done` and returning a Promise may not be combined,
- a `describe` block must not return anything,

and we [made some TypeScript types stricter](https://github.com/jestjs/jest/pull/10512).

Modules used in the following configuration options are now transformed like the rest of your code, which may be breaking if you relied on them being loaded as-is:

- `testEnvironment`
- `runner`
- `testRunner`
- `snapshotResolver`

## Miscellaneous breaking changes

We removed some long-deprecated functions:

- `jest.addMatchers` (use `expect.extend` instead)
- `jest.resetModuleRegistry` (use `jest.resetModules` instead)
- `jest.runTimersToTime` (use `jest.advanceTimersByTime` instead)

A lot of Jest's packages have been migrated to use ESM-style exports (although they are still shipped as CommonJS), so if you consume e.g. `pretty-format` directly, you may need to adjust your import to a `default` import.

We dropped support for Node 13—but Jest always supports the _Current_ and all _LTS_ [Node versions](https://nodejs.org/en/about/releases/), and Jest 27 continues to support Node 10, which only recently became unmaintained.

As always, the full changelog and list of breaking changes can be [viewed here](https://github.com/jestjs/jest/blob/main/CHANGELOG.md#2700).

Finally, we'd like to thank the community for once again awarding Jest a sky-high satisfaction rating of 96% in the [State of JS 2020](https://2020.stateofjs.com/en-US/technologies/testing/) survey! Stay safe everyone, and we hope you continue to enjoy using Jest in the years and versions to come! 🃏
