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

@styleupp/stylex-ui

v0.1.6

Published

Expo-first token-driven UI kit with custom/native render modes.

Readme

Stylex UI — Expo-first Token-Driven React Native UI Kit

A lightweight UI library for Expo/React Native that renders components from design tokens you provide in stylex.json. Each component supports two render modes:

  • custom (default) — fully token-driven styling
  • native (beta stub) — reserved for future platform-native look/feel

This README covers install, setup, usage, tokens, and component APIs.


Contents


Install

# add the UI library
npm i @styleupp/stylex-ui

# peer deps must already exist in your app (Expo projects have them)
# npm i react react-native expo

# for ParallaxScrollView component, also install:
npx expo install react-native-reanimated

The library ships ESM+CJS bundles and d.ts typings. It keeps react, react-native, expo, and react-native-reanimated external so your app controls versions.


Quick start

  1. Create tokens in your app root: stylex.json
{
  "$schema": "node_modules/@your-scope/stylex-ui/stylex.schema.json",
  "mode": "system",
  "light": {
    "colors": {
      "bg": "#0b0d10",
      "card": "#12161b",
      "text": "#e7eef6",
      "muted": "#8ea0b4",
      "accent": "#4da3ff",
      "accentText": "#0b0d10",
      "border": "rgba(255,255,255,0.08)",
      "danger": "#ff6b6b",
      "warning": "#ffd166",
      "success": "#70e0a3"
    },
    "radius": { "sm": 8, "md": 12, "lg": 20, "xl": 28 },
    "spacing": { "xs": 4, "sm": 8, "md": 12, "lg": 16, "xl": 24, "2xl": 32 },
    "font": {
      "family": "Inter",
      "weight": { "regular": "400", "medium": "500", "semibold": "600", "bold": "700" },
      "size": { "xs": 12, "sm": 14, "md": 16, "lg": 18, "xl": 22, "2xl": 28, "3xl": 34 }
    },
    "shadows": { "sm": 2, "md": 6, "lg": 12 }
  },
  "dark": { "...": "define a matching dark palette" },
  "components": {
    "Button": { "radius": "lg" },
    "Text":   { "tracking": { "tight": -0.2, "normal": 0, "wide": 0.2 } }
  }
}
  1. Wrap your app with the single provider:
// App.tsx
import React from "react";
import { SafeAreaView, View } from "react-native";
import stylex from "./stylex.json";
import { StylexProvider, Card, Button, Text, Heading, Stack } from "@your-scope/stylex-ui";

export default function App() {
  return (
    <StylexProvider config={stylex} mode="custom">
      <SafeAreaView style={{ flex: 1 }}>
        <View style={{ flex: 1, padding: 16 }}>
          <Stack gap="lg">
            <Heading>Stylex UI</Heading>
            <Text>Unified look from tokens.</Text>
            <Card>
              <Text kind="caption" muted tracking="wide">Inside card</Text>
              <Button label="Tap me" />
              <Button label="Native (stub)" use="native" />
            </Card>
          </Stack>
        </View>
      </SafeAreaView>
    </StylexProvider>
  );
}
  1. Use components — everything is tokenized, with optional use="native" per instance.

Tokens (stylex.json)

Shape

  • mode: "system" | "light" | "dark" — choose how the library selects the color scheme.

  • light/dark:

    • colors: arbitrary named color tokens (bg, card, text, muted, accent, accentText, border, danger, warning, success, …).
    • radius: { sm, md, lg, xl } numbers (px).
    • spacing: { xs, sm, md, lg, xl, 2xl } numbers (px).
    • font: { family, weight: { regular, medium, semibold, bold }, size: { xs..3xl } }.
    • shadows (optional): { sm, md, lg } elevation values.
  • components (optional): per-component preferences (e.g., Button.radius, Text.tracking).

Loading custom fonts

If you set a custom font.family, load it before render:

import * as Font from "expo-font";
await Font.loadAsync({ Inter: require("./assets/Inter.ttf") });

Provider

<StylexProvider
  config={stylex}   // object loaded from stylex.json
  mode="custom"     // "custom" | "native" (global default; per-component override via `use`)
>
  {children}
</StylexProvider>
  • Responds to system theme changes when mode: "system" in tokens.
  • Hook: const { colors, spacing, radius, font, px, r, fs, scheme, renderMode } = useStylex();

Usage examples

<Button label="Buy now" variant="solid" />
<Button label="Outline" variant="outline" />
<Button label="Ghost" variant="ghost" size="sm" />

<Text kind="display" weight="bold">Headline</Text>
<Text kind="overline" tracking="wide" muted>OVERLINE</Text>
<Text kind="code" monospace>npm run build</Text>

<Card><Text>Card body</Text></Card>

<TextInput placeholder="Email" />
<Switch value={on} onValueChange={setOn} />
<Checkbox checked={agree} onChange={setAgree} />

<Badge label="New" tone="accent" />
<Chip label="React Native" selected onClose={() => {}} />
<Avatar label="Ada Lovelace" />
<Progress value={42} />

<Modal visible={open} onClose={() => setOpen(false)}><Text>Hi</Text></Modal>
<Tabs items={[{key:"a",label:"Tab A"}, {key:"b",label:"Tab B"}]} value={tab} onChange={setTab} />

<ToastProvider>{/* call useToast().show({ text: "Saved!" }) */}</ToastProvider>

Components & props

Typography

  • Text

    • kind: "display"|"title"|"header"|"subheader"|"body"|"caption"|"overline"|"code" (default "body")
    • weight: "regular"|"medium"|"semibold"|"bold"
    • tracking: "tight"|"normal"|"wide"
    • muted: boolean — use colors.muted
    • monospace: boolean — force monospaced font (or set kind="code")
    • use: "custom"|"native"
  • Heading

    • level: 1|2|3|4|5|6 (maps to text sizes)
    • other props: same as Text

Layout & primitives

  • Stack

    • gap: spacing key
    • direction: "row"|"column"
  • Row / Column

    • gap, align, justify
  • Box

    • bg: color token name or hex
    • p, px, py: spacing keys
    • r: radius key
    • border: boolean
  • Divider

    • vertical: boolean
    • size: number (thickness)
  • ScrollView

    • extends RN ScrollViewProps
    • contentGap, contentPadding: spacing keys
  • ParallaxScrollView

    • extends ScrollViewProps
    • header: ReactNode (header content with parallax effect)
    • headerHeight: number (default: 250)
    • headerBackgroundColor: string (optional, defaults to theme bg)
    • contentPadding: spacing key (default: "lg")
    • contentGap: spacing key (default: "md")
    • enableScale: boolean (enable scale effect on header, default: true)
    • Note: Requires react-native-reanimated >=3 peer dependency

Inputs

  • Button

    • label: string
    • size: "sm"|"md"|"lg"
    • variant: "solid"|"outline"|"ghost"
    • disabled, onPress, use
  • TextInput

    • extends RN TextInputProps
    • invalid: boolean
    • left, right: ReactNode
    • size: "sm"|"md"|"lg"
    • use
  • Switch

    • extends RN SwitchProps
    • use
  • Checkbox

    • checked: boolean
    • onChange(v: boolean)
    • disabled
    • size: "sm"|"md"|"lg"
    • use
  • Select<T>

    • value?: T
    • onChange(v: T)
    • options: {label:string, value:T}[]
    • placeholder?: string
  • RadioGroup<T>

    • items: {label:string, value:T, disabled?:boolean}[]
    • value?: T
    • onChange(v: T)
  • Slider

    • value: number, onChange(v:number)
    • min, max, step, height

Data display

  • Card — container with colors.card, border, radius.

  • Badge

    • label
    • tone: "neutral"|"success"|"warning"|"danger"|"accent"
  • Chip

    • label: string
    • selected?: boolean
    • onPress?: () => void
    • onClose?: () => void — show close button
    • style?: ViewStyle
  • Avatar

    • uri?: string, label?: string (initials)
    • size?: number
    • rounded: "sm"|"md"|"lg"|"xl"|"full"
  • ListItem

    • title, subtitle?
    • left?, right?
    • onPress?

Feedback

  • Spinner

    • size: "small"|"large"|number
  • Progress

    • value: 0–100, height?
  • Skeleton

    • style?, rounded?

Overlays

  • Modal

    • visible, onClose?, dismissOnBackdrop?
  • Sheet

    • open, onClose?, height?
  • Tooltip

    • content, children

Navigation

  • Tabs

    • items: { key, label, disabled?, badge? }[]
    • value: string, onChange(key)
    • variant: "underline"|"pill"

Icons & actions

  • Icon

    • name?: string (emoji or mapped glyph), uri?: string, size?: number, color?
  • IconButton

    • icon: ReactNode|string, onPress?, size?, variant: "ghost"|"solid"
  • IconTextButton

    • icon: ReactNode|string, label, onPress?
  • ActionButton

    • icon?: ReactNode|string, onPress? — floating primary action

Disclosure

  • Collapsible

    • open, duration?
  • Accordion

    • items: { key, title, content }[]
    • value?, onChange?(key)

Misc

  • ExternalLink

    • href, label
  • ErrorBoundary

    • fallback? (ReactNode)

Toast (provider + hook)

  • ToastProvider — place near the app root
  • useToast().show({ text, tone? })

TypeScript & builds

  • You can import JSON tokens directly (import stylex from "./stylex.json";).
  • All components are typed. You can inspect StylexConfig if you generate tokens dynamically.
  • If you build your own fork/package, make sure your bundler keeps react, react-native, and expo external (already configured).

Accessibility & theming

  • Touch targets aim for ≥ 44×44 where interactive.
  • Text contrast is controlled by your tokens. Prefer accessible pairs (colors.text vs colors.card).
  • RTL: primitives avoid directional assumptions; if you introduce directional padding, consult I18nManager.isRTL.
  • Theme switching: set mode: "system" in tokens for automatic scheme changes; or force "light"/"dark".

FAQ

Can I override render mode per component? Yes, pass use="native" on any component. Global default is the mode prop on StylexProvider.

Do I need to ship stylex.json with the app? You load it at build time (import stylex from "./stylex.json"), then pass the object to the provider.

Can I extend tokens with new keys? Yes—colors, radius, spacing, and font can contain additional keys. Components only read the token names they use.

Does it work on web? Yes—everything is built from RN primitives and Expo. Some platform nuances (focus rings, hover) are minimal by design.


Contributing

  • Keep new components dependency-free when possible.
  • Follow the pattern: tokenized custom branch + stubbed native branch with use override.
  • Add props to this README and minimal examples.

License

MIT.