K.

Back to Case Studies
Engineering
Oct 12, 2024

Bazaruto: Optimizing Performance via Library Migration

"Future-proofing a complex safari booking platform by migrating from the deprecated Moment.js to a modern, lightweight alternative."

-45kB

Bundle Size

15%

TTI Improvement

High

Risk Mitigation

As web applications grow, the cost of dependencies becomes a significant factor in performance and long-term maintainability. For Bazaruto, we faced a dual challenge: our primary date library, Moment.js, was contributing significantly to our JavaScript bundle size and, more critically, had been officially deprecated (moving into maintenance mode) by its maintainers.

The Challenge: Legacy Risk & Performance

Bazaruto's booking engine relies heavily on complex date calculations: seasonal pricing, availability checks, and multi-timezone itinerary drafts. Using a deprecated library meant we were accumulating technical debt and missing out on modern optimizations like tree-shaking.

The Solution: Selecting Day.js

We chose Day.js as the replacement. Day.js shares a nearly identical API with Moment.js but is a fraction of the weight (2kB vs 70kB+). To bridge the gap in specialized functionality, we implemented a custom date-utils.ts wrapper that extended Day.js with several essential plugins:

  • UTC and AdvancedFormat for global traveler coordination.
  • IsSameOrBefore, IsSameOrAfter, and IsBetween for precise availability logic.
  • Duration and RelativeTime for user-friendly itinerary displays.

The Strategy: Incremental Strangling

We didn't perform a "big bang" replacement. Instead:

  1. Centralized Wrapper: We created a centralized date-utils.ts that abstracted all date operations.
  2. Dual-Dependency Phase: For a short period, both libraries co-existed. New features used the Day.js wrapper, while legacy components were moved over function-by-function.
  3. Exhaustive Testing: We mirrored our Moment.js unit tests for the new Day.js implementation to ensure parity in obscure edge cases (e.g., leap years, DST transitions).

Results

The migration was a resounding success. We reduced our total JavaScript bundle size by 45kB (gzip) and improved the initial page load time on mobile devices. Most importantly, we removed a major piece of legacy risk by moving to a modern, actively maintained foundation.

The Challenge

Moment.js was officially deprecated and entered maintenance mode, creating a long-term maintenance risk. Additionally, its monolithic size was bloating the Bazaruto bundle and slowing down mobile page loads.

Our Approach

Implemented an incremental migration strategy to replace the deprecated Moment.js with Day.js. Developed a specialized `date-utils.ts` utility layer to maintain API parity and ensure zero regressions across complex booking logic.

Measurable Impact

Eliminated legacy risk by migrating away from a deprecated library.

Successfully replaced Moment.js with Day.js across 100+ components.

Reduced bundle size by 45kB gzip, significantly improving Time to Interactive (TTI).

Established a standardized, plugin-oriented date utility library with full TypeScript support.

Maintained 100% logic parity verified through a comprehensive parallel test suite.

Stack Architecture

ReactTypeScriptDay.jsMoment.jsJest

"Future-proofed the codebase by removing deprecated dependencies and reduced JS bundle size by 45kB."

Senior Engineering Impact