5.9 KiB
Bun Analyzer Developer Gotchas
This document covers common pitfalls and considerations when working with the Bun analyzer.
1. Isolated Installs Are Symlink-Heavy
Bun's isolated linker (bun install --linker isolated) creates a flat store under node_modules/.bun/ with symlinks for package resolution. This differs from the default hoisted layout.
Implications:
- The analyzer must traverse
node_modules/.bun/**/package.jsonin addition tonode_modules/**/package.json - Symlink safety guards are critical to prevent infinite loops and out-of-root traversal
- Both logical and real paths are recorded in evidence for traceability
- Performance guards (
MaxSymlinkDepth=10,MaxFilesPerRoot=50000) are enforced
Testing:
- Use the
IsolatedLinkerInstallIsParsedAsynctest fixture to verify.bun/traversal - Use the
SymlinkSafetyIsEnforcedAsynctest fixture for symlink corner cases
2. node_modules/.bun/ Scanning Requirement
Unlike Node.js, Bun may store packages entirely under node_modules/.bun/ with only symlinks in the top-level node_modules/. If your scanner configuration excludes .bun/ directories, you will miss dependencies.
Checklist:
- Ensure glob patterns include
.bun/subdirectories - Do not filter out hidden directories in container scans
- Verify evidence shows packages from both
node_modules/andnode_modules/.bun/
3. bun.lockb Policy (2025-12-09)
The binary lockfile (bun.lockb) remains unsupported. We will not parse it and will keep remediation-only handling until Bun publishes a stable, documented format.
Posture:
- Treat
bun.lockbas unsupported input; do not attempt best-effort parsing. - Emit a deterministic remediation finding instructing conversion to text.
- Skip package inventory when only
bun.lockbis present to avoid nondeterministic/partial results.
Migration command (required):
bun install --save-text-lockfile
This generates bun.lock (JSONC text format) which the analyzer parses.
WebService response when only bun.lockb exists:
- Scan completes with
unsupportedmarker for the package manager. - Remediation guidance is included in findings.
- No package inventory is generated until
bun.lockis provided.
4. JSONC Lockfile Format
bun.lock uses JSONC (JSON with Comments) format supporting:
- Single-line comments (
// ...) - Multi-line comments (
/* ... */) - Trailing commas in arrays and objects
Parser considerations:
- The
BunLockParsertolerates these JSONC features - Standard JSON parsers will fail on
bun.lockfiles - Format may evolve with Bun releases; parser is intentionally tolerant
5. Multi-Stage Build Implications
In multi-stage Docker builds, the final image may contain only production artifacts without the lockfile or node_modules/.bun/ directory.
Scanning strategies:
- Image scanning (recommended for production): Scans the final image filesystem. Set
include_dev: falseto filter dev dependencies - Repository scanning: Scans
bun.lockfrom source. Includes all dependencies by default (include_dev: true)
Best practice: Scan both the repository (for complete visibility) and production images (for runtime accuracy).
6. npm Ecosystem Reuse
Bun packages are npm packages. The analyzer:
- Emits
pkg:npm/<name>@<version>PURLs (same as Node analyzer) - Uses
ecosystem = npmfor vulnerability lookups - Adds
package_manager = bunmetadata for differentiation
This means:
- Vulnerability intelligence is shared with Node analyzer
- VEX statements for npm packages apply to Bun
- No separate Bun-specific advisory database is needed
7. Source Detection in Lockfile
bun.lock entries include source information that determines package type:
| Source Pattern | Type | Example |
|---|---|---|
| No source / default registry | registry |
lodash@4.17.21 |
git+https://... or git://... |
git |
VCS dependency |
file: or link: |
tarball |
Local package |
workspace: |
workspace |
Monorepo member |
The analyzer records source type in evidence for provenance tracking.
8. Workspace/Monorepo Handling
Bun workspaces use a single bun.lock at the root with multiple package.json files in subdirectories.
Analyzer behavior:
- Discovers the root by presence of
bun.lock+package.json - Traverses all
node_modules/directories under the root - Deduplicates packages by
(name, version)while accumulating occurrence paths - Records workspace member paths in metadata
Testing: Use the WorkspacesAreParsedAsync test fixture.
9. Dev/Prod Dependency Filtering
The include_dev configuration option controls whether dev dependencies are included:
| Context | Default include_dev |
Rationale |
|---|---|---|
| Repository scan (lockfile-only) | true |
Full visibility for developers |
| Image scan (installed packages) | true |
Packages are present regardless of intent |
Override: Set include_dev: false in scan configuration to exclude dev dependencies from results.
10. Evidence Model
Each Bun package includes evidence with:
source: Where the package was found (node_modules,bun.lock,node_modules/.bun)locator: File path to the evidenceresolved: The resolved URL from lockfile (if available)integrity: SHA hash from lockfile (if available)sha256: File hash for installed packages
Evidence enables:
- Tracing packages to their origin
- Validating integrity
- Explaining presence in SBOM
CLI Reference
Inspect local workspace
stellaops-cli bun inspect --root /path/to/project
Resolve packages from scan
stellaops-cli bun resolve --scan-id <id>
stellaops-cli bun resolve --digest sha256:<hash>
stellaops-cli bun resolve --ref myregistry.io/myapp:latest
Output formats
stellaops-cli bun inspect --format json > packages.json
stellaops-cli bun inspect --format table