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

expo-interface

v0.23.0

Published

Native-first universal UI kit for Expo — SwiftUI on iOS, Jetpack Compose on Android, real DOM on web, WinUI 3 on Windows — built on @expo/ui and react-native-windows.

Readme

Expo Interface

A UI kit for Expo where every component is the platform's own control.

Write a screen once. It renders as SwiftUI on iOS, Jetpack Compose (Material 3) on Android, real DOM elements on web, and WinUI 3 on Windows. One accent color themes all four, and screens follow the system's light or dark scheme with no per-platform styling.

import {Button, FieldGroup, Screen, Switch} from 'expo-interface';

export default function Settings() {
  return (
    <Screen native>
      <FieldGroup>
        <FieldGroup.Section title="Sync">
          <Switch label="Notifications" value={on} onValueChange={setOn}/>
          <Button label="Continue" onPress={save}/>
        </FieldGroup.Section>
      </FieldGroup>
    </Screen>
  );
}

| Platform | That screen is | Through | | --- | --- | --- | | iOS | A SwiftUI Form with a Toggle and a Button | @expo/ui/swift-ui | | Android | A Material 3 grouped list with a Switch and a Button | @expo/ui/jetpack-compose | | Web | <button>, <input> and the rest, with CSS beside each component | react-native-web for layout | | Windows | A Settings-style card with a ToggleSwitch and a Button | The kit's own WinUI library, on expo-windows |

See every component live in the Storybook.

Quick start

Requires Expo SDK 57 and Expo Router.

1. Install

npx expo install expo-interface @expo/ui @expo/material-symbols

The peer dependencies are standard Expo modules that most Expo Router apps already have. If any are missing:

npx expo install expo-router expo-symbols expo-asset expo-image expo-constants expo-status-bar expo-system-ui expo-web-browser react-native-safe-area-context

2. Wrap the app

Use AccentProvider and the kit's Stack in the root layout. seed is any hex color, and the default is #007AFF.

// app/_layout.tsx
import {ThemeProvider} from 'expo-router';
import {AccentProvider, Stack, useNavTheme} from 'expo-interface';

function Navigation() {
  return (
    <ThemeProvider value={useNavTheme()}>
      <Stack screenOptions={{headerShown: false}}/>
    </ThemeProvider>
  );
}

export default function Layout() {
  return (
    <AccentProvider seed="#8959EA">
      <Navigation/>
    </AccentProvider>
  );
}

3. Web only: emit the palette

// app/+html.tsx
import {ScrollViewStyleReset} from 'expo-router/html';
import {getThemeBootScript, getThemeCSS} from 'expo-interface';

export default function Root({children}: React.PropsWithChildren) {
  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8"/>
        <meta name="viewport" content="width=device-width, initial-scale=1"/>
        <style dangerouslySetInnerHTML={{__html: getThemeCSS()}}/>
        <script dangerouslySetInnerHTML={{__html: getThemeBootScript()}}/>
        <ScrollViewStyleReset/>
      </head>
      <body>{children}</body>
    </html>
  );
}

4. Android only: register XML assets

Jetpack Compose draws icons from XML vector drawables, which @expo/material-symbols provides.

// metro.config.js
const {getDefaultConfig} = require('expo/metro-config');

const config = getDefaultConfig(__dirname);
config.resolver.assetExts.push('xml');

module.exports = config;

5. Build screens

Use the screen at the top of this page, then run the app on two platforms and compare. Getting started continues from here with tabs, icons and troubleshooting.

Windows

Add the platform with expo-windows. The kit needs no setup of its own there. See Windows.

Components

Everything is exported from expo-interface. Value controls are controlled: pair value with onValueChange. Each link says what the component does, its props, what each platform renders, and where the platforms differ.

| Group | Components | | --- | --- | | Layout | Screen, ScreenHeader, NativeHost, Surface, Card, Toolbar, KeyboardBar, FieldGroup, ListItem, Collapsible, Divider, EmptyState | | Navigation | Stack, Tabs, TabStack, ConstrainedStackHeader, TabView, Pager, HeaderMenu, HeaderAction, HeaderActions, ExternalLink, ShareLink | | Controls | Button, Fab, Chip, IconToggle, Switch, Checkbox, TextField, SearchField, Picker, SegmentedControl, Slider, Stepper, DateTimePicker, ColorPicker | | Indicators | Progress, Spinner, Gauge, Badge, Avatar, Typography and its variants | | Overlays | Menu, ContextMenu, PopupMenu, Popover, Tooltip, Alert, Sheet, Toast |

Features

| Feature | What it does | Guide | | --- | --- | --- | | One accent | AccentProvider takes one hex seed. It becomes the SwiftUI tint, a full Material 3 palette, CSS variables, and WinUI's accent brushes. | Theming | | Light and dark | Every component follows the system. setColorScheme forces one, and on web the choice survives a reload without a flash. | Theming | | Color tokens | theme.label, theme.background and the rest resolve to values the OS keeps current, with no re-render. useColor and usePalette give plain strings. | Theming | | Icons | One token names the icon in SF Symbols, Material Symbols and Segoe Fluent Icons. fill: true asks for the solid form. | Icons | | Native hosts | Screen native hosts a whole screen. NativeHost hosts a group of controls beside a canvas or an editor. | Native hosts | | Navigation | Stack, Tabs and TabStack over Expo Router: the native stack and tab bar, a floating bar on web, a NavigationView on Windows. | Navigation | | Web platform primitives | Popovers, anchor positioning, <dialog>, <select> and <datalist> rather than portals and z-index, with the ARIA keyboard patterns. | Web | | Windows | WinUI 3 controls in XAML islands, content in the title bar, keyboard shortcuts, high contrast, right to left and scaling. | Windows | | @expo/ui on Windows | Screens written against @expo/ui and the community controls draw WinUI controls with no change. | Windows | | Accessibility | An accessible name on every control, headings, live regions, and the platform's own semantics. | Accessibility | | Honest differences | A prop a platform cannot honour is documented as absent there. Nothing is faked. | Where platforms differ |

Documentation

| Page | What is in it | | --- | --- | | Getting started | The quick start in full, tabs, icons, troubleshooting. | | Components | Every component, one line each, linked to its entry. | | Theming | Accent, scheme, tokens, reading colors, high contrast, constants. | | Icons | Tokens, filled icons, drawables, the web font, Windows glyphs. | | Native hosts | Where native controls live on iOS and Android. | | Web and Windows | What each platform does its own way. | | Where platforms differ | The differences that change what a screen can do, in one table. | | Accessibility | What the kit sets on each platform. | | Contributing | The repository, the checks, Storybook, the harness, CI. |

Versions

Expo SDK 57, React Native 0.86.3 and @expo/ui 57.0.18. On Windows the kit runs on expo-windows. React Native 0.86 has no react-native-windows release yet, so the Windows side is built and tested on the 0.84 line. expo-windows' versions page says what that means for an app today.

Contributing

The example app, dropfiles, uses every component and imports the package from ../src.

bun install        # bun 1.4 or later
bun run web        # or ios, android
bun run lint
bun run typecheck
bun run test       # vitest, every platform project, 100% coverage

Contributing has the rest: how a component is built, the Storybooks, the tests, the harness and the Windows build.

License

MIT