MetaMask / MetaMask/metamask-mobile

Consolidate duplicate date libraries (dayjs + luxon) onto one

Open
#31,281 1 comment 0 reactions 0 assignees View on GitHub
area-performance ta-triaged team-mobile-platform
Dominant language
TypeScript
Stars
3k
Forks
1.7k
Avg merge
1d 14h
Merged PRs (30d)
669

Description

> **Performance audit finding** · Severity: **Low** · Effort: Hard · Fix risk: Risky · Test safety net: Uncovered
> Owner: `@MetaMask/mobile-platform (suggested)`
> File: `package.json:424 (dayjs), package.json:459 (luxon)`

### What is this about?

The app ships two overlapping date/time libraries as top-level dependencies: `dayjs` and `luxon`. Both are bundled, so users download and the JS runtime initializes two date libraries that do essentially the same job.

**Why it matters**

Each library adds to bundle size and module-init cost for no functional reason — date formatting/parsing can be served by a single library. luxon in particular is sizeable (its `DateTime` pulls in the Intl-backed engine). Shipping both is pure duplication. Usage is small and roughly balanced, which makes consolidation feasible.

### Scenario

N/A — see Technical Details.

### Design

N/A — internal performance change; no UI/design impact.

### Technical Details

**Evidence**

`package.json`:
```
424: "dayjs": "^1.11.13",
459: "luxon": "^3.5.0",
```
dayjs usages (`grep -rn "from 'dayjs'" app`):
- `app/util/notifications/methods/common.ts:1`
- `app/components/UI/Rewards/utils.ts:6`
- `app/components/UI/Predict/components/PredictGameChart/ChartTooltip.tsx:3`
- `app/components/UI/Predict/components/PredictPositionResolved/PredictPositionResolved.tsx:3`

luxon usages (`grep -rn "from 'luxon'" app`):
- `app/components/UI/Bridge/components/TransactionDetails/BridgeStepList.tsx:6`
- `app/components/Snaps/SnapUIDateTimePicker/SnapUIDateTimePicker.tsx:3`
- `app/components/Views/confirmations/utils/date.ts:1`
- `app/components/Views/SocialLeaderboard/TraderProfileView/components/StatsRow.tsx:2` (`Duration`)
- `app/store/migrations/084.ts:10`

(`moment` / `date-fns` are not direct app dependencies.)

**Fix**

Pick one library (dayjs is the smaller of the two) and migrate the ~5 luxon call sites — or vice-versa. luxon's `Duration` usage in `StatusRow.tsx` and `DateTime` formatting have dayjs equivalents (dayjs `duration` plugin / `format`). After migration, remove the unused package from `package.json` and lockfile. Caveat: `app/store/migrations/084.ts` is a redux-persist migration — changing its date logic must preserve identical output, so port it carefully or leave that single file on luxon until last.

### Threat Modeling Framework

N/A — performance-only change; behavior is preserved, no new data flow / trust boundary / attack surface.

### Acceptance Criteria

- - After migration: `grep -rn "from 'luxon'" app` (or `dayjs`, whichever is dropped) returns 0; remove the dependency and run `yarn dedupe` / verify lockfile no longer resolves it.
- Run unit tests for the touched files (notifications, Bridge step list, confirmations date utils, migration 084) — migration 084 has a test; confirm it still passes byte-for-byte output.
- Bundle-size diff to confirm the dropped library is gone.

### References

- File: `package.json:424 (dayjs), package.json:459 (luxon)`
- Source: MetaMask Mobile performance audit — finding `bundle-duplicate-date-libraries`
- Owner (CODEOWNERS / best-effort): @MetaMask/mobile-platform (suggested)
- Status: **UNVALIDATED**

Contributor guide

Open the contributing guide

Research direction

Start with package.json and the listed dayjs and luxon call sites under app/, comparing the formatting, parsing, Duration, and migration-084 behavior. Run the relevant unit tests, including the migration 084 test, before and after the change. Done means one date library is removed from app usage and the dependency and lockfile, tests preserve migration output, and the bundle confirms the dropped library is gone.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
mobile-dev, performance
Issue type
Refactor
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.