# @tapjs/after

> a built-in tap extension for t.after() and t.teardown()

Latest version **3.3.12** (published 2026-09-03) · BlueOak-1.0.0 license · 0 weekly downloads

## Install

```sh
npm install @tapjs/after
pnpm add @tapjs/after
yarn add @tapjs/after
bun add @tapjs/after
```

## Health

**Score 70/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; recently updated; high maintenance score; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 3.3.12 |
| Published | 2026-09-03 |
| First published | 2023-08-04 |
| Weekly downloads | 0 |
| License | BlueOak-1.0.0 |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | 20 \|\| >=22 |
| Dependencies | 1 |
| Unpacked size | 18.5 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 2423 |
| Author | Isaac Z. Schlueter |
| Maintainers | ljharb, isaacs |
| Keywords | tapjs plugin |

## Links

- npm: https://www.npmjs.com/package/@tapjs/after
- Repository: https://github.com/tapjs/tapjs
- Homepage: https://github.com/tapjs/tapjs/tree/main/src/after#readme
- Issues: https://github.com/tapjs/tapjs/issues
- npm.io page: https://npm.io/package/@tapjs/after

## Dependencies (1)

- [is-actual-promise](https://npm.io/package/is-actual-promise.md) ^1.0.1

## Recent versions

- 3.3.12 (latest) — 2026-09-03
- 1.0.0 (pre) — 2023-09-15
- 3.3.11 — 2026-07-27
- 3.3.10 — 2026-05-15
- 3.3.9 — 2026-05-13
- 3.3.8 — 2026-05-01
- 3.3.7 — 2026-04-17
- 3.3.6 — 2026-04-15
- 3.3.5 — 2026-04-05
- 3.3.4 — 2026-02-20
- 3.3.3 — 2026-02-18
- 3.3.2 — 2026-02-18
- 3.3.1 — 2026-02-05
- 3.3.0 — 2025-12-01
- 3.2.1 — 2025-11-26
- … 76 more at https://npm.io/package/@tapjs/after/versions

## README

# `@tapjs/after`

A default tap plugin providing `t.after()` and `t.teardown()`.

## USAGE

This plugin is installed with tap by default. If you had
previously removed it, you can `tap plugin add @tapjs/after` to
bring it back.

```ts
import t from 'tap'
t.after(() => {
  // this will run after all the tests in this file are done
})
```

The method can be called as either `t.teardown()` or `t.after()`.
In an earlier version of tap, these had slightly different
behaviors, but they are now the same.

If the method returns a promise, it will be awaited before moving
on to the next test.

So, this test:

```js
import t from 'tap'

t.test('first test', t => {
  t.teardown(async () => {
    // this will wait before moving on
    await new Promise(res => setTimeout(res, 100))
    console.error('end of first test teardown')
  })
  console.error('in first test')
  t.end()
})
t.test('second test', t => {
  console.error('in second test')
  t.end()
})
```

will print:

```
in first test
end of first test teardown
in second test
```

## Order

If multiple teardown methods are assigned to a single test, they
will be run in _reverse_ order of how they are assigned. This is
a change from earlier versions of tap, and provides symmetry with
`t.before()`.

In practice, it can make things more straightforward, by keeping
cleanup methods close to their associated setup logic. For
example:

```js
const connection = await connectToDB()
t.ok(connection, 'connected to database')
t.teardown(() => disconnectFromDB(connection))

const user1 = await createUser(connection)
t.ok(user1, 'created user 1')
t.teardown(() => deleteUser(connection, user1))

const user2 = await createUser(connection)
t.ok(user2, 'created user 2')
t.teardown(() => deleteUser(connection, user2))
```

If we delete the connection created in the first step _before_
deleting the user records, then we can't use that connection to
delete the user records.

This can also be accomplished with subtests, and a single
teardown in each section:

```js
t.test('user db tests', async t => {
  const connection = await connectToDB()
  t.ok(connection, 'connected to database')
  t.teardown(() => disconnectFromDB(connection))

  t.test('user 1', async t => {
    const user1 = await createUser(connection)
    t.ok(user1, 'created user 1')
    t.teardown(() => deleteUser(connection, user1))
  })

  t.test('user 2', async t => {
    const user2 = await createUser(connection)
    t.ok(user2, 'created user 2')
    t.teardown(() => deleteUser(connection, user2))
  })
})
```

---
_Source: https://npm.io/package/@tapjs/after · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
