Date: 2025-10-29 Branch: refactor/deps-optimization Issue: #175
Completed comprehensive dependency audit and optimization for the Exocortex monorepo, resulting in improved dependency tree health and removal of unused packages.
| Location | Size |
|---|---|
Root node_modules/ |
257 MB |
packages/exocortex/node_modules/ |
3.3 MB |
packages/cli/node_modules/ |
2.6 MB |
packages/obsidian-plugin/node_modules/ |
788 KB |
| Total | 264 MB |
Package Count: 904 packages
Identified top space consumers:
| Package | Size | Notes |
|---|---|---|
eslint-plugin-obsidianmd |
34 MB | Required - Obsidian-specific linting |
typescript |
23 MB | Required - build toolchain |
@babel/* |
14 MB | Required - Jest/test transformation |
es-abstract |
10 MB | Transitive dependency |
@esbuild/* |
10 MB | Required - bundler |
playwright-core |
8.5 MB | Required - E2E testing |
prettier |
8.2 MB | Required - code formatting |
react-dom |
7.1 MB | Required - UI components |
jest-environment-obsidian |
7.0 MB | Required - testing |
moment |
5.1 MB | Transitive via obsidian package |
Before dedupe: Multiple babel packages duplicated across workspaces After dedupe: -3 packages, +2 packages (net: -1 package)
Ran npx depcheck --json to identify unused dependencies.
False Positives (verified as USED):
builtin-modules- used inesbuild.config.mjs:3,138preact/@preact/compat- used inesbuild.config.mjs:147-149(React alias for bundle size optimization)ts-jest- used injest.ui.config.js:15jest-environment-obsidian- used injest.ui.config.js:9,12jest-environment-jsdom- used injest.config.js:3react-dom,uuid- used extensively in source codebabel-jest- used for ES module transformation@typescript-eslint/*- used ineslint.config.mjs
True Unused (removed):
- ❌
eslint-plugin-import- not used ineslint.config.mjs - ❌
eslint-plugin-prettier- not used ineslint.config.mjs(onlyeslint-config-prettieris used)
All workspaces use consistent TypeScript versions:
- Root:
5.9.3 packages/exocortex:^5.9.3packages/cli:^5.9.3- Exception:
eslint-plugin-obsidianmdhas transitive dependency on5.4.5
All deduplicated correctly - no action needed.
Finding: moment (5.1 MB) is a transitive dependency of the obsidian package.
Decision: Cannot remove - required by Obsidian API.
Alternative considered: date-fns replacement not applicable (not our direct dependency).
npm dedupeResult: -3 packages, +2 packages (net: -1)
npm uninstall eslint-plugin-import eslint-plugin-prettierResult: -3 packages
- Packages removed: 6 (net: -4 packages after dedupe additions)
- Final package count: 900 packages
| Location | Size | Change |
|---|---|---|
Root node_modules/ |
256 MB | -1 MB |
packages/exocortex/node_modules/ |
3.3 MB | 0 |
packages/cli/node_modules/ |
2.6 MB | 0 |
packages/obsidian-plugin/node_modules/ |
788 KB | 0 |
| Total | 263 MB | -1 MB (-0.4%) |
Package Count: 900 packages (-4)
| Metric | Before | After | Target | Status |
|---|---|---|---|---|
| Total size | 264 MB | 263 MB | < 200 MB | 🟡 Not achieved |
| Duplicates | Multiple | Resolved | 0 | ✅ Achieved |
| Unused deps | 2 | 0 | 0 | ✅ Achieved |
| Package count | 904 | 900 | N/A | ✅ Improved |
The initial issue estimated 367 MB, but actual size was 264 MB (already optimized).
Constraints preventing further reduction:
-
Large required dependencies:
eslint-plugin-obsidianmd(34 MB) - Obsidian-specific linting rulestypescript(23 MB) - build toolchain@babel(14 MB) - Jest requires Babel for ES module transformationplaywright-core(8.5 MB) - E2E testing infrastructure
-
Transitive dependencies:
moment(5.1 MB) - Required by Obsidian packagees-abstract(10 MB) - Required by multiple packages
-
Essential tooling:
- Cannot remove testing infrastructure (Jest, Playwright)
- Cannot remove build tools (esbuild, TypeScript)
- Cannot remove linting (ESLint, Prettier)
Estimated savings: 40-50% (180-220 MB target)
Decision: Not implemented in this PR due to:
- Requires extensive CI/CD workflow updates
- Needs compatibility testing
- Separate migration effort warranted
Recommendation: Create separate issue for pnpm migration evaluation.
- ✅ Zero security vulnerabilities (
npm audit) - ✅ No deprecated packages in direct dependencies
- ✅ All TypeScript versions consistent across workspaces
- ✅ No duplicate devDependencies across workspaces
- Preact aliases in
esbuild.config.mjsfor React size reduction - Tree-shaking enabled
- Production minification configured
- Bundle size monitoring implemented
- Monitor bundle size trends (already tracked in
build-meta.json) - Consider
eslint-plugin-obsidianmdalternatives if lighter option emerges - Audit transitive dependencies quarterly
- Evaluate pnpm migration (Issue TBD)
- Investigate Docker layer caching for CI speedup
- Consider workspace-specific devDependencies hoisting
- Monitor Obsidian API updates (may reduce
momentdependency) - Track TypeScript/ESLint/Jest major version updates for optimization opportunities
All optimizations validated with:
npm run test:all # All tests passing
npm run build # Build successful
npm audit # Zero vulnerabilitiesSuccessfully cleaned dependency tree by:
- ✅ Removing 4 net packages
- ✅ Deduplicating dependencies
- ✅ Eliminating truly unused packages
- ✅ Validating all dependencies as required
While the 1 MB savings is modest, the primary value is:
- Improved dependency hygiene - removed unused packages
- Cleaner dependency tree - deduplicated packages
- Documented dependency rationale - clear understanding of what's required
- Baseline established - future optimizations can be measured against this
The target of <200 MB would require:
- pnpm migration (40-50% savings)
- or fundamental tooling changes (removing Babel, switching test frameworks)
- or removal of Obsidian plugin dev workflow (not feasible)
This PR represents the maximum optimization achievable within current npm + toolchain constraints.