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

@groooh/react-native-webify

v0.1.1

Published

Zero-runtime build-time compiler and universal design system converting React Native components into semantic React Web & Next.js code

Readme

@groooh/react-native-webify

npm version Live Demo License: MIT TypeScript Zero Runtime Website

Write once in React Native using design tokens. Compile to 100% semantic, accessible, zero-runtime React & Next.js web code.

Created by d-naum • Powered by Groooh

🌐 Live Web Demo: https://react-native-webify-boilerplate.vercel.app/
📱 Starter & Examples Boilerplate: https://github.com/d-naum/react-native-webify-boilerplate


🔗 Live Demo & Starter Kit

Experience the zero-runtime compiled components live in your browser:

⚡ Why @groooh/react-native-webify?

Traditional solutions like react-native-web inject a heavy runtime compatibility layer, turning every native component into nested <div> and <span style="display:flex"> tags. This creates deep, unsemantic DOM trees, degrades web performance, harms SEO, and causes hydration penalties in modern SSR frameworks like Next.js.

@groooh/react-native-webify solves this at build time.

Using a high-performance TypeScript AST (Abstract Syntax Tree) compiler, it reads your React Native source code, statically evaluates your design tokens, and transforms native primitives into native HTML5 elements (<article>, <h1>-<h6>, <button>, <input>, <dialog>, <progress>, etc.).

┌──────────────────────────────────────────────┐
│  React Native Component + Tokens             │
│  <Card padding="lg">                         │
│    <Heading variant="h2">Title</Heading>     │
│    <Button variant="primary">Submit</Button> │
│  </Card>                                     │
└──────────────────────┬───────────────────────┘
                       │
         ┌─────────────┴─────────────┐
         ▼                           ▼
┌─────────────────┐         ┌────────────────────────────────────────────────────────┐
│  iOS / Android  │         │  React Web / Next.js (0 KB Runtime Overhead)           │
│  Native Runtime │         │  <article style={{ padding: "24px", ... }}>            │
│  View, Text,    │         │    <h2>Title</h2>                                      │
│  Pressable      │         │    <button style={{ backgroundColor: "#6366f1" }}>     │
│                 │         │      Submit                                            │
│                 │         │    </button>                                           │
│                 │         │  </article>                                            │
└─────────────────┘         └────────────────────────────────────────────────────────┘

Key Differentiators

  • 0 KB Web Runtime Overhead: No polyfill bundle, no runtime translation cost, no style injection shims.
  • Semantic HTML5 Output: Renders native <article>, <section>, <nav>, <input>, <button>, <dialog>, <progress>, <hr>, <figure>, and <details>.
  • First-Class Next.js Support: Compatible with React 19, Next.js App Router (Server Components & Client Components), and static exports.
  • Centralized Design Token Engine: Spacing, colors, typography, borders, and breakpoints compile directly into static inline styles.
  • Lightning-Fast CLI: Compiles directories in milliseconds and includes an active --watch mode for hot development.

📦 Installation

In your React Native / Expo Mobile Project

# npm
npm install @groooh/react-native-webify

# yarn
yarn add @groooh/react-native-webify

# pnpm
pnpm add @groooh/react-native-webify

In your React Web / Next.js Project (Build Compiler & CLI)

# npm
npm install -D @groooh/react-native-webify

# yarn
yarn add -D @groooh/react-native-webify

# pnpm
pnpm add -D @groooh/react-native-webify

🚀 Quick Start

1. Write your component in React Native

Create your shared cross-platform component using @groooh/react-native-webify primitives and design tokens:

// src/components/UserProfileCard.tsx
import React from "react";
import {
  Card,
  Row,
  Stack,
  Avatar,
  Heading,
  Body,
  Badge,
  Button,
  Divider,
} from "@groooh/react-native-webify";

export interface UserProfileCardProps {
  name: string;
  role: string;
  avatarUrl?: string;
  isOnline?: boolean;
  onFollow?: () => void;
}

export const UserProfileCard = ({
  name,
  role,
  avatarUrl,
  isOnline = true,
  onFollow,
}: UserProfileCardProps) => {
  return (
    <Card padding="lg">
      <Stack gap="md">
        <Row align="center" justify="between">
          <Row align="center" gap="sm">
            <Avatar name={name} uri={avatarUrl} size="md" />
            <Stack gap="xs">
              <Body weight="bold">{name}</Body>
              <Body size="xs" color="neutral.500">{role}</Body>
            </Stack>
          </Row>
          <Badge
            variant={isOnline ? "success" : "neutral"}
            label={isOnline ? "Active" : "Offline"}
          />
        </Row>

        <Divider />

        <Heading variant="h3">Profile Overview</Heading>
        <Body size="sm" color="neutral.600">
          Cross-platform engineer building high-performance universal user interfaces.
        </Body>

        <Row justify="end" gap="sm">
          <Button variant="secondary" size="sm">Message</Button>
          <Button variant="primary" size="sm" onPress={onFollow}>Follow</Button>
        </Row>
      </Stack>
    </Card>
  );
};

2. Compile to Semantic React Web JSX

Run the compiler CLI to transform mobile components into web-native code:

# Single build
npx webify build -i src/components -o web/src/generated

# Or watch mode for instantaneous recompilation
npx webify build -i src/components -o web/src/generated --watch

3. See the Generated Zero-Runtime Web Output

The compiler produces a clean, accessible .web.tsx file with zero native dependencies:

// web/src/generated/UserProfileCard.web.tsx
import * as React from "react";

export const UserProfileCard = ({ name, role, avatarUrl, isOnline = true, onFollow }) => {
  return (
    <article style={{ backgroundColor: "#ffffff", borderRadius: "12px", border: "1px solid #e5e7eb", padding: "24px" }}>
      <div style={{ display: "flex", flexDirection: "column", gap: "16px" }}>
        <div style={{ display: "flex", flexDirection: "row", alignItems: "center", justifyContent: "space-between" }}>
          <div style={{ display: "flex", flexDirection: "row", alignItems: "center", gap: "8px" }}>
            <figure style={{ display: "inline-flex", alignItems: "center", justifyContent: "center", borderRadius: "9999px", width: "40px", height: "40px" }} />
            <div style={{ display: "flex", flexDirection: "column", gap: "4px" }}>
              <p style={{ fontWeight: 700, margin: 0 }}>{name}</p>
              <p style={{ fontSize: "12px", color: "#6b7280", margin: 0 }}>{role}</p>
            </div>
          </div>
          <span style={{ backgroundColor: isOnline ? "#dcfce7" : "#f3f4f6", borderRadius: "9999px", padding: "2px 8px" }}>
            {isOnline ? "Active" : "Offline"}
          </span>
        </div>

        <hr style={{ border: "none", borderTop: "1px solid #e5e7eb", margin: 0 }} />

        <h3 style={{ fontSize: "20px", fontWeight: 600, margin: 0 }}>Profile Overview</h3>
        <p style={{ fontSize: "14px", color: "#4b5563", margin: 0 }}>
          Cross-platform engineer building high-performance universal user interfaces.
        </p>

        <div style={{ display: "flex", flexDirection: "row", justifyContent: "flex-end", gap: "8px" }}>
          <button style={{ backgroundColor: "#f3f4f6", color: "#111827", borderRadius: "8px", cursor: "pointer" }}>
            Message
          </button>
          <button onClick={onFollow} style={{ backgroundColor: "#6366f1", color: "#ffffff", borderRadius: "8px", cursor: "pointer" }}>
            Follow
          </button>
        </div>
      </div>
    </article>
  );
};

🎨 Design Token System

@groooh/react-native-webify includes a battle-tested design token system. Tokens can be passed directly as component props or consumed via @groooh/react-native-webify/tokens.

1. Semantic Color Palette

Each color family contains 10 carefully calibrated tints (50 through 900):

| Color Scale | Purpose | Values | |---|---|---| | primary | Main brand accents, primary buttons, active tabs | primary.50 to primary.900 (#6366f1 base) | | neutral | Backgrounds, cards, text hierarchy, borders | neutral.50 to neutral.900 (#111827 base) | | success | Confirmation states, completed indicators, tags | success.50 to success.900 (#22c55e base) | | warning | Caution banners, pending items, highlights | warning.50 to warning.900 (#f59e0b base) | | error | Destructive actions, validation errors, alerts | error.50 to error.900 (#ef4444 base) | | info | System notices, informative tips | info.50 to info.900 (#0ea5e9 base) |

<Body color="neutral.700">High contrast body copy</Body>
<Card backgroundColor="neutral.50" borderColor="primary.200">...</Card>
<Badge variant="error" label="Failed" />

2. Spacing Tokens

Consistent 4px/8px rhythm across both mobile layout engines and CSS:

| Token | Pixels | CSS Web Value | Usage | |---|---|---|---| | xs | 4px | "4px" | Tight label margins, indicator spacing | | sm | 8px | "8px" | Compact gaps, button internal padding | | md | 16px | "16px" | Standard stack spacing, card paddings | | lg | 24px | "24px" | Section spacing, container padding | | xl | 32px | "32px" | Modal padding, major layout gaps | | 2xl | 48px | "48px" | Screen gutters, section dividers | | 3xl | 64px | "64px" | Landing page hero spacing | | 4xl | 96px | "96px" | Large desktop display spacing |

<Stack gap="lg" padding="xl">
  <Row gap="sm">...</Row>
</Stack>

3. Border Radius Tokens

| Token | Pixels | Equivalent | |---|---|---| | none | 0px | Squared | | xs | 2px | Subtle corner rounding | | sm | 4px | Small badges, code blocks | | md | 8px | Standard buttons, input fields | | lg | 12px | Cards, dialog modals | | xl | 16px | Floating sheets, banners | | full | 9999px | Pill badges, circular avatars |

<Card radius="lg">...</Card>
<Image radius="md" uri="..." />

4. Typography Tokens

| Token | Font Size | Line Height | Native Mobile | Web Tag | |---|---|---|---|---| | h1 | 32px | 40px | <Text style={{ fontSize: 32 }}> | <h1> | | h2 | 24px | 32px | <Text style={{ fontSize: 24 }}> | <h2> | | h3 | 20px | 28px | <Text style={{ fontSize: 20 }}> | <h3> | | h4 | 18px | 24px | <Text style={{ fontSize: 18 }}> | <h4> | | h5 | 16px | 22px | <Text style={{ fontSize: 16 }}> | <h5> | | h6 | 14px | 20px | <Text style={{ fontSize: 14 }}> | <h6> | | body (md) | 16px | 24px | <Text style={{ fontSize: 16 }}> | <p> | | caption | 12px | 16px | <Text style={{ fontSize: 12 }}> | <span> |


🧩 Complete Component Catalog (30+ Components)

| Category | Component | Mobile Representation | Web Compilation Output | |---|---|---|---| | Layout | Stack | <View style={{ flexDirection: 'column', gap }}> | <div style="display:flex; flex-direction:column; gap:..."> | | | Row | <View style={{ flexDirection: 'row', gap, alignItems }}> | <div style="display:flex; flex-direction:row; gap:..."> | | | Box / View | <View> | <div> | | | ScrollView | <ScrollView> | <div style="overflow:auto"> | | | FlatList | <FlatList> | Native .map() loop with item keys | | Typography| Heading | <Text style={headingStyles[variant]}> | <h1>, <h2>, <h3>, <h4>, <h5>, <h6> | | | Body | <Text style={bodyStyles[size]}> | <p style="..."> | | | Caption | <Text style={captionStyles}> | <span style="..."> | | Actions | Button | <Pressable style={buttonStyles}> | <button style="..."> (with onClick) | | Form Inputs | Input | <TextInput> | <input type="text"> | | | PasswordInput| <TextInput secureTextEntry> | <input type="password"> | | | SearchInput | <TextInput> with search icon | <input type="search"> | | | Textarea | <TextInput multiline> | <textarea> | | | Slider | Gesture-driven track & thumb | <input type="range" min max value onChange> | | | Checkbox | Pressable box with checkmark | <input type="checkbox"> | | | Radio / RadioGroup | Pressable radio indicator group | <fieldset> + <input type="radio"> | | | Select | Dropdown picker modal | <select> + <option> (styled 42px height & primary hover) | | | DatePicker | Primary-themed calendar picker | <input type="date"> (42px height, inherited font & label) | | | OTPInput | Discrete PIN digit boxes | Segmented <input maxLength="1"> series | | | InputFrame | Label, error message, helper container | <div style="..."> container with field helper | | Data Display| Card | <View style={cardStyles}> | <article style="..."> | | | Badge | Pill container with colored status | <span style="..."> | | | Tag | Removable chip with dismiss icon | <span style="..."> with close <button> | | | Avatar | Profile photo / name initials / edit badge | <figure style="..."> with optional upload camera badge | | | AvatarGroup | Overlapping avatar stack (+N badge) | <div style="display:flex"> overlapping stack | | | Divider | Horizontal or vertical separator | <hr style="..."> | | | Accordion | Animated collapsible disclosure | <details> + <summary> | | | Tabs | Segmented tab button bar | Tab navigation with ARIA roles | | | ProgressBar | Animated progress fill bar | <progress max="100" value="..."> | | | Skeleton | Shimmer placeholder loader | <div style="background:linear-gradient..."> | | Media & Upload | Image | <Image source={{ uri }}> | <img src="..." alt="..." /> | | | ImageSlider | Multi-image carousel with dots & arrows | <div role="region"> with image slider & indicators | | | FileUpload | Drag-and-drop file upload zone | Dropzone with SVG cloud upload icon & file preview | | Overlays | Modal | Full-screen animated overlay | <dialog style="..."> | | | BottomSheet | Drag-up mobile drawer sheet | Accessible overlay drawer container | | | Drawer | Side sliding navigation sheet | <aside style="..."> | | Feedback | Alert | Banner with warning/info icon | <div role="alert"> | | | Spinner | Animated activity indicator | <div role="status"> SVG spinner | | | Toast | Floating transient feedback notification | Floating notification banner | | E-Commerce | ProductCard | Product card with multi-image slider | <article> with image carousel, price, rating, wishlist & cart | | | Price | Formatted price with discount comparison | <div style="..."> with formatted price & <del> | | | Rating | Star ratings (0-5) with review counts | <div role="img"> with stars & review count | | | QuantitySelector | Numeric increment/decrement stepper | <div role="group"> with - / + buttons |


🛠️ CLI Usage & Compilation

The package provides the webify command (aliases: react-native-webify, rn-to-react).

Command Options

webify build [options]

Options:
  -i, --input <path>     React Native source directory (default: ./src)
  -o, --output <path>    Generated React Web directory (default: ./web)
  -w, --watch            Watch for file changes and recompile automatically
  -h, --help             Show help message

Configuration File (react-native-webify.config.json)

You can place a configuration file in your project root:

{
  "input": "./src/components",
  "output": "./web/src/generated",
  "recursive": true
}

Then simply execute:

npx webify build

🌐 Next.js & React Web Integration

Integrating with Next.js is straightforward. Add a pre-compilation script in your package.json:

{
  "scripts": {
    "compile:ui": "webify build -i ../mobile/components -o ./src/components/generated",
    "dev": "npm run compile:ui && next dev",
    "build": "npm run compile:ui && next build",
    "watch:ui": "webify build -i ../mobile/components -o ./src/components/generated --watch"
  }
}

Because the output is pure React JSX using semantic HTML, it works seamlessly with:

  • Server Components (RSC) in Next.js App Router.
  • Static Site Generation (SSG) and Server-Side Rendering (SSR).
  • Standard bundlers (Vite, Webpack, Turbopack, Rspack).

💻 Programmatic API

You can also use the compiler directly in your custom Node.js build pipelines:

import { transformReactNativeToReact } from "@groooh/react-native-webify/compiler";

const rnCode = `
import React from "react";
import { Card, Heading, Button } from "@groooh/react-native-webify";

export const Welcome = () => (
  <Card padding="md">
    <Heading variant="h2">Hello Groooh</Heading>
    <Button variant="primary">Explore</Button>
  </Card>
);
`;

const webCode = transformReactNativeToReact(rnCode, "Welcome.tsx");
console.log(webCode);
// Outputs semantic <article>, <h2>, <button> React code!

📊 Feature Comparison

| Feature | @groooh/react-native-webify | react-native-web | Solito | |---|:---:|:---:|:---:| | Zero Runtime Overhead | ✅ 0 KB | ❌ ~50–100 KB | ❌ Depends on RNW | | Semantic HTML Elements | ✅ Native <article>, <h1>, <button>, <dialog> | ❌ Nested <div> & <span> | ❌ Only handles links/routing | | SEO & Lighthouse Scores | ✅ 100% Native Lighthouse Score | ⚠️ Degraded by non-semantic DOM | ⚠️ Degraded by RNW | | Next.js Server Components | ✅ 100% Native Support | ⚠️ Needs client boundary wrappers | ⚠️ Mixed | | Design Token System | ✅ Integrated (Colors, Spacing, Typography) | ❌ Manual | ❌ Bring your own | | Real-time CLI Watch Mode | ✅ Built-in | ❌ | ❌ |


👨‍💻 Author

d-naum


📄 License

MIT © d-naum — see the LICENSE file for details.