한국어 | English | 中文 | Español | 日本語
Slim bundles with precision.
Legolas is a Rust-powered CLI, distributed through npm with native binaries, for finding bundle-weight problems in modern web projects. It combines source-import analysis, lockfile inspection, optional bundle-artifact evidence, budget gates, and machine-readable output so optimization work can move from local triage to CI.
- Framework and project shape for Next.js, Vite, Webpack, Rollup, Astro, Nuxt, React, Vue, and Svelte projects
- Static and dynamic imports in JavaScript, TypeScript, JSX, TSX, Vue, and Svelte files
- Heavy client dependencies such as charting, editor, icon, SDK, animation, map, monitoring, and UI packages
- Duplicate package versions from npm, pnpm, and Yarn lockfiles
- Tree-shaking risks, including broad icon imports, root utility imports, and repeated locale subpath imports
- Lazy-loading opportunities on route-like, dashboard, modal, editor, map, and chart surfaces
- Server/client boundary warnings for patterns such as browser surfaces importing Node-only modules
- Bundle artifacts when present, including Webpack
stats.jsonand esbuild/Rollupmeta.jsonfiles in known locations
Legolas estimates savings directionally. Treat the numbers as prioritization signals, then confirm production impact with your own bundle analyzer and performance telemetry.
Run without adding a dependency:
npx @jeremyfellaz/legolas scan .
npx @jeremyfellaz/legolas visualize .
npx @jeremyfellaz/legolas optimize .Or install it in a project:
npm install -D @jeremyfellaz/legolas
npx legolas scan .The npm package requires Node.js >=18.17 and ships prebuilt Rust binaries for macOS arm64/x64, Linux x64 with glibc, and Windows x64.
| Command | Purpose | Common options |
|---|---|---|
scan |
Full analysis report with dependency, lockfile, import, artifact, and boundary findings | [path], --config, --lang ko|en, --json, --sarif, --write-baseline, --baseline, --regression-only |
visualize |
Text bars for estimated dependency weight and duplicate package pressure | [path], --config, --lang ko|en, --limit |
optimize |
Ranked action list with difficulty, confidence, target files, and suggested fixes | [path], --config, --lang ko|en, --top, --json, --baseline, --regression-only |
budget |
Evaluates bundle-health budget rules | [path], --config, --lang ko|en, --json, --baseline, --regression-only |
ci |
CI-oriented budget gate that exits with code 1 on failures |
[path], --config, --lang ko|en, --json, --sarif, --baseline, --regression-only |
Help and text reports default to Korean. Pass --lang en for English output. Use legolas help --lang en for English command help.
npx @jeremyfellaz/legolas help --lang enScan an app:
npx @jeremyfellaz/legolas scan ./apps/storefront --lang enGet JSON for automation:
npx @jeremyfellaz/legolas scan ./apps/storefront --json --lang enUpload SARIF from a scan-capable workflow:
npx @jeremyfellaz/legolas scan ./apps/storefront --sarif --lang enCreate and compare a baseline:
npx @jeremyfellaz/legolas scan ./apps/storefront --write-baseline ./legolas-baseline.json --json --lang en
npx @jeremyfellaz/legolas scan ./apps/storefront --baseline ./legolas-baseline.json --regression-only --json --lang enFail CI on budget regressions:
npx @jeremyfellaz/legolas ci ./apps/storefront --baseline ./legolas-baseline.json --regression-only --sarif --lang enLegolas automatically discovers legolas.config.json from the project root. You can also pass a file explicitly with --config.
{
"scan": {
"path": "src",
"ignorePatterns": ["generated/**", "!generated/keep.ts"]
},
"visualize": {
"limit": 12
},
"optimize": {
"top": 7
},
"budget": {
"rules": {
"potentialKbSaved": {
"warnAt": 40,
"failAt": 80
},
"duplicatePackageCount": {
"warnAt": 2,
"failAt": 4
},
"dynamicImportCount": {
"warnAt": 1,
"failAt": 0
}
}
}
}Source scanning also honors the project's .gitignore and root .legolasignore. scan.ignorePatterns uses POSIX-style path patterns relative to the resolved project root and supports ! exception patterns like .gitignore.
potentialKbSaved and duplicatePackageCount are maximum-style rules: higher actual values are worse. dynamicImportCount is a minimum-style rule: too few dynamic imports can warn or fail.
scan --jsonandoptimize --jsonemitlegolas.analysis.v1, documented by docs/schema/analysis.v1.schema.json.budget --jsonemitslegolas.budget.v1, documented by docs/schema/budget.v1.schema.json.ci --jsonemitslegolas.ci.v1, documented by docs/schema/ci.v1.schema.json.scan --sarifandci --sarifemit SARIF2.1.0, documented by docs/schema/sarif.v1.json.
JSON output includes a top-level reportSummary. SARIF output carries the same summary at runs[0].properties.reportSummary. The summary includes language, verdictKey, confirmedInitialPayloadKbSaved, directionalOpportunityKb, estimatedLcpImprovementMs, and topActions.
--json and --sarif are mutually exclusive. ci returns a non-zero exit code when budget rules fail.
Use --lang en when you want English human-readable output. scan summarizes the project, verdict, confirmed initial payload savings, directional cleanup opportunity, next actions, evidence, and finding groups:
Legolas scan for basic-parity-app
Project root: <PROJECT_ROOT>
Mode: heuristic
Frameworks: Vite, React
Package manager: pnpm
Scanned 1 source files and 4 imported packages
Verdict: high impact
Confirmed initial payload savings: ~348 KB (estimated LCP improvement ~731 ms)
Directional cleanup opportunity: ~366 KB
Top next actions:
1. Review chart.js upfront bundle weight [hard | high confidence | ~160 KB]
recommended fix: lazy-load - Register only the chart primitives you use and lazy load dashboard surfaces.
targets: src/Dashboard.tsx
evidence: src/Dashboard.tsx | specifier: chart.js | static import; Charting code is often only needed on a subset of screens.
2. Lazy load chart.js [medium | low confidence | ~120 KB]
evidence: src/Dashboard.tsx | specifier: chart.js | route-like UI surface matched `dashboard` keyword
Heaviest known dependencies:
- chart.js (160 KB) [high confidence]: Charting code is often only needed on a subset of screens. imported in 1 file(s).
Confirmed initial payload savings sums only findings with source-import or bundle-artifact evidence for initial payload impact. Lockfile-only duplication is not counted in that confirmed/LCP number; it is treated as a Directional cleanup opportunity dependency-hygiene signal. Development/test-only duplicates are also presented as dependency-hygiene cleanup work, not as LCP improvement.
optimize turns findings into ranked actions:
Legolas optimize for basic-parity-app
1. Review chart.js upfront bundle weight [hard | high confidence | ~160 KB]
recommended fix: lazy-load - Register only the chart primitives you use and lazy load dashboard surfaces.
targets: src/Dashboard.tsx
evidence: src/Dashboard.tsx | specifier: chart.js | static import; Charting code is often only needed on a subset of screens.
budget reports pass, warn, or fail for each rule:
Legolas budget for basic-parity-app
Overall status: Fail
Rule results:
- potentialKbSaved: Fail (actual: 348, warnAt: 40, failAt: 80)
- duplicatePackageCount: Pass (actual: 1, warnAt: 2, failAt: 4)
- dynamicImportCount: Fail (actual: 0, warnAt: 1, failAt: 0)
cargo run -p legolas-cli -- help
cargo test --workspaceContributor workflows use cargo run -p legolas-cli -- ... as the source of truth. The npm package wraps the compiled Rust binary from vendor/<triple>/legolas[.exe]. When release packaging has staged those vendor binaries, validate the package layout with npm run pack:check.
- License: MIT
- Contributing guide: CONTRIBUTING.md
- Code of Conduct: CODE_OF_CONDUCT.md
- Security policy: SECURITY.md
- Sponsor: GitHub Sponsors