This episode covers managing Jest in a monorepo structure: multi-project configuration, running tests selectively per package, and centralized versus per-package config decisions.

A monorepo unites many packages — libraries, services, and applications — in a single repository. It's efficient, but challenging for tooling that must know which configuration applies to which package. Episode 17 covers monorepos & multi-project testing with Jest: managing Jest across a monorepo structure, multi-project configuration, running tests selectively per package, and deciding between centralized and per-package config.
The right approach makes a monorepo suite fast and organized, while the wrong approach produces configuration conflicts and tests that interfere with each other.
A monorepo usually has a structure like this:
packages/
core/
src/
index.js
package.json
api/
src/
server.js
package.json
jest.config.jsEach package has different needs: core is pure JavaScript running in node, while api may need jsdom or extra setup. A single global configuration rarely fits all of them — this is where multi-project config comes in.
Jest supports project mode by writing a list of projects inside a single config file:
module.exports = {
projects: [
{
displayName: "core",
testMatch: ["<rootDir>/packages/core/**/*.test.js"],
},
{
displayName: "api",
testEnvironment: "jsdom",
testMatch: ["<rootDir>/packages/api/**/*.test.js"],
setupFilesAfterEnv: ["<rootDir>/packages/api/setup.js"],
},
],
};displayName labels each project in the output, so you can clearly see which tests belong to which package. Each project carries its own configuration — api uses jsdom while core stays on node.
When running Jest in project mode, the output shows each project's label next to its results. This makes debugging much easier: you immediately know whether a failure comes from the core or api package, complete with the configuration in effect.
Jest provides a flag to run only specific projects:
npx jest --selectProjects coreThe command npx jest --selectProjects core runs only the project named core. This is very useful in CI: packages that didn't change don't need re-testing, so the pipeline runs much faster.
--selectProjects can be combined with the regular test pattern:
npx jest --selectProjects api -t "server"The command npx jest --selectProjects api -t "server" restricts to the api project while only running tests whose names contain "server". This combination gives precise control to run a very small subset while debugging.
A centralized config at the root fits when all packages share the same policies — for example clearMocks, coverage thresholds, or report formats. The benefit: one place to change policy, and no configuration duplicated across 20 packages.
Per-package config is more flexible for genuinely different needs — special environments, special transforms, or different domain matchers. The downside: policy decisions become scattered and can conflict.
A common strategy: a base config at the root for shared policy, and a per-package project config only to override what genuinely differs. Each package can have its own jest.config.js that extends the root one, keeping duplication minimal.
For large monorepos, tools like Turborepo or Nx can orchestrate per-package test commands with caching and a dependency graph. Jest remains the runner inside them — these tools only decide when and which packages to run.
Episode 17 covered testing in a monorepo: multi-project configuration with displayName, running tests selectively with --selectProjects, and the centralized versus per-package config decision, with a strategy of extending from a base config.
Key takeaways:
displayName gives clear labels in per-project output.--selectProjects runs only the projects you need.-t for a very precise subset.In the next episode, episode 18, we'll cover migrating & upgrading Jest — upgrading Jest versions safely, migrating from other frameworks, handling breaking changes and test refactoring, and maintaining long-term suite stability.