mmntjs
Compatibility-first migration bridge away from moment.js

Migration

Roll out in stages, not in hope.

This page is for teams that need a realistic adoption path: evaluate first, replace in a small surface, compare behavior, then expand with confidence.

CLI Migration Tool

The mmntjs CLI automates the mechanical part of migration: scanning source files, rewriting import paths, and generating a report to make rollout decisions visible.

# Scan first, then apply
mmntjs migrate --check
mmntjs migrate --apply
mmntjs migrate --check [dir]
Scans source files and reports how many moment imports can be automatically rewritten.
mmntjs migrate --apply [dir]
Rewrites all detected moment import paths to mmntjs in place.
mmntjs report [dir]
Generates a MIGRATION.md with usage statistics, API breakdown, and Temporal-readiness estimate.
mmntjs audit [dir]
Analyzes moment usage patterns and flags risky APIs for manual review.
mmntjs stats [dir]
Prints a quick summary of moment usage count and Temporal-ready percentage to the terminal.

Migration Overview

The safest way to adopt mmntjs is to treat it as a compatibility bridge first and an optimization or modernization step second. Teams usually get better results by reducing the migration surface one ownership boundary at a time instead of attempting a global swap.

A good migration plan also makes room for the possibility that a few modules should stay on moment.js longer than others. That is not failure. It is a controlled rollout doing its job.

Staged Rollout

Phase 0

Inventory current moment usage and identify timezone, locale, and parsing hotspots.

Phase 1

Run compatibility checks and review known differences for the APIs your codebase uses.

Phase 2

Replace imports in a low-risk module or service and run the existing test suite.

Phase 3

Compare production-like behavior, especially invalid dates, offsets, and custom parsing.

Phase 4

Expand rollout module by module with ownership and rollback clarity.

Phase 5

Use the bridge period to guide new code toward modern date/time APIs, including Temporal where it fits.

Migration Approaches by Build Tool

mmntjs supports three migration patterns. Which one works best depends on your package manager and test runner.

Approachnpm / yarnpnpmJest / webpackvitestbun
A: npm alias
"moment": "npm:mmntjs"
Works with one dependency alias. Use root overrides when workspace resolution needs to be forced.
"moment": "link:../mmntjs/dist"
Works; pool: threads is recommended.
B: Migration tool rewrite
mmntjs migrate --apply
C: Preload alias
Module._resolveFilename hook
Works with one setup file. Use root overrides plus link:. Works. Use pool: threads; forks can fail to inherit resolution. Use --preload.

pnpm + vitest notes from a real Ghost trial

Migration to Temporal

The report shows you where Temporal is already an option.

mmntjs report analyzes each file and estimates how many moment usages can be expressed directly with Temporal APIs. That number is not a migration promise; it is a signal for which modules are worth evaluating for a Temporal path first.

mmntjs report .
Generate a migration report that shows which moment usages are Temporal-ready.
Review the Temporal-ready count and API breakdown.
Focus on simple parse, format, add, diff calls that can be expressed directly in Temporal.
Use mmntjs as the bridge.
Keep existing moment-shaped code on mmntjs while writing new modules directly against Temporal APIs.
Expand incrementally.
The report makes it visible whether a module's moment usage is simple enough for a future Temporal rewrite.

mmntjs itself is the bridge: keep legacy moment-shaped code stable on mmntjs, write new code against Temporal where the report shows a clean mapping, and retire the old surface on your schedule rather than on a migration deadline.

Concrete Rollout Examples

Example A: package-by-package migration in a monorepo

  1. Start with one internal package that formats and compares dates but does not own timezone-heavy scheduling logic.
  2. Replace imports in that package only and run its tests plus a small integration slice that consumes it.
  3. Add a few explicit fixtures for custom parsing, invalid inputs, and date-boundary math before expanding to the next package.

Example B: service-by-service migration

  1. Begin with a service that has clear ownership and a deploy path independent from billing or scheduling-critical systems.
  2. Switch the import path, compare outputs in staging or canary logs, then expand after those comparisons stay boring for a full release cycle.
  3. Leave higher-risk services on moment.js longer if needed; controlled uneven rollout is better than a misleading all-at-once switch.

Good Fit

  • Large codebases with deep moment.js usage.
  • Teams that need behavioral continuity before broader modernization.
  • Owners who can stage adoption by module, package, or service.

Use Caution

  • Critical timezone-data workflows that assume full IANA behavior in core.
  • Codebases with little or no regression testing around date parsing and formatting.
  • Rollouts that demand a same-day global replacement without verification time.

Testing Strategy

  • Run the tests you already trust before writing new migration-specific wrappers.
  • Add a small set of targeted comparisons for parsing, invalid dates, offsets, and DST boundaries.
  • Prefer module-level rollout so failures have a clear owner and rollback path.

What Not To Rush

  • Do not start with your most time-sensitive billing, reporting, or scheduling path.
  • Do not treat a benchmark win as evidence of behavioral safety.
  • Do not assume timezone-heavy code is low-risk just because the tests are green in UTC.

Risk Checklist

If your team can complete this checklist for one low-risk module first, the next expansion step becomes much more credible to reviewers and maintainers.

Minimal Comparison Set

Before expanding beyond the first module or service, keep a tiny comparison set that reflects the way your application actually uses dates. It does not need to be large. It needs to be representative.