get-tbd 0.1.27 → 0.1.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.mjs +140 -104
- package/dist/bin.mjs.map +1 -1
- package/dist/cli.mjs +41 -15
- package/dist/cli.mjs.map +1 -1
- package/dist/docs/guidelines/bun-monorepo-patterns.md +328 -58
- package/dist/docs/guidelines/pnpm-monorepo-patterns.md +399 -64
- package/dist/docs/guidelines/typescript-cli-tool-rules.md +39 -8
- package/dist/docs/guidelines/typescript-code-coverage.md +27 -3
- package/dist/docs/guidelines/typescript-rules.md +18 -0
- package/dist/docs/guidelines/typescript-yaml-handling-rules.md +12 -0
- package/dist/docs/tbd-design.md +16 -1
- package/dist/docs/tbd-docs.md +11 -2
- package/dist/index.mjs +1 -1
- package/dist/{src-BIE27KDA.mjs → src-D2xEmH4L.mjs} +2 -2
- package/dist/{src-BIE27KDA.mjs.map → src-D2xEmH4L.mjs.map} +1 -1
- package/dist/tbd +140 -104
- package/package.json +2 -2
|
@@ -5,7 +5,7 @@ author: Joshua Levy (github.com/jlevy) with LLM assistance
|
|
|
5
5
|
---
|
|
6
6
|
# Bun Monorepo Patterns
|
|
7
7
|
|
|
8
|
-
**Last Updated**: 2026-
|
|
8
|
+
**Last Updated**: 2026-05-21
|
|
9
9
|
|
|
10
10
|
**Related**:
|
|
11
11
|
|
|
@@ -14,6 +14,7 @@ author: Joshua Levy (github.com/jlevy) with LLM assistance
|
|
|
14
14
|
- [Changesets Documentation](https://github.com/changesets/changesets)
|
|
15
15
|
- [Biome Documentation](https://biomejs.dev/)
|
|
16
16
|
- [Companion: pnpm Monorepo Patterns](./pnpm-monorepo-patterns.md)
|
|
17
|
+
- [Supply-Chain Mitigation](#supply-chain-mitigation) (in this document)
|
|
17
18
|
|
|
18
19
|
* * *
|
|
19
20
|
|
|
@@ -23,19 +24,19 @@ author: Joshua Levy (github.com/jlevy) with LLM assistance
|
|
|
23
24
|
|
|
24
25
|
| Tool / Package | Version | Check For Updates |
|
|
25
26
|
| --- | --- | --- |
|
|
26
|
-
| **Bun** | 1.3.
|
|
27
|
-
| **TypeScript** | ^
|
|
28
|
-
| **Bunup** | ^0.16.
|
|
29
|
-
| **Biome** | ^2.
|
|
30
|
-
| **@changesets/cli** | ^2.
|
|
31
|
-
| **bun-types** | ^1.3.
|
|
27
|
+
| **Bun** | 1.3.13 (1.3.14 too recent) | [bun.sh/blog](https://bun.sh/blog) — Runtime, bundler, package manager, test runner. Acquired by Anthropic (Dec 2025). **Pinned to 1.3.13 (2026-04-20) per the 14-day rule** — 1.3.14 (2026-05-13) is the **last Zig-based release** and the Rust rewrite merged to `main` 2026-05-14 (~960K lines, generated by Claude AI agents over ~6 days). New built-ins in 1.3.x: `Bun.Image` (Sharp replacement), experimental HTTP/3 in `Bun.serve()`, 7× faster warm installs via isolated linker global store, rewritten `fs.watch()` on Linux/macOS. Bump to 1.3.14 (or 1.4.x once it ships) once the 14-day window has elapsed. |
|
|
28
|
+
| **TypeScript** | ^6.0.3 | [github.com/microsoft/TypeScript/releases](https://github.com/microsoft/TypeScript/releases) — **6.0.3 stable** (shipped 2026-03-23). TS 6.0 is the **last JavaScript-based release** and is positioned as a bridge to 7.0: `strict: true` is now the default, ESM is the default module system, and ~9 compiler settings flipped defaults. **TS 7.0 Beta** (Project Corsa, Go rewrite) shipped 2026-04-21 as `@typescript/native-preview` (binary: `tsgo`); claims ~10× type-check speed and ~3× less memory. TS 7.0 stable is expected mid-to-late 2026. Do not adopt `tsgo` for production builds yet. |
|
|
29
|
+
| **Bunup** | ^0.16.31 | [npmjs.com/package/bunup](https://www.npmjs.com/package/bunup) — Build tool for TS libs. Still 0.x; 0.16.23 through 0.16.31 are bug-fix only (DTS alias fixes, workspace `onSuccess` fix, external/noExternal honoring). Pin to a specific minor version for stability. |
|
|
30
|
+
| **Biome** | ^2.4.14 (2.4.15 borderline) | [biomejs.dev](https://biomejs.dev/) — Formatter + linter. **Pinned to 2.4.14 (2026-05-01) per the 14-day rule**; 2.4.15 (2026-05-09) is 13 days old today — bump on next refresh. v2.4 (Feb 2026) added experimental embedded snippet formatting (CSS/GraphQL in JS/TS template literals), 15 HTML accessibility lint rules enabled by default, and promoted 24 nursery rules to stable (Vue 3, Next.js, Qwik). |
|
|
31
|
+
| **@changesets/cli** | ^2.31.0 | [github.com/changesets/changesets/releases](https://github.com/changesets/changesets/releases) — 2.31.0 latest. **Still no native Bun support**; `changeset version` does not resolve `workspace:*` references for Bun workspaces — workarounds below remain required. |
|
|
32
|
+
| **bun-types** | ^1.3.13 | [npmjs.com/package/bun-types](https://www.npmjs.com/package/bun-types) — Type definitions for Bun runtime APIs. Track Bun version (pinned to 1.3.13 per the 14-day rule). |
|
|
32
33
|
| **tryscript** | ^0.1.6 | [npmjs.com/package/tryscript](https://www.npmjs.com/package/tryscript) — Golden/CLI testing via Markdown test files. |
|
|
33
34
|
| **flowmark** | latest | [github.com/jlevy/flowmark](https://github.com/jlevy/flowmark) — Markdown auto-formatter (via `uvx`). |
|
|
34
|
-
| **publint** | ^0.3.
|
|
35
|
-
| **actions/checkout** | v6 | [github.com/actions/checkout/releases](https://github.com/actions/checkout/releases) |
|
|
36
|
-
| **oven-sh/setup-bun** | v2 | [github.com/oven-sh/setup-bun](https://github.com/oven-sh/setup-bun) —
|
|
37
|
-
| **lefthook** | ^2.
|
|
38
|
-
| **npm-check-updates** | ^
|
|
35
|
+
| **publint** | ^0.3.20 (0.3.21 too recent) | [npmjs.com/package/publint](https://www.npmjs.com/package/publint) — **Pinned to 0.3.20 (2026-05-08) per the 14-day rule**; 0.3.21 (2026-05-13) is 9 days old today. Incremental: re-enabled TS/TSX file existence checks; `exports["default"]` support. |
|
|
36
|
+
| **actions/checkout** | v6 | [github.com/actions/checkout/releases](https://github.com/actions/checkout/releases) — v6.0.2 (2026-01-09). Credentials now stored in `$RUNNER_TEMP` rather than `.git/config`; Node 24 runtime; requires runner ≥ 2.327.1. |
|
|
37
|
+
| **oven-sh/setup-bun** | v2 | [github.com/oven-sh/setup-bun](https://github.com/oven-sh/setup-bun) — v2.2.0 (2026-03-14). Migrated to Node.js 24 runtime ahead of GitHub's **2026-06-02 deadline** that forces all Node.js 20 actions to Node.js 24. |
|
|
38
|
+
| **lefthook** | ^2.1.5 (2.1.7/2.1.8 too recent) | [github.com/evilmartians/lefthook/releases](https://github.com/evilmartians/lefthook/releases) — **Pinned to 2.1.5 (2026-04-06) per the 14-day rule**; 2.1.7 and 2.1.8 both shipped 2026-05-19 (3 days old). Patch-level since 2.1.1: dependency bumps and config-warning improvements. v2 still excludes regexp `exclude` and `skip_output` from v1. |
|
|
39
|
+
| **npm-check-updates** | ^22.0.0 (22.2.0 too recent) | [npmjs.com/package/npm-check-updates](https://www.npmjs.com/package/npm-check-updates) — **Major version jump from 19 to 22.** **Pinned to 22.0.0 (2026-04-25) per the 14-day rule**; 22.2.0 (2026-05-12) is 10 days old today. Now pure ESM; named imports only (`import { run } from 'npm-check-updates'`); `.ncurc.js` with `module.exports` no longer works in `"type": "module"` projects (use `.ncurc.cjs`). **Critical for supply chain: now ships `--cooldown <days>` to refuse versions younger than the specified age.** See [Supply-Chain Mitigation](#supply-chain-mitigation). |
|
|
39
40
|
|
|
40
41
|
### Reminders When Updating
|
|
41
42
|
|
|
@@ -61,6 +62,11 @@ author: Joshua Levy (github.com/jlevy) with LLM assistance
|
|
|
61
62
|
|
|
62
63
|
6. **Review “Open Research Questions”** section for any resolved items
|
|
63
64
|
|
|
65
|
+
7. **Honor the 14-day package-age rule** when bumping versions in code examples. See
|
|
66
|
+
[Supply-Chain Mitigation](#supply-chain-mitigation) — versions cited here should be
|
|
67
|
+
≥14 days old at the time the table is updated, except where a clearly-noted
|
|
68
|
+
security exception applies.
|
|
69
|
+
|
|
64
70
|
* * *
|
|
65
71
|
|
|
66
72
|
## Executive Summary
|
|
@@ -140,9 +146,17 @@ research stock.
|
|
|
140
146
|
- Missing some pnpm features: no `pnpm deploy`, less strict `node_modules` (phantom
|
|
141
147
|
dependencies possible)
|
|
142
148
|
|
|
143
|
-
- **Notable**: Bun was acquired by Anthropic
|
|
144
|
-
|
|
145
|
-
|
|
149
|
+
- **Notable**: Bun was acquired by Anthropic on 2025-12-02 — Anthropic's first
|
|
150
|
+
acquisition. Bun powers Claude Code (which ships as a `bun build --compile`
|
|
151
|
+
executable), the Claude Agent SDK, and other Anthropic AI tooling, signaling
|
|
152
|
+
strong ongoing investment and maintenance. **Language transition**: Bun 1.3.14
|
|
153
|
+
(2026-05-13) is the last Zig-based release. A full Rust rewrite (~960K lines,
|
|
154
|
+
generated by Claude agents over ~6 days, 6,755 commits) merged to `main` on
|
|
155
|
+
2026-05-14 and passes 99.8% of the test suite. The transition was motivated by
|
|
156
|
+
Zig's no-AI-contribution policy conflicting with the Bun team's workflow. The
|
|
157
|
+
external API surface (`bun`, `bunx`, `bun install`, `bun test`, `bun build`)
|
|
158
|
+
is unchanged; consumers should expect no breakage but watch the 1.4.x release
|
|
159
|
+
notes for migration details.
|
|
146
160
|
|
|
147
161
|
**Assessment**: Bun workspaces are functional and fast, but less strict than pnpm.
|
|
148
162
|
The text-based `bun.lock` format (since Bun 1.2) resolves the earlier diffability
|
|
@@ -375,8 +389,8 @@ Key advantages:
|
|
|
375
389
|
|
|
376
390
|
- **Compile support**: Can produce standalone executables via `bun --compile`
|
|
377
391
|
|
|
378
|
-
- **Rapid iteration**: Bunup is under active development (0.16.
|
|
379
|
-
|
|
392
|
+
- **Rapid iteration**: Bunup is under active development (0.16.31 as of May 2026,
|
|
393
|
+
bug-fix releases since 0.16.22). Pin to a specific minor version for stability.
|
|
380
394
|
|
|
381
395
|
**Configuration (`bunup.config.ts`)**:
|
|
382
396
|
|
|
@@ -1085,7 +1099,7 @@ bun add -d @biomejs/biome
|
|
|
1085
1099
|
|
|
1086
1100
|
```json
|
|
1087
1101
|
{
|
|
1088
|
-
"$schema": "https://biomejs.dev/schemas/2.
|
|
1102
|
+
"$schema": "https://biomejs.dev/schemas/2.4.14/schema.json",
|
|
1089
1103
|
"vcs": {
|
|
1090
1104
|
"enabled": true,
|
|
1091
1105
|
"clientKind": "git",
|
|
@@ -1695,23 +1709,32 @@ This is a unique advantage that the pnpm ecosystem does not offer natively.
|
|
|
1695
1709
|
|
|
1696
1710
|
**Details**:
|
|
1697
1711
|
|
|
1698
|
-
npm-check-updates (`ncu`) works with Bun.
|
|
1699
|
-
|
|
1712
|
+
npm-check-updates (`ncu`) works with Bun. The main difference is using `bun install`
|
|
1713
|
+
instead of `pnpm install` after updates. **All upgrade commands must honor the
|
|
1714
|
+
14-day package-age rule** — see [Supply-Chain Mitigation](#supply-chain-mitigation)
|
|
1715
|
+
for the rationale and exception process. `ncu` v22+ ships a native `--cooldown`
|
|
1716
|
+
flag that enforces this directly.
|
|
1700
1717
|
|
|
1701
1718
|
**Root `package.json` scripts**:
|
|
1702
1719
|
|
|
1703
1720
|
```json
|
|
1704
1721
|
{
|
|
1705
1722
|
"scripts": {
|
|
1706
|
-
"upgrade:check": "bunx npm-check-updates --format group",
|
|
1707
|
-
"upgrade": "bunx npm-check-updates --target minor -u && bun install && bun test",
|
|
1708
|
-
"upgrade:major": "bunx npm-check-updates --target latest --interactive --format group"
|
|
1723
|
+
"upgrade:check": "bunx npm-check-updates --cooldown 14 --format group",
|
|
1724
|
+
"upgrade": "bunx npm-check-updates --cooldown 14 --target minor -u && bun install && bun test",
|
|
1725
|
+
"upgrade:major": "bunx npm-check-updates --cooldown 14 --target latest --interactive --format group"
|
|
1709
1726
|
}
|
|
1710
1727
|
}
|
|
1711
1728
|
```
|
|
1712
1729
|
|
|
1713
|
-
**
|
|
1714
|
-
`
|
|
1730
|
+
**Note on npm-check-updates v22**: v22 is pure ESM, named imports only
|
|
1731
|
+
(`import { run } from 'npm-check-updates'`), and config files must be
|
|
1732
|
+
`.ncurc.cjs` (not `.ncurc.js`) in projects with `"type": "module"`. The
|
|
1733
|
+
`--cooldown <days>` flag is the recommended enforcement point for the 14-day
|
|
1734
|
+
package-age rule.
|
|
1735
|
+
|
|
1736
|
+
**Assessment**: Identical workflow to pnpm. `bunx` replaces `npx`. Always
|
|
1737
|
+
include `--cooldown 14`.
|
|
1715
1738
|
|
|
1716
1739
|
* * *
|
|
1717
1740
|
|
|
@@ -1741,7 +1764,7 @@ Bun natively executes TypeScript, eliminating the need for `tsx` entirely.
|
|
|
1741
1764
|
| Aspect | pnpm (tsx) | Bun |
|
|
1742
1765
|
| --- | --- | --- |
|
|
1743
1766
|
| Dev command | `tsx packages/pkg/src/cli/bin.ts` | `bun packages/pkg/src/cli/bin.ts` |
|
|
1744
|
-
| Extra dependency | `tsx` (~4.
|
|
1767
|
+
| Extra dependency | `tsx` (~4.22.3) | None (built-in) |
|
|
1745
1768
|
| TypeScript support | Via esbuild transform | Native |
|
|
1746
1769
|
| Startup time | ~50ms | ~5ms |
|
|
1747
1770
|
|
|
@@ -1785,6 +1808,221 @@ in core library code if the library needs to work in Node.js environments.
|
|
|
1785
1808
|
|
|
1786
1809
|
* * *
|
|
1787
1810
|
|
|
1811
|
+
## Supply-Chain Mitigation
|
|
1812
|
+
|
|
1813
|
+
> **Sync note**: this section is normative and is duplicated **verbatim** in both
|
|
1814
|
+
> `bun-monorepo-patterns.md` and `pnpm-monorepo-patterns.md`. When you change one,
|
|
1815
|
+
> change the other in the same commit. Tooling-specific commands (e.g.
|
|
1816
|
+
> `bun audit` vs. `pnpm audit`) are called out inline.
|
|
1817
|
+
|
|
1818
|
+
Modern TypeScript supply-chain attacks land through fresh package versions — a
|
|
1819
|
+
maintainer's npm token is compromised, malware is published as a patch release, and
|
|
1820
|
+
the registry yanks it 1–10 days later once detection catches up. The
|
|
1821
|
+
**Shai-Hulud 2.0** campaign of May 2026 compromised 170+ npm packages this way, and
|
|
1822
|
+
similar campaigns ran through 2025 (`debug`, `chalk`, `ansi-styles` lookalikes;
|
|
1823
|
+
`expr-eval` post-install RCE). pnpm shipped `minimumReleaseAge` as a default in
|
|
1824
|
+
v11.0 (1 day). Bun ships a built-in trusted-dependency allowlist and `bun audit`.
|
|
1825
|
+
The settings below are stricter than the ecosystem defaults and intentionally so.
|
|
1826
|
+
|
|
1827
|
+
### The 14-day package-age rule
|
|
1828
|
+
|
|
1829
|
+
**Never install or upgrade to a package version less than 14 days old.**
|
|
1830
|
+
|
|
1831
|
+
Why 14 days specifically:
|
|
1832
|
+
|
|
1833
|
+
- **Detection window**: most malicious publishes are reported and yanked within
|
|
1834
|
+
3–7 days; 14 days gives a generous buffer past that median.
|
|
1835
|
+
- **Patch-level releases ship dangerous code more often**: many compromises arrive
|
|
1836
|
+
as `1.2.3 → 1.2.4` patch bumps. A trailing window neutralizes the entire class
|
|
1837
|
+
of "fresh patch is malicious" attacks regardless of which dependency moved.
|
|
1838
|
+
- **Cheap to enforce, cheap to wait**: there is essentially no business cost to
|
|
1839
|
+
waiting 14 days on a routine upgrade, and the upside is large.
|
|
1840
|
+
|
|
1841
|
+
Scope:
|
|
1842
|
+
|
|
1843
|
+
- Applies to **`dependencies`, `devDependencies`, `peerDependencies`, and
|
|
1844
|
+
`optionalDependencies`** alike. devDependencies (bundlers, linters, test
|
|
1845
|
+
runners) have historically been *more* dangerous than runtime deps because
|
|
1846
|
+
they execute with full developer privileges on every install.
|
|
1847
|
+
- Applies to **transitive dependencies** to the extent the package manager
|
|
1848
|
+
enforces it (see below). Direct deps are the primary control point.
|
|
1849
|
+
- Applies to **upgrades and new installs**. Existing pins resolved before this
|
|
1850
|
+
policy was adopted are grandfathered until their next planned upgrade.
|
|
1851
|
+
|
|
1852
|
+
Exception process: if a security patch within the 14-day window is needed —
|
|
1853
|
+
e.g., a CVE patch published yesterday that fixes a vulnerability you are
|
|
1854
|
+
exposed to — the exception **must** be documented in the upgrade commit message
|
|
1855
|
+
or PR description, including:
|
|
1856
|
+
|
|
1857
|
+
- The CVE ID (or vulnerability description if no CVE yet).
|
|
1858
|
+
- A link to the upstream release notes.
|
|
1859
|
+
- A reviewer sign-off line (`Reviewed-by: …`).
|
|
1860
|
+
|
|
1861
|
+
No exception is "trivial" — even a `prettier` patch is in scope. The whole
|
|
1862
|
+
point of the rule is that we don't trust ourselves to spot-judge which fresh
|
|
1863
|
+
versions are safe.
|
|
1864
|
+
|
|
1865
|
+
### Enforcement: Bun
|
|
1866
|
+
|
|
1867
|
+
Bun blocks arbitrary lifecycle scripts by default via an internal allowlist of
|
|
1868
|
+
trusted packages. To extend that allowlist for your repo, declare the packages
|
|
1869
|
+
explicitly in `package.json`:
|
|
1870
|
+
|
|
1871
|
+
```json
|
|
1872
|
+
{
|
|
1873
|
+
"trustedDependencies": [
|
|
1874
|
+
"esbuild",
|
|
1875
|
+
"sharp"
|
|
1876
|
+
]
|
|
1877
|
+
}
|
|
1878
|
+
```
|
|
1879
|
+
|
|
1880
|
+
Anything not in the allowlist runs without `postinstall`/`preinstall`/`install`
|
|
1881
|
+
scripts. This is the most important single mitigation Bun gives you out of the
|
|
1882
|
+
box.
|
|
1883
|
+
|
|
1884
|
+
`bun audit` (documented at [bun.com/docs/pm/cli/audit](https://bun.com/docs/pm/cli/audit))
|
|
1885
|
+
checks the installed tree against the npm advisory database:
|
|
1886
|
+
|
|
1887
|
+
```bash
|
|
1888
|
+
# Run as part of CI; non-zero exit on findings
|
|
1889
|
+
bun audit --audit-level=moderate
|
|
1890
|
+
|
|
1891
|
+
# JSON output for parsing in scripts
|
|
1892
|
+
bun audit --json
|
|
1893
|
+
```
|
|
1894
|
+
|
|
1895
|
+
Bun does **not yet** ship a built-in equivalent of pnpm's `minimumReleaseAge`,
|
|
1896
|
+
so age enforcement is handled at the upgrade-tool layer (see below).
|
|
1897
|
+
|
|
1898
|
+
### Enforcement: cross-tool tooling
|
|
1899
|
+
|
|
1900
|
+
**`npm-check-updates --cooldown`** is the primary upgrade-time check. Use it
|
|
1901
|
+
even on Bun-managed projects (via `bunx`):
|
|
1902
|
+
|
|
1903
|
+
```bash
|
|
1904
|
+
# Refuse any candidate version younger than 14 days
|
|
1905
|
+
bunx npm-check-updates --cooldown 14
|
|
1906
|
+
|
|
1907
|
+
# Interactive upgrade with the 14-day filter applied
|
|
1908
|
+
bunx npm-check-updates --cooldown 14 --target minor --interactive
|
|
1909
|
+
|
|
1910
|
+
# CI-style check: exits non-zero if upgrades are available
|
|
1911
|
+
bunx npm-check-updates --cooldown 14 --errorLevel 2
|
|
1912
|
+
```
|
|
1913
|
+
|
|
1914
|
+
**Direct registry query** (when in doubt about a specific version):
|
|
1915
|
+
|
|
1916
|
+
```bash
|
|
1917
|
+
# Show all publish times for a package
|
|
1918
|
+
npm view typescript time
|
|
1919
|
+
|
|
1920
|
+
# Show the time of a specific version
|
|
1921
|
+
npm view typescript time.6.0.3
|
|
1922
|
+
```
|
|
1923
|
+
|
|
1924
|
+
If `npm view <pkg> time.<version>` reports less than 14 days ago, **wait**.
|
|
1925
|
+
|
|
1926
|
+
### Enforcement: lockfile discipline
|
|
1927
|
+
|
|
1928
|
+
- **Always commit `bun.lock`** (the text JSONC lockfile, default since Bun 1.2).
|
|
1929
|
+
- **Use `bun install --frozen-lockfile` in CI** so any drift between
|
|
1930
|
+
`package.json` and `bun.lock` fails the build instead of silently resolving
|
|
1931
|
+
to fresh versions.
|
|
1932
|
+
- **Never run `bun update` (or `bun install` on a fresh `node_modules` with an
|
|
1933
|
+
unpinned `package.json`) without lockfile review.** Treat lockfile diffs the
|
|
1934
|
+
same as code diffs.
|
|
1935
|
+
- In a monorepo, **a single root `bun.lock`** is the source of truth; per-package
|
|
1936
|
+
lockfiles are an anti-pattern.
|
|
1937
|
+
|
|
1938
|
+
### Enforcement: provenance and signatures
|
|
1939
|
+
|
|
1940
|
+
- Prefer dependencies that publish with [npm provenance attestations](https://docs.npmjs.com/generating-provenance-statements).
|
|
1941
|
+
Major projects (TypeScript, Vitest, Prettier, ESLint, etc.) ship these.
|
|
1942
|
+
- Run `npm audit signatures` (or the upcoming `bun audit signatures` once it
|
|
1943
|
+
ships) in CI on a periodic basis to catch tampered packages.
|
|
1944
|
+
|
|
1945
|
+
### Sample CI gate
|
|
1946
|
+
|
|
1947
|
+
Add this job to the CI workflow alongside lint/test:
|
|
1948
|
+
|
|
1949
|
+
```yaml
|
|
1950
|
+
audit:
|
|
1951
|
+
runs-on: ubuntu-latest
|
|
1952
|
+
steps:
|
|
1953
|
+
- uses: actions/checkout@v6
|
|
1954
|
+
- uses: oven-sh/setup-bun@v2
|
|
1955
|
+
with:
|
|
1956
|
+
bun-version: latest
|
|
1957
|
+
- run: bun install --frozen-lockfile
|
|
1958
|
+
- name: Vulnerability audit
|
|
1959
|
+
run: bun audit --audit-level=moderate
|
|
1960
|
+
- name: Package-age check
|
|
1961
|
+
run: bunx npm-check-updates --cooldown 14 --errorLevel 0
|
|
1962
|
+
# errorLevel 0 logs but doesn't fail — flip to 2 once you've cleared
|
|
1963
|
+
# the existing backlog.
|
|
1964
|
+
```
|
|
1965
|
+
|
|
1966
|
+
### Recommended local script
|
|
1967
|
+
|
|
1968
|
+
Drop a `scripts/check-package-age.mjs` (or `.ts`) one-liner in the repo that a
|
|
1969
|
+
pre-push hook can call:
|
|
1970
|
+
|
|
1971
|
+
```ts
|
|
1972
|
+
#!/usr/bin/env bun
|
|
1973
|
+
// Refuses to commit if any direct dependency in package.json was published
|
|
1974
|
+
// less than COOLDOWN_DAYS ago. Intended for the pre-push hook.
|
|
1975
|
+
import pkg from '../package.json' with { type: 'json' };
|
|
1976
|
+
|
|
1977
|
+
const COOLDOWN_MS = 14 * 24 * 60 * 60 * 1000;
|
|
1978
|
+
const now = Date.now();
|
|
1979
|
+
const all = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
1980
|
+
|
|
1981
|
+
let violations = 0;
|
|
1982
|
+
for (const [name, spec] of Object.entries(all)) {
|
|
1983
|
+
const version = String(spec).replace(/^[\^~=<>]+/, '');
|
|
1984
|
+
const meta = await (await fetch(`https://registry.npmjs.org/${name}`)).json();
|
|
1985
|
+
const publishedAt = meta.time?.[version];
|
|
1986
|
+
if (!publishedAt) continue;
|
|
1987
|
+
const ageMs = now - new Date(publishedAt).getTime();
|
|
1988
|
+
if (ageMs < COOLDOWN_MS) {
|
|
1989
|
+
const days = (ageMs / 86_400_000).toFixed(1);
|
|
1990
|
+
console.error(`✗ ${name}@${version} is only ${days} days old (< 14)`);
|
|
1991
|
+
violations++;
|
|
1992
|
+
}
|
|
1993
|
+
}
|
|
1994
|
+
process.exit(violations > 0 ? 1 : 0);
|
|
1995
|
+
```
|
|
1996
|
+
|
|
1997
|
+
Wire it into lefthook (see Appendix E):
|
|
1998
|
+
|
|
1999
|
+
```yaml
|
|
2000
|
+
pre-push:
|
|
2001
|
+
commands:
|
|
2002
|
+
package-age:
|
|
2003
|
+
glob: "package.json"
|
|
2004
|
+
run: bun scripts/check-package-age.ts
|
|
2005
|
+
```
|
|
2006
|
+
|
|
2007
|
+
### Exception bookkeeping
|
|
2008
|
+
|
|
2009
|
+
When you take an exception, leave a one-line marker in `package.json` adjacent
|
|
2010
|
+
to the pin:
|
|
2011
|
+
|
|
2012
|
+
```jsonc
|
|
2013
|
+
{
|
|
2014
|
+
"devDependencies": {
|
|
2015
|
+
// Exception: CVE-2026-XXXX patch within 14d window. Reviewed 2026-05-21.
|
|
2016
|
+
"vitest": "4.1.7"
|
|
2017
|
+
}
|
|
2018
|
+
}
|
|
2019
|
+
```
|
|
2020
|
+
|
|
2021
|
+
(JSON strict-parsers will reject `//` comments — use a JSONC-aware tool or
|
|
2022
|
+
move the note to a `README.md` / `CHANGELOG.md` entry instead.)
|
|
2023
|
+
|
|
2024
|
+
* * *
|
|
2025
|
+
|
|
1788
2026
|
## Comparative Analysis
|
|
1789
2027
|
|
|
1790
2028
|
### Full-Stack Tooling Comparison
|
|
@@ -1834,10 +2072,16 @@ in core library code if the library needs to work in Node.js environments.
|
|
|
1834
2072
|
|
|
1835
2073
|
## Best Practices
|
|
1836
2074
|
|
|
1837
|
-
1. **
|
|
2075
|
+
1. **Follow the 14-day package-age rule** for every dependency install and upgrade.
|
|
2076
|
+
See [Supply-Chain Mitigation](#supply-chain-mitigation). Use
|
|
2077
|
+
`bunx npm-check-updates --cooldown 14` and `bun audit` in CI; declare
|
|
2078
|
+
`trustedDependencies` explicitly; commit `bun.lock`; use
|
|
2079
|
+
`bun install --frozen-lockfile` in CI.
|
|
2080
|
+
|
|
2081
|
+
2. **Use Bun workspaces** with `"workspaces"` in root `package.json`. Use `--cwd` to
|
|
1838
2082
|
target specific workspaces when adding dependencies.
|
|
1839
2083
|
|
|
1840
|
-
|
|
2084
|
+
3. **Enable `isolatedDeclarations`** in `tsconfig.base.json` for dramatically faster DTS
|
|
1841
2085
|
generation with Bunup.
|
|
1842
2086
|
|
|
1843
2087
|
3. **Use Bunup’s auto-exports** (`exports: true`) to keep `package.json` exports
|
|
@@ -1913,12 +2157,12 @@ in core library code if the library needs to work in Node.js environments.
|
|
|
1913
2157
|
It is diffable in code review and supported by GitHub rendering.
|
|
1914
2158
|
The binary `bun.lockb` is deprecated.
|
|
1915
2159
|
|
|
1916
|
-
4. **Biome plugin ecosystem**: Biome v2.
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
Custom ESLint rules remain a reason to keep ESLint
|
|
1921
|
-
in Appendix G).
|
|
2160
|
+
4. **Biome plugin ecosystem**: Biome v2.4 (Feb 2026) added experimental embedded
|
|
2161
|
+
snippet formatting (CSS/GraphQL inside JS/TS template literals), 15 HTML
|
|
2162
|
+
accessibility rules enabled by default, and promoted Vue 3 / Next.js / Qwik
|
|
2163
|
+
rules to stable. The rule set continues growing toward parity with security and
|
|
2164
|
+
accessibility ESLint plugins. Custom ESLint rules remain a reason to keep ESLint
|
|
2165
|
+
(see craft-agents-oss case study in Appendix G).
|
|
1922
2166
|
|
|
1923
2167
|
5. **Bun workspace strictness**: Bun still uses flat `node_modules` (no
|
|
1924
2168
|
content-addressable store).
|
|
@@ -1931,21 +2175,41 @@ in core library code if the library needs to work in Node.js environments.
|
|
|
1931
2175
|
The open issue ([#5854](https://github.com/oven-sh/bun/issues/5854)) remains tracked.
|
|
1932
2176
|
The `--minify` and `--bytecode` flags help with startup time but not binary size.
|
|
1933
2177
|
|
|
1934
|
-
7.
|
|
1935
|
-
|
|
1936
|
-
|
|
1937
|
-
|
|
1938
|
-
|
|
2178
|
+
7. ~~**TypeScript 6.0**~~: **SHIPPED** 2026-03-23. TypeScript 6.0 is the last
|
|
2179
|
+
JavaScript-based release; `strict: true` is the default; ESM is the default
|
|
2180
|
+
module system; ~9 compiler settings flipped defaults. Currently 6.0.3. Adopt
|
|
2181
|
+
for the codebase as part of the May 2026 currency refresh; review
|
|
2182
|
+
`tsconfig.base.json` for now-redundant flag declarations.
|
|
2183
|
+
|
|
2184
|
+
8. **TypeScript 7.0 (Project Corsa, Go rewrite)**: Beta shipped 2026-04-21 as
|
|
2185
|
+
`@typescript/native-preview` (binary `tsgo`). Claims ~10x type-check speed
|
|
2186
|
+
and ~3x less memory; passes 95%+ of the test suite. Available in
|
|
2187
|
+
Visual Studio 2026 18.6 Insiders by default. **Do not adopt for production
|
|
2188
|
+
builds yet** — wait for stable (expected mid-to-late 2026). May change the
|
|
2189
|
+
DTS generation landscape for Bunup and tsdown once stable.
|
|
1939
2190
|
|
|
1940
|
-
|
|
2191
|
+
9. **Bunup maturity**: Bunup is iterating rapidly (0.16.31 as of May 2026, up from 0.4.x
|
|
1941
2192
|
a few months earlier).
|
|
1942
2193
|
The API surface (`defineConfig`, `defineWorkspace`, `exports`, `compile`) appears
|
|
1943
2194
|
stable, but pin versions carefully.
|
|
1944
2195
|
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
2196
|
+
10. **Bun + Anthropic + Rust rewrite**: Bun was acquired by Anthropic on
|
|
2197
|
+
2025-12-02 (Anthropic's first acquisition) and now powers Claude Code, the
|
|
2198
|
+
Claude Agent SDK, and other Anthropic AI tooling. A full Rust rewrite
|
|
2199
|
+
(~960K lines, generated by Claude agents over ~6 days) merged to `main` on
|
|
2200
|
+
2026-05-14 and passes 99.8% of the test suite. **Bun 1.3.14 is the last
|
|
2201
|
+
Zig-based release.** External API surface (`bun`, `bunx`, `bun install`,
|
|
2202
|
+
`bun test`, `bun build`, `bun --compile`) is unchanged, but watch 1.4.x
|
|
2203
|
+
release notes for migration details. Monitor whether the broader
|
|
2204
|
+
open-source community continues to benefit equally as the codebase
|
|
2205
|
+
integrates more deeply with Anthropic's AI tooling.
|
|
2206
|
+
|
|
2207
|
+
11. **`bun audit`**: Now a documented command
|
|
2208
|
+
([bun.com/docs/pm/cli/audit](https://bun.com/docs/pm/cli/audit)) with
|
|
2209
|
+
`--audit-level=<low|moderate|high|critical>` and `--json` output. Should be
|
|
2210
|
+
a required CI check (see [Supply-Chain Mitigation](#supply-chain-mitigation)).
|
|
2211
|
+
A `bun audit signatures` equivalent to npm's signature verification has not
|
|
2212
|
+
yet shipped — monitor.
|
|
1949
2213
|
|
|
1950
2214
|
* * *
|
|
1951
2215
|
|
|
@@ -2113,10 +2377,10 @@ testing features.
|
|
|
2113
2377
|
},
|
|
2114
2378
|
"dependencies": {},
|
|
2115
2379
|
"devDependencies": {
|
|
2116
|
-
"bun-types": "^1.3.
|
|
2117
|
-
"bunup": "^0.16.
|
|
2118
|
-
"publint": "^0.3.
|
|
2119
|
-
"typescript": "^
|
|
2380
|
+
"bun-types": "^1.3.13",
|
|
2381
|
+
"bunup": "^0.16.31",
|
|
2382
|
+
"publint": "^0.3.20",
|
|
2383
|
+
"typescript": "^6.0.3"
|
|
2120
2384
|
}
|
|
2121
2385
|
}
|
|
2122
2386
|
```
|
|
@@ -2168,10 +2432,10 @@ testing features.
|
|
|
2168
2432
|
"optional-sdk": { "optional": true }
|
|
2169
2433
|
},
|
|
2170
2434
|
"devDependencies": {
|
|
2171
|
-
"bun-types": "^1.3.
|
|
2172
|
-
"bunup": "^0.16.
|
|
2173
|
-
"publint": "^0.3.
|
|
2174
|
-
"typescript": "^
|
|
2435
|
+
"bun-types": "^1.3.13",
|
|
2436
|
+
"bunup": "^0.16.31",
|
|
2437
|
+
"publint": "^0.3.20",
|
|
2438
|
+
"typescript": "^6.0.3"
|
|
2175
2439
|
}
|
|
2176
2440
|
}
|
|
2177
2441
|
```
|
|
@@ -2210,29 +2474,35 @@ testing features.
|
|
|
2210
2474
|
"upgrade:major": "bunx npm-check-updates --target latest --interactive --format group"
|
|
2211
2475
|
},
|
|
2212
2476
|
"devDependencies": {
|
|
2213
|
-
"@biomejs/biome": "^2.
|
|
2214
|
-
"@changesets/cli": "^2.
|
|
2215
|
-
"lefthook": "^2.
|
|
2216
|
-
"npm-check-updates": "^
|
|
2217
|
-
"typescript": "^
|
|
2477
|
+
"@biomejs/biome": "^2.4.14",
|
|
2478
|
+
"@changesets/cli": "^2.31.0",
|
|
2479
|
+
"lefthook": "^2.1.5",
|
|
2480
|
+
"npm-check-updates": "^22.0.0",
|
|
2481
|
+
"typescript": "^6.0.3"
|
|
2218
2482
|
}
|
|
2219
2483
|
}
|
|
2220
2484
|
```
|
|
2221
2485
|
|
|
2222
2486
|
**Notes**:
|
|
2223
2487
|
|
|
2488
|
+
- All pinned versions above are ≥14 days old as of 2026-05-21 per the
|
|
2489
|
+
[Supply-Chain Mitigation](#supply-chain-mitigation) policy. Newer releases
|
|
2490
|
+
may exist (`@biomejs/biome` 2.4.15, `lefthook` 2.1.8, `npm-check-updates`
|
|
2491
|
+
22.2.0) but were too fresh at the time of this document update.
|
|
2224
2492
|
- `"check:ci": "biome ci ."` uses `biome ci` (stricter than `biome check` — errors on
|
|
2225
2493
|
formatting issues)
|
|
2226
2494
|
- `bun run --filter '*' <script>` delegates to each workspace package
|
|
2227
2495
|
- The `@changesets/changelog-github` dependency is optional — use
|
|
2228
2496
|
`"changelog": "@changesets/cli/changelog"` in `.changeset/config.json` for a simpler
|
|
2229
2497
|
built-in changelog generator
|
|
2498
|
+
- `npm-check-updates` v22+ is pure ESM. Add `--cooldown 14` to every invocation per
|
|
2499
|
+
the 14-day package-age rule (see Supply-Chain Mitigation section).
|
|
2230
2500
|
|
|
2231
2501
|
### Appendix C: Complete biome.json Example
|
|
2232
2502
|
|
|
2233
2503
|
```json
|
|
2234
2504
|
{
|
|
2235
|
-
"$schema": "https://biomejs.dev/schemas/2.
|
|
2505
|
+
"$schema": "https://biomejs.dev/schemas/2.4.14/schema.json",
|
|
2236
2506
|
"vcs": {
|
|
2237
2507
|
"enabled": true,
|
|
2238
2508
|
"clientKind": "git",
|