Skip to content

ADR-20250606: Migration from Lodash to ES-Toolkit

Status

Accepted

Date

2025-06-06

Context

The monorepo was using Lodash as the primary utility library for JavaScript/TypeScript operations such as object manipulation, array operations, and functional programming utilities. However, Lodash has several drawbacks in modern development:

  1. Bundle Size: Lodash is relatively large and can contribute significantly to bundle size, even with tree-shaking
  2. Performance: Some Lodash functions are not optimized for modern JavaScript engines
  3. Modern JavaScript: Many Lodash utilities are now superseded by native JavaScript methods (ES2015+)
  4. Type Safety: While @types/lodash exists, it's not always perfectly aligned with TypeScript best practices

We needed a modern, performant, and tree-shakable utility library that provides:

  • Better TypeScript support out of the box
  • Smaller bundle size impact
  • Modern JavaScript optimizations
  • Compatibility with existing utility patterns

Decision

We have decided to migrate from Lodash to ES-Toolkit as our primary utility library.

ES-Toolkit is a modern JavaScript utility library that provides:

  • High Performance: Optimized for modern JavaScript engines with 2-3x better performance than Lodash
  • Small Bundle Size: Significantly smaller footprint with excellent tree-shaking
  • TypeScript First: Built with TypeScript and provides excellent type safety
  • Modern JavaScript: Leverages modern JavaScript features and patterns
  • Comprehensive: Covers most common utility functions needed in modern development

Key Benefits of ES-Toolkit:

  1. Performance: 2-3x faster than Lodash in most operations
  2. Bundle Size: ~97% smaller than Lodash (when tree-shaken)
  3. TypeScript: Native TypeScript support with excellent type inference
  4. Modern: Uses modern JavaScript features and follows current best practices
  5. Tree-Shakable: Excellent tree-shaking support for minimal bundle impact
  6. API Compatibility: Similar API patterns to Lodash, making migration straightforward

Consequences

Positive:

  • Improved Performance: Applications will run faster due to optimized utility functions
  • Reduced Bundle Size: Smaller JavaScript bundles leading to faster load times
  • Better TypeScript Experience: More accurate types and better IDE support
  • Future-Proof: Built on modern JavaScript standards and maintained actively
  • Developer Experience: More predictable behavior and better error messages

Negative:

  • Migration Effort: Required updating imports and potentially some function calls across the codebase
  • Learning Curve: Developers need to familiarize themselves with ES-Toolkit API (though it's similar to Lodash)
  • Ecosystem: Smaller ecosystem compared to Lodash (though this is improving)

Migration Impact:

  • All Lodash imports have been replaced with ES-Toolkit equivalents
  • Function calls that differ between libraries have been updated
  • Type definitions updated to use ES-Toolkit types
  • Build processes updated to optimize for ES-Toolkit's tree-shaking

Alternatives Considered

1. Ramda

  • Pros: Functional programming focused, immutable by default
  • Cons: Different API paradigm, larger learning curve, similar bundle size issues

2. Remeda

  • Pros: TypeScript first, good performance
  • Cons: Smaller function library, less mature ecosystem

3. Native JavaScript Only

  • Pros: No dependencies, guaranteed compatibility
  • Cons: Missing many useful utilities, would require custom implementations

4. Keep Lodash

  • Pros: No migration effort, familiar API
  • Cons: Performance and bundle size issues remain, less optimal TypeScript support

Implementation Guidelines

Import Patterns:

// Old (Lodash)
import _ from 'lodash';
import { debounce, throttle } from 'lodash';

// New (ES-Toolkit)
import { debounce, throttle, isEqual, cloneDeep } from 'es-toolkit';

Common Function Mappings:

  • _.isEqual()isEqual()
  • _.cloneDeep()cloneDeep()
  • _.debounce()debounce()
  • _.throttle()throttle()
  • _.pick()pick()
  • _.omit()omit()

Performance Sensitive Areas:

Focus ES-Toolkit usage in:

  • Real-time data processing (orderbook, websockets)
  • Frequent utility operations (validation, transformation)
  • Client-side bundle-size sensitive areas

References