Skip to content

fix(ts-templates): allow esbuild + unrs-resolver install scripts for tsx#831

Draft
DaveHanns wants to merge 1 commit into
masterfrom
fix/f62-trusted-deps-tsx
Draft

fix(ts-templates): allow esbuild + unrs-resolver install scripts for tsx#831
DaveHanns wants to merge 1 commit into
masterfrom
fix/f62-trusted-deps-tsx

Conversation

@DaveHanns

Copy link
Copy Markdown
Contributor

Summary

npm 11 introduced an allowlist for dependency lifecycle scripts. Freshly scaffolded TypeScript templates run tsx src/main.ts (via npm start / apify run), and tsx depends transitively on esbuild, whose native binary is fetched by a postinstall script. Under npm 11+ that script is silently skipped, so tsx fails at runtime.

This PR adds a two-entry trustedDependencies allowlist to every ts-* template so esbuild and unrs-resolver are permitted to run their install scripts.

Reproduction (before this PR)

$ apify create my-actor -t ts-empty
$ cd my-actor
$ npm install
...
npm warn allow-scripts   esbuild@0.28.1 (postinstall: node install.js)
npm warn allow-scripts   unrs-resolver@1.12.2 (postinstall: node postinstall.js)
...
$ npm start
> tsx src/main.ts
node:internal/modules/esm/resolve:... Cannot find package 'esbuild/bin/esbuild' ...

The obvious workaround (npm approve-scripts esbuild unrs-resolver) does not work on a fresh install — the packages have not yet been installed, so approve-scripts errors out:

npm error code ENOMATCH
npm error No installed packages match: esbuild, unrs-resolver

That produces a chicken-and-egg situation where the user has to run npm install twice (once with --ignore-scripts=false after manual approval, etc.), which is friction they should not have to discover.

Fix

Add to each templates/ts-*/package.json:

"trustedDependencies": [
    "esbuild",
    "unrs-resolver"
]

This is npm 11's opt-in mechanism for pre-approving lifecycle scripts of specific packages. It is inert on older npm versions (which already run all install scripts by default), so it is safe for the templates' engines.node: >=18 support range.

Applied to all 14 templates that ship tsx:

  • ts-beeai-agent
  • ts-bootstrap-cheerio-crawler
  • ts-crawlee-cheerio
  • ts-crawlee-playwright-camoufox
  • ts-crawlee-playwright-chrome
  • ts-crawlee-puppeteer-chrome
  • ts-empty
  • ts-mastraai
  • ts-mcp-empty
  • ts-mcp-proxy
  • ts-playwright-test-runner
  • ts-standby
  • ts-start
  • ts-start-bun

Test plan

  • apify create tmp -t ts-empty && cd tmp && npm install completes without any npm warn allow-scripts lines for esbuild / unrs-resolver.
  • node_modules/esbuild/bin/esbuild --version works.
  • apify run (or npm start) launches without tsx erroring on missing esbuild binary.
  • Verify no regression on npm 10 (trustedDependencies is ignored there).

Follow-up (not in this PR)

Once base images track Node 22+ / 24+, start:dev could migrate from tsx to node --experimental-strip-types src/main.ts and drop the tsx + esbuild dependency chain entirely.

Surfaced during an evaluation of Apify surfaces for agent-driven Actor development.

npm 11 introduced an allowlist gate for dependency lifecycle scripts. When a
freshly scaffolded TypeScript template is installed with npm 11+, npm skips
the postinstall scripts of `esbuild` (a transitive dependency of `tsx`) and
`unrs-resolver`, printing:

    npm warn allow-scripts   esbuild@... (postinstall: node install.js)
    npm warn allow-scripts   unrs-resolver@... (postinstall: node postinstall.js)

esbuild's postinstall is what downloads its native binary, so skipping it
leaves `node_modules/esbuild/bin/esbuild` missing and any `tsx src/main.ts`
run (including `npm start` / `apify run`) fails. The obvious remedy
(`npm approve-scripts esbuild unrs-resolver`) does not work on a fresh
install because the packages are not yet installed:

    npm error code ENOMATCH
    npm error No installed packages match: esbuild, unrs-resolver

Declaring `trustedDependencies` in package.json opts these two packages
into running their install scripts, which is exactly what a working `tsx`
requires. This is applied to every `ts-*` template that ships `tsx`.

Surfaced during an evaluation of Apify surfaces for agent-driven Actor development.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@DaveHanns DaveHanns requested a review from l2ysho as a code owner July 4, 2026 22:51
@DaveHanns DaveHanns marked this pull request as draft July 5, 2026 11:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants