Investigate trimming or patching the transitive sharp + libvips dependency, which libsql-search installs but never uses.
What we carry and why
sharp@0.34.5
└─┬ @huggingface/transformers@4.2.0
└── libsql-search (dependencies)
@huggingface/transformers@4.2.0 declares "sharp": "^0.34.5" in top-level dependencies — not optionalDependencies, not peerDependencies — so every install pulls it regardless of which pipeline is used. This library only calls the text feature-extraction pipeline; nothing in src/ references sharp. Its native backend (@img/sharp-libvips-*) is ~15 MB on darwin-arm64, plus ~600 KB for sharp itself.
4.2.0 is currently npm's latest, so there is no newer release that changes this.
Correcting the audit baseline comment
pnpm-workspace.yaml attributes both ignored GHSAs to "@huggingface/transformers 4.2.0 native runtime deps." Verified against the GitHub Advisory Database and OSV, that is only half right — the two advisories come from two different dependencies:
| GHSA |
Actual package |
Range |
Fixed in |
Reached via |
GHSA-f88m-g3jw-g9cj |
sharp (inherited libvips CVEs) |
< 0.35.0 |
0.35.0 |
transformers → sharp |
GHSA-xcpc-8h2w-3j85 |
adm-zip (CVE-2026-39244) |
< 0.6.0 |
0.6.0 |
transformers → onnxruntime-node@1.24.3 → adm-zip ^0.5.16 |
So GHSA-xcpc-8h2w-3j85 has nothing to do with sharp — it is onnxruntime's transitive ZIP library. The baseline comment should be corrected regardless of what else we do here.
The real blocker is a caret range, not the dependency itself
Both advisories already have published fixes. We cannot reach either one because the intermediate packages pin below them:
sharp fixed in 0.35.0, but transformers requires ^0.34.5 — a caret range that cannot resolve to 0.35.x.
adm-zip fixed in 0.6.0, but onnxruntime-node@1.24.3 requires ^0.5.16.
That reframes this issue. The cheapest win is probably not removing sharp at all — it is forcing both to their patched versions.
Options, in rough order of cost
pnpm.overrides to patched versions. Force sharp to ^0.35.0 and adm-zip to ^0.6.0. If this works, both GHSAs clear and the ignoreGhsas baseline can be deleted entirely — without removing anything or changing what we ship. Needs testing: overriding a native package across a minor is not risk-free, and the local embedding path must still work.
pnpm.overrides to remove sharp outright. pnpm documents overrides: { "pkg>dep": "-" } for dropping a dependency a parent does not need on your code path. Verify the syntax and its caveats directly against pnpm's docs before relying on this — the documentation frames it as "especially useful with optionalDependencies," and sharp here is a hard dependency, so it may behave differently or fail at runtime if any reached code path touches it.
- Wait for upstream. PR huggingface/transformers.js#1731 ("deps: bump onnxruntime-node and sharp") is open and unmerged; it bumps onnxruntime-node to
^1.27.0 and sharp to ^0.35.0, which would fix both advisories at the source. Related: #1729, #1718. Zero effort for us, but no timeline.
- Push upstream for optional sharp. #636 asks for exactly this — "Is it possible to make 'sharp' an optional dependency since it is only needed if used for images." Open since 2024-03-09 with no maintainer commitment. Structurally the right fix, but two years of no traction.
Things ruled out
- Switching package manager does not help. npm, pnpm, yarn, and bun all resolve the same manifests to the same tree. The installer has no say in whether a hard dependency is installed.
onlyBuiltDependencies / ignoredBuiltDependencies do not help with footprint. They control whether install scripts run, not whether a package is installed. Skipping the build avoids compile time and some risk; the bytes stay.
- sharp offers no supported "skip libvips" flag.
SHARP_IGNORE_GLOBAL_LIBVIPS / SHARP_FORCE_GLOBAL_LIBVIPS control how a from-source build sources libvips, not whether the prebuilt binaries install. @img/sharp-wasm32 is an additional package, not a replacement.
Forward-looking note
packageManager is pinned to pnpm@10.34.5. pnpm v11 merges onlyBuiltDependencies / neverBuiltDependencies / ignoredBuiltDependencies into a single allowBuilds map, so the block in pnpm-workspace.yaml will need migrating whenever we upgrade.
Tasks
Investigate trimming or patching the transitive
sharp+libvipsdependency, whichlibsql-searchinstalls but never uses.What we carry and why
@huggingface/transformers@4.2.0declares"sharp": "^0.34.5"in top-leveldependencies— notoptionalDependencies, notpeerDependencies— so every install pulls it regardless of which pipeline is used. This library only calls the text feature-extraction pipeline; nothing insrc/referencessharp. Its native backend (@img/sharp-libvips-*) is ~15 MB on darwin-arm64, plus ~600 KB forsharpitself.4.2.0 is currently npm's
latest, so there is no newer release that changes this.Correcting the audit baseline comment
pnpm-workspace.yamlattributes both ignored GHSAs to "@huggingface/transformers 4.2.0 native runtime deps." Verified against the GitHub Advisory Database and OSV, that is only half right — the two advisories come from two different dependencies:GHSA-f88m-g3jw-g9cjsharp(inherited libvips CVEs)< 0.35.0GHSA-xcpc-8h2w-3j85adm-zip(CVE-2026-39244)< 0.6.0^0.5.16So
GHSA-xcpc-8h2w-3j85has nothing to do with sharp — it is onnxruntime's transitive ZIP library. The baseline comment should be corrected regardless of what else we do here.The real blocker is a caret range, not the dependency itself
Both advisories already have published fixes. We cannot reach either one because the intermediate packages pin below them:
sharpfixed in 0.35.0, but transformers requires^0.34.5— a caret range that cannot resolve to 0.35.x.adm-zipfixed in 0.6.0, but onnxruntime-node@1.24.3 requires^0.5.16.That reframes this issue. The cheapest win is probably not removing sharp at all — it is forcing both to their patched versions.
Options, in rough order of cost
pnpm.overridesto patched versions. Forcesharpto^0.35.0andadm-zipto^0.6.0. If this works, both GHSAs clear and theignoreGhsasbaseline can be deleted entirely — without removing anything or changing what we ship. Needs testing: overriding a native package across a minor is not risk-free, and the local embedding path must still work.pnpm.overridesto remove sharp outright. pnpm documentsoverrides: { "pkg>dep": "-" }for dropping a dependency a parent does not need on your code path. Verify the syntax and its caveats directly against pnpm's docs before relying on this — the documentation frames it as "especially useful withoptionalDependencies," and sharp here is a hard dependency, so it may behave differently or fail at runtime if any reached code path touches it.^1.27.0and sharp to^0.35.0, which would fix both advisories at the source. Related: #1729, #1718. Zero effort for us, but no timeline.Things ruled out
onlyBuiltDependencies/ignoredBuiltDependenciesdo not help with footprint. They control whether install scripts run, not whether a package is installed. Skipping the build avoids compile time and some risk; the bytes stay.SHARP_IGNORE_GLOBAL_LIBVIPS/SHARP_FORCE_GLOBAL_LIBVIPScontrol how a from-source build sources libvips, not whether the prebuilt binaries install.@img/sharp-wasm32is an additional package, not a replacement.Forward-looking note
packageManageris pinned topnpm@10.34.5. pnpm v11 mergesonlyBuiltDependencies/neverBuiltDependencies/ignoredBuiltDependenciesinto a singleallowBuildsmap, so the block inpnpm-workspace.yamlwill need migrating whenever we upgrade.Tasks
task-1- Correct theignoreGhsascomment to attribute each GHSA to its real packagetask-2- Testpnpm.overridesforcingsharp@^0.35.0andadm-zip@^0.6.0; confirm local embeddings still passtask-3- If overrides clear both advisories, remove theignoreGhsasbaselinetask-4- Evaluate whether removing sharp viaoverrides"-"is viable and safe for a hard dependencytask-5- Track upstream PR #1731; drop local workarounds if it mergestask-6- Remove Transformers.js dependency and local embedding providertask-7- Require explicit external provider selection and update tests/docstask-8- Regenerate lockfile and prove the native dependency chain is gonetask-9- Run full validation and confirm the breaking 0.x release plan