## TL;DR

Something in your test (or setup file) started async work, a timer, an un-awaited promise, or a dynamic import, that finished after Jest tore the environment down. Find the dangling async handle, await it inside the test, or clean it up in `afterAll`. Re-running the single file with `--runInBand` usually produces the stack pointing at it.

## Error

```text
ReferenceError: You are trying to import a file after the Jest environment has been torn down
```

## Steps

1. Run only the failing file with `--runInBand`: `npx jest path/to/test --runInBand`. Expected: the stack trace names the module that imported late.
2. Search the test and its setup files for async work that outlives the test: un-awaited promises, `setTimeout` or `setInterval`, subscriptions, open sockets, dynamic `import()` in callbacks. Expected: you find at least one handle with no matching cleanup.
3. Await the work inside the test, or move the import into the test body or `beforeAll` so it resolves while the environment is alive. Expected: the import happens before teardown, error gone.
4. Tear down handles explicitly in `afterAll`: clear timers, close servers and DB pools, unsubscribe listeners. Expected: no async work survives the suite.
5. If the late import comes from a mocked module factory, make the factory synchronous or hoist the import with `jest.mock` at the top of the file. Expected: the mock resolves during setup, not after teardown.

## When to use

- The exact ReferenceError about importing after teardown appears, usually at the end of a suite.
- It shows up with ESM (`--experimental-vm-modules`) or dynamic `import()` in tests.
- The failure is intermittent and moves between files (a timing race with teardown).

## When not to use

- The error is "Cannot log after tests are done" (same family, but the fix is awaiting the logging call, not imports).
- Imports fail at the start of the run (module resolution problem, not teardown).
- You saw it once in a flaky CI run with no repro; note it, but do not refactor on one sighting.

## Tool compatibility

- Jest 27 through 30, both CJS and ESM modes.
- Most common with `--experimental-vm-modules` and dynamic `import()`.
- Applies to jsdom and node test environments.

## Variant phrasings

### jest environment has been torn down import error

Same error. The environment (jsdom or node context) is destroyed after the last test, and any later import throws.

### trying to import a file after jest teardown

Usually a promise or timer callback that calls `import()` or `require()` after the test finished.

## Why it happens

Jest tears down each test file's environment (module registry, jsdom, timers) once its tests complete. Any async work still in flight, a resolving promise or a firing timer, keeps running, and if it touches `import` or `require`, the runtime finds the registry gone and throws this ReferenceError.

## Edge cases

- `jest.useFakeTimers()` with pending timers can fire them at teardown; clear them or run them before the test ends.
- Top-level await in setup files can push imports past teardown in watch mode; keep setup imports static.
- The stack trace often points at jest-runtime internals; look one frame up for your code.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_agbj3JD1npYJPw-nlNpRvw
