Skip to content

Trim or patch the unused transitive sharp/libvips dependency #51

Description

@llbbl

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

  1. 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.
  2. 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.
  3. 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.
  4. 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

  • task-1 - Correct the ignoreGhsas comment to attribute each GHSA to its real package

  • task-2 - Test pnpm.overrides forcing sharp@^0.35.0 and adm-zip@^0.6.0; confirm local embeddings still pass

  • task-3 - If overrides clear both advisories, remove the ignoreGhsas baseline

  • task-4 - Evaluate whether removing sharp via overrides "-" is viable and safe for a hard dependency

  • task-5 - Track upstream PR #1731; drop local workarounds if it merges

  • task-6 - Remove Transformers.js dependency and local embedding provider

  • task-7 - Require explicit external provider selection and update tests/docs

  • task-8 - Regenerate lockfile and prove the native dependency chain is gone

  • task-9 - Run full validation and confirm the breaking 0.x release plan

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions