Skip to content

Metro plugin imports private metro-cache path; breaks under isolated installs and Expo (vendored metro) #552

@ottob

Description

@ottob

Im playing around with the new globalStore option for bun and then my expo app didn't start.
Debugged with claude, so take it with a grain of salt. But the solution worked for me.

Summary

uniwind/metro does require('metro-cache/private/stores/FileStore'). This breaks in two cases:

  1. Isolated installs (pnpm, Yarn PnP, Bun's globalStore = true in 1.3.x). metro-cache is not
    declared in uniwind's dependencies or peerDependencies, so under isolated/strict layouts the
    require can't resolve — Node walks up from the uniwind link directory and never finds metro-cache.
    Crash:

Error: Cannot find module 'metro-cache/private/stores/FileStore'
Require stack:

  • /uniwind@1.7.0/.../uniwind/dist/metro/index.cjs
  • /apps//metro.config.js
    ...
  1. Expo projects. Expo (>=53 and certainly Expo 56) vendors metro under @expo/metro. The path
    metro-cache/private/stores/FileStore does not exist there — Expo's tree is
    @expo/metro/metro-cache/stores/FileStore (no /private/). Even when it limps along under hoisted
    installs, you're reaching into a private path that may shift between metro versions.

Repro

  • Expo 56 project, bun install with bunfig.toml containing globalStore = true, then bun expo
    start. Crashes immediately on requiring uniwind/metro.
  • Same setup with pnpm node-linker=isolated reproduces the same error.

Suggested fix

Use the public Expo wrapper when running under Expo — it already extends the right FileStore for
the vendored metro and adds Expo-specific cache invalidation behavior:

// dist/metro/index.cjs
const { FileStore: FileStoreBase } = require('@expo/metro-config/file-store');

// dist/metro/index.mjs
import { FileStore as FileStoreBase } from '@expo/metro-config/file-store';

For bare React Native (non-Expo), the proper public API is metro-cache's top-level export (the
FileStore named export was added in metro 0.79+) — and metro-cache should be declared as a
peerDependency (optional) on uniwind so isolated installs resolve it.

A combined approach: try @expo/metro-config/file-store first, fall back to metro-cache for bare
RN. Or expose cacheStores as a config option so app authors pass their own FileStore.

Environment

  • uniwind 1.7.0
  • expo 56.0.5, @expo/metro-config 56.0.13, @expo/metro (vendored)
  • bun 1.3.14 with globalStore = true

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions