npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@react-native-media-styles/expo

v0.1.0

Published

Build-time CSS extraction and route-based stylesheet delivery for Expo.

Readme

@react-native-media-styles/expo

Build-time CSS extraction and route-based stylesheet delivery for Expo.

Experimental: This integration depends on version-specific Expo internals. Its API and generated output may change between releases. Pin Expo and this package, and rerun the SSR, navigation, and browser checks when upgrading.

Install @react-native-media-styles/expo with @react-native-media-styles/core. Apply withMediaStyles to the Expo Metro configuration.

import {getDefaultConfig} from 'expo/metro-config';
import {withMediaStyles} from '@react-native-media-styles/expo';

module.exports = withMediaStyles(getDefaultConfig(__dirname));
  • Apply @react-native-media-styles/expo after other Metro configuration wrappers.
  • The Babel extractor in @react-native-media-styles/expo compiles static React Native Web and breakpoint declarations. The Metro worker supplies the generated CSS to Expo's asset serializer.
  • Expo exports content-hashed CSS files and includes their links in the server document.
  • Expo's CSS development loader replaces styles during Fast Refresh.
  • Metro's resolved dependency graph supplies shared CSS and separate CSS bundles for route and layout modules. Each bundle includes its lazy dependencies and components rendered only in the browser.
  • Server responses link shared CSS and the bundles selected by Expo Router's URL matching, including layouts and initial navigator routes.
  • Client navigation waits for the destination route's stylesheet before rendering its content. A timed, bounded retry handles transient failures.
  • Stylesheet names contain a content hash. The client route registry is emitted as a separate content-hashed script, so production does not rely on an inline registry and unchanged bundles retain their URLs for caching.
  • @react-native-media-styles/expo combines generated layer blocks and keeps the last occurrence of identical rules within each layer. Imported CSS and media rules preserve their positions.
  • Production CSS contains route asset metadata. Development CSS also includes module paths for Fast Refresh updates.
  • Static StyleSheet.create and breakpoints declarations generate CSS assets. Runtime RNW style values use inline styles.
  • Breakpoint hooks compose references to existing CSS declarations supplied by @react-native-media-styles/expo.
  • Development serves route CSS as files and applies Fast Refresh updates to modules used by active routes.
  • Restart Metro with --clear after configuration changes and changes to imported breakpoint constants.
  • @react-native-media-styles/expo implementation and tests use TypeScript. Builds emit CommonJS modules for Metro and Babel.

@react-native-media-styles/expo preserves the configured Expo worker, Babel transformer and resolver. Extraction, route asset selection and development updates are internal modules of @react-native-media-styles/expo.

Supported React Native Web combination

The supported and continuously tested web combination is:

  • Expo 58.0.14
  • React Native 0.88.0
  • React Native Web 0.21.4
  • React 19.3.0

The package peer dependency pins the associated React Native Web and Expo Metro versions. Verify upgrades through server rendering, client navigation, delayed content, Fast Refresh and all browser projects.

Production deployment contract

The library emits the assets and manifest. The application or CDN owns HTTP delivery.

  • Serve /_expo/static/** with Cache-Control: public, max-age=31536000, immutable.
  • Compress HTML, JavaScript, JSON and CSS with Brotli or gzip.
  • Do not publicly cache personalized or authenticated HTML.
  • Preserve the manifest script before the Expo entry bundle.
  • Serve missing hashed assets as 404 responses rather than HTML fallbacks.

The example production server implements this contract and production.spec.ts verifies the actual response headers. Do not deploy Expo's development serve output as-is: it does not provide the production cache and compression policy.

The client manifest is an external script-src 'self' asset. It does not add an inline script that requires a CSP nonce.

Stylesheet failure recovery

Routes should export an Expo Router ErrorBoundary that clears the failed stylesheet record before retrying:

import {retryRouteCSS} from '@react-native-media-styles/expo/client';
import type {ErrorBoundaryProps} from 'expo-router';

export function ErrorBoundary({retry}: ErrorBoundaryProps) {
  return (
    <button
      onClick={() => {
        retryRouteCSS();
        retry();
      }}
    >
      Try again
    </button>
  );
}

The default load policy waits 10 seconds per attempt and makes three total attempts with exponential backoff. Applications can adjust it in their client bootstrap with configureRouteCSS({timeoutMs, retries, retryDelayMs}).

Route CSS scope

Route CSS selection applies to streaming server rendering and subsequent client navigation. Shared entry dependencies supply application-wide CSS. A route bundle contains every stylesheet reachable through its resolved imports, including conditional and asynchronous imports. Dependencies shared by route modules can appear in multiple route bundles.

Expo's single-page and static export HTML currently includes the complete CSS asset list. Native builds use the host pipeline.

@react-native-media-styles/expo transforms Expo's server renderer and route rendering functions. It checks the expected function shapes during compilation and reports an error when those integration points change. Route matching builds Expo Router's route table once per server process and reuses it across requests. Verify Expo upgrades with server rendering, delayed content, navigation and Fast Refresh tests.

Compiler syntax caveat

@react-native-media-styles/expo recognizes static style declarations in ES modules and CommonJS modules, including Babel object-spread helpers in both formats. It evaluates recognized syntax without executing application modules.

Compiler versions and build settings can produce different syntax for the same style declaration. Each additional helper or expression shape needs explicit handling and regression coverage. AMD, UMD, IIFE and System.register bundles are outside the supported extraction inputs.

An unrecognized expression can prevent extraction even when its values are constant at runtime. Ordinary RNW styles retain validated inline values. Styles that require CSS, including $raw rules and keyframes, and breakpoint definitions report an extraction error when their values cannot be resolved at build time.

Verify dependency upgrades through the application's Metro pipeline, including SSR and browser builds. Regression tests should exercise the dependency files and compiler output used by those builds.