Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
strategy:
fail-fast: false
matrix:
node-version: ['20', '22', '24', '26', 'latest']
node-version: ['22', '24', '26', 'latest']

env:
CI: true
Expand All @@ -35,18 +35,18 @@ jobs:
run: npm run check-bundle-size

# Run the full test suite on every supported Node version.
# Coverage + Codecov report only on the minimum supported version (20)
# Coverage + Codecov report only on the minimum supported version (22)
# to avoid redundant uploads and overhead.
- name: Run tests (with coverage)
if: matrix.node-version == '20'
if: matrix.node-version == '22'
run: npm run coverage

- name: Run tests
if: matrix.node-version != '20'
if: matrix.node-version != '22'
run: npm test

- name: Report coverage
if: matrix.node-version == '20'
if: matrix.node-version == '22'
uses: codecov/codecov-action@v5
with:
token: ${{ secrets.CODECOV_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion .nvmrc
Original file line number Diff line number Diff line change
@@ -1 +1 @@
16
22
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"js/ts.tsdk.path": "node_modules/@typescript/native-preview"
"js/ts.tsdk.path": "node_modules/typescript"
}
11 changes: 6 additions & 5 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ npm run test:e2e-apps # Framework E2E: real Next.js (Turbopack) + TanStack Start
## Build System

- **ESM-only.** There is no CJS build and no `require("tslog")` — v5 dropped dual publishing.
- **tsgo** (`@typescript/native-preview`, the TypeScript 7 native compiler) emits the ESM output (`dist/esm/`) and the declaration files (`dist/types/`).
- **tsc** from `typescript` 7 (the native compiler) emits the ESM output (`dist/esm/`) and the declaration files (`dist/types/`).
- `typescript` 7 has no JS compiler API, so a second install, `typescript-6` (`npm:typescript@6`), serves the bundler-compatibility tests: ts-loader gets `compiler: "typescript-6"`, and `vitest.config.ts` aliases `typescript` → `typescript-6` for the inlined `@rollup/plugin-typescript`.
- **esbuild** (`build.js`) bundles the browser IIFE (`dist/browser/index.js`, global `tslog`) from `src/index.browser.ts`.
- `"type": "module"` — the project is ESM throughout.
- `npm run build` = `clean-dist` (wipes `dist/` so stale files never ship) → `build-types` → `build-esm` → `build-browser` → `prepare-publish`.
Expand Down Expand Up @@ -143,7 +144,7 @@ src/
- **master** — stable releases, CI runs on push/PR
- **development** — active development branch
- Pre-commit hook via **Husky v9** (`.husky/pre-commit`) runs: test → check (biome) → build
- CI: GitHub Actions on Node 20 (coverage + browser), Bun (latest), Deno (v2.x); uploads to Codecov
- CI: GitHub Actions on Node 22, 24, 26 and latest (coverage on 22), Playwright browsers, Bun (latest), Deno (v2.x); uploads to Codecov

## Publishing

Expand All @@ -154,16 +155,16 @@ src/

## Key Conventions

- Node.js 20+ required (`package.json` `engines`); ES2022 target
- Node.js 22+ required (`package.json` `engines`); ES2022 target
- npm only (engine-strict in `.npmrc`)
- Zero runtime dependencies
- TypeScript 7 (tsgo) strict mode throughout; ESM-only
- TypeScript 7 (`tsc` from `typescript` 7) strict mode throughout; ESM-only
- Tests are numbered by feature area (e.g., `1_json_loglevel`, `5_pretty_Log_Types`)
- Browser-specific code isolated in `index.browser.ts` and `tests/support/`

## Quality Standards

- **100% test coverage** on statements, branches, functions and lines — enforced by `coverage.thresholds` in `vitest.config.ts` (`npm run coverage`, CI's Node 20 job, fails below it) — but only with meaningful tests, no padding. Vitest 4 counts the implicit `else` of every `if` as a branch and binds `/* v8 ignore next */` to a single AST node (`next N` counts are ignored; use `/* v8 ignore else */` before an `if` for a truly unreachable else path)
- **100% test coverage** on statements, branches, functions and lines — enforced by `coverage.thresholds` in `vitest.config.ts` (`npm run coverage`, CI's Node 22 job, fails below it) — but only with meaningful tests, no padding. Vitest 4+ counts the implicit `else` of every `if` as a branch and binds `/* v8 ignore next */` to a single AST node (`next N` counts are ignored; use `/* v8 ignore else */` before an `if` for a truly unreachable else path)
- Every new feature **must** have corresponding tests
- Every new feature **must** be reflected in the docs (`docs/`)
- Don't write tests just to hit coverage numbers; each test should verify real behavior
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ All notable changes to this project are documented here. This project adheres to
## [5.2.0] - 2026-09-11

### Changed
- **Node.js 22 or newer is required** — Node 20 reached end-of-life in April 2026, so `engines.node` is now `>=22` and CI no longer tests it. Stay on `tslog@5.1.0` if you still run Node 20. Nothing in the runtime code relied on dropping it; Bun, Deno and browsers are unaffected.
- **Built with stable TypeScript 7.0** — the ESM output and declarations are emitted by `tsc` from `typescript@7` instead of the `@typescript/native-preview` dev builds.
- **Logged errors are cloned** — with `mask` configured, an `Error` argument is replaced by a masked clone like every other argument, and that clone is what transports receive as `nativeError`. It is a real `Error` with the source's prototype (no subclass constructor runs), so `instanceof`, JSON error detection and Sentry-style transports keep working, and the caller's instance is never modified. Without `mask`, errors pass through untouched as before.

### Fixed
Expand Down
4 changes: 2 additions & 2 deletions MIGRATION_v4_to_v5.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ You should upgrade to v5 when you want one or more of these. None of them exist
| | v4 | v5 |
|---|---|---|
| Module system | ESM **and** CJS (`require` worked) | **ESM-only** — no CJS, no `require` |
| Node.js | 16+ | **20+** |
| Node.js | 16+ | **22+** (20+ up to 5.1) |
| TS target | es2020 | **es2022** |
| Runtime deps | none | none |

Expand Down Expand Up @@ -709,7 +709,7 @@ silently degrading. Develop against `tslog`, ship `tslog/slim`.

## Migration checklist

- [ ] Move the app (or the file importing tslog) to **ESM**; bump Node to **20+**, TS target to **es2022**.
- [ ] Move the app (or the file importing tslog) to **ESM**; bump Node to **22+** (20+ for tslog 5.0–5.1), TS target to **es2022**.
- [ ] Replace `require("tslog")` with `import`.
- [ ] Translate every flat setting key to its **grouped path** (table in §2).
- [ ] Replace `hideLogPositionForProduction` with `stack.capture: "off"` (or drop it for `type: "json"`).
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Donations help me allocate more time for my open source work.
The per-runtime details are below.

> [!IMPORTANT]
> **tslog v5 is ESM-only and requires Node.js ≥ 20.** There is no CommonJS build and no `require("tslog")`. If you cannot move to ESM or off Node 16/18 yet, stay on **`tslog@4.11.0`** — it keeps CJS, Node 16+ and the v4 JSON shape. See **[Upgrading from v4?](#upgrading-from-v4)**.
> **tslog v5 is ESM-only and requires Node.js ≥ 22** (5.0–5.1 also ran on Node 20; stay on **`tslog@5.1.0`** if you are still on it). There is no CommonJS build and no `require("tslog")`. If you cannot move to ESM or off Node 16/18 yet, stay on **`tslog@4.11.0`** — it keeps CJS, Node 16+ and the v4 JSON shape. See **[Upgrading from v4?](#upgrading-from-v4)**.

### Node.js

Expand Down Expand Up @@ -1061,7 +1061,7 @@ Whichever logger you come from, `createTestLogger` from `tslog/testing` captures
> [!IMPORTANT]
> **`tslog@4.11.0` is the safe staying point.** Most of the v5 performance wins (faster lazy stack capture, transport isolation, masking fixes) were back-ported to **4.11.0 with zero breaking changes**. If you are on the 4.x line and just want the wins, `npm install tslog@4.11.0` keeps your existing settings, CJS `require`, Node 16+, and the v4 JSON shape exactly as they are. There is no deprecation pressure.

Move to **v5** when you actually want its new capabilities: opt-in structured JSON output, the flat fields-first JSON shape, grouped settings, `use()` middleware, per-transport level/format, the presets, and the AI/agent DX. v5 is ESM-only and requires Node ≥ 20.
Move to **v5** when you actually want its new capabilities: opt-in structured JSON output, the flat fields-first JSON shape, grouped settings, `use()` middleware, per-transport level/format, the presets, and the AI/agent DX. v5 is ESM-only and requires Node ≥ 22 (≥ 20 up to 5.1).

👉 **Full guide: [MIGRATION_v4_to_v5.md](./MIGRATION_v4_to_v5.md)** — it maps every removed v4 setting (`stylePrettyLogs`, `prettyLogTemplate`, `maskValuesOfKeys`, `metaProperty`, `hideLogPositionForProduction`, the whole `overwrite.*` family, …) to its v5 replacement.

Expand Down
4 changes: 2 additions & 2 deletions biome.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://biomejs.dev/schemas/2.3.14/schema.json",
"$schema": "https://biomejs.dev/schemas/2.5.13/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
Expand All @@ -24,7 +24,7 @@
"linter": {
"enabled": true,
"rules": {
"recommended": true
"preset": "recommended"
}
},
"assist": {
Expand Down
Loading
Loading