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

@myop/react-native

v0.0.49

Published

React Native component for embedding Myop components via WebView

Readme

@myop/react-native

Official React Native bindings for embedding Myop components in your React Native applications.

Myop components are framework-agnostic UI components that can be updated in real-time without redeploying your application. Build once, embed anywhere, and iterate instantly. Perfect for teams that need to ship UI changes fast, A/B test components, or empower non-developers to customize the interface. Myop is also the safest way to adopt AI-generated components in your application—whether created by developers or non-developers—with built-in sandboxing and controlled integration.

npm version License: MIT Discord

Website | Documentation | Dashboard | Discord

Installation

npm install @myop/react-native

Install the required peer dependency:

npm install react-native-webview

Auto-Generated React Native Components

Myop automatically generates a typed React Native component package for every component you create in the dashboard. Install it directly via npm:

npm install https://cloud.myop.dev/npm/{component-id}/react-native

Then import and use it like any React Native component. For example, if you created a table component called "users-table" in the dashboard:

import { UsersTable } from "@myop/users-table";

export default function App() {
  const users = [
    { id: 1, name: "Alice", email: "[email protected]", role: "Admin" },
    { id: 2, name: "Bob", email: "[email protected]", role: "User" },
    { id: 3, name: "Charlie", email: "[email protected]", role: "User" },
  ];

  return (
    <UsersTable
      data={{ rows: users }}
      onRowClicked={(payload) => {
        console.log("Selected user:", payload.rowData);
      }}
      onDeleteClicked={(payload) => {
        deleteUser(payload.userId);
      }}
      onExportRequested={(payload) => {
        exportToFormat(payload.format); // "csv" | "xlsx"
      }}
      style={{ flex: 1 }}
    />
  );
}

Why this is powerful:

  • Fully typed — The generated package includes complete TypeScript types for your component's data interface and all CTA event payloads
  • Auto loaded — Components are fetched and rendered automatically, no manual setup required
  • Not in your code — The actual component implementation lives on Myop and is loaded at runtime. Update your component in the dashboard and it's instantly live—no rebuild, no redeploy
  • Zero bundle impact — Auto-generated component packages are just thin typed wrappers. The actual component implementations are loaded at runtime via WebView, meaning your Myop components can be as complex, feature-rich, and heavy as you need without adding to your application bundle

Environment options:

Set the default environment for all components using setEnvironment:

import { setEnvironment } from "@myop/react-native";

// Set default environment for all component loads
setEnvironment("staging");

You can also override the environment directly on a specific component:

<UsersTable
  data={{ rows: users }}
  preview={true}        // Load unpublished preview version
  environment="staging" // Load from specific environment (prod, staging, etc.)
  style={{ flex: 1 }}
/>

Environments are fully configurable in the dashboard, allowing you to test changes in staging before publishing to production.

For more details on auto-generated packages, see the Auto-Generated Packages documentation.

Requirements

| Dependency | Version | |------------|---------| | React | >= 16.8.0 | | React Native | >= 0.60.0 | | react-native-webview | >= 11.0.0 |

Quick Start

import { MyopComponent } from '@myop/react-native';

export default function App() {
  return (
    <MyopComponent
      componentId="your-component-id"
      style={{ flex: 1 }}
    />
  );
}

Usage

Loading by Component ID

The simplest way to embed a Myop component:

<MyopComponent
  componentId="abc123"
  style={{ flex: 1 }}
/>

Passing Data to Components

Use the data prop to send data to your component's myop_init_interface:

const [userData, setUserData] = useState({ name: 'John', theme: 'dark' });

<MyopComponent
  componentId="abc123"
  data={userData}
  style={{ flex: 1 }}
/>

When data changes, myop_init_interface is automatically called with the new value.

Handling Component Events

Listen for events from your component's myop_cta_handler:

<MyopComponent
  componentId="abc123"
  on={(action, payload) => {
    switch (action) {
      case 'submit':
        handleSubmit(payload);
        break;
      case 'navigate':
        navigation.navigate(payload.screen);
        break;
    }
  }}
  style={{ flex: 1 }}
/>

Component Proxy API

Access the component instance for direct manipulation:

import { IMyopComponentProxy } from '@myop/react-native';

const [component, setComponent] = useState<IMyopComponentProxy | null>(null);

<MyopComponent
  componentId="abc123"
  onLoad={(proxy) => setComponent(proxy)}
  style={{ flex: 1 }}
/>

// Send data to component
component?.props.myop_init_interface({ theme: 'dark' });

// DOM manipulation
component?.element.style.set('opacity', '0.5');
component?.element.set('style.background', 'red');

// Get values (async)
const opacity = await component?.element.style.get('opacity');
const scrollTop = await component?.element.get('scrollTop');

// Lifecycle methods
component?.hide();
component?.show();
component?.dispose();

Loading & Error States

By default, no loader is shown while the component loads. The Myop-branded fallback is displayed automatically on error.

Using the Default Myop Loader

import { MyopComponent, MyopLoader } from '@myop/react-native';

<MyopComponent
  componentId="abc123"
  loader={<MyopLoader />}  // Opt-in to default Myop loader
  fadeDuration={300}
  style={{ flex: 1 }}
/>

Custom Loading State

Provide your own loading component:

import { ActivityIndicator, View } from 'react-native';

<MyopComponent
  componentId="abc123"
  loader={
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <ActivityIndicator size="large" color="#0000ff" />
    </View>
  }
  fadeDuration={300}
  style={{ flex: 1 }}
/>

Custom Error Fallback

Display a custom view when the component fails to load:

import { MyopComponent, MyopFallback } from '@myop/react-native';

<MyopComponent
  componentId="abc123"
  fallback={
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text>Unable to load component</Text>
    </View>
  }
  onError={(error) => console.error('Load failed:', error)}
  style={{ flex: 1 }}
/>

// Or use the default Myop fallback explicitly
<MyopComponent
  componentId="abc123"
  fallback={<MyopFallback />}
  style={{ flex: 1 }}
/>

Using Component Configuration

For advanced use cases, pass a full configuration object:

import { MyopComponent, IComponentInstanceConfig } from '@myop/react-native';

const config: IComponentInstanceConfig = {
  id: 'instance-1',
  componentId: 'abc123',
  componentName: 'MyComponent',
  skinSelector: {
    type: 'Dedicated',
    skin: { id: 'skin-1' }
  }
};

<MyopComponent
  componentConfig={config}
  style={{ flex: 1 }}
/>

Environment Selection

Target different deployment environments:

<MyopComponent
  componentId="abc123"
  environment="staging"  // defaults to "production"
  style={{ flex: 1 }}
/>

WebView Behavior

Control scroll, zoom, and text selection:

<MyopComponent
  componentId="abc123"
  scrollEnabled={true}      // Enable scrolling (default: false)
  zoomEnabled={true}        // Enable pinch-to-zoom (default: false)
  selectionEnabled={true}   // Enable text selection (default: false)
  style={{ flex: 1 }}
/>

Pass through any other react-native-webview prop via webViewProps — for example, to debug the screen with Safari/Chrome DevTools:

<MyopComponent
  componentId="abc123"
  webViewProps={{ webviewDebuggingEnabled: true }}
  style={{ flex: 1 }}
/>

Preloading Components

Preload components for instant rendering when they're displayed:

import { preloadComponents, isPreloaded } from '@myop/react-native';

// Preload on app startup or before navigating
await preloadComponents(['component-1', 'component-2']);

// Check if component is preloaded
if (isPreloaded('component-1')) {
  // Component will render instantly without loader
}

Configuration APIs

Configure the CloudRepository for custom endpoints or local development:

import {
  enableLocalDev,
  setCloudRepositoryUrl,
  setCloudRepository,
  setEnvironment,
  getCloudRepository
} from '@myop/react-native';

// Enable local development mode (connects to localhost:9292)
enableLocalDev();

// Use a custom endpoint
setCloudRepositoryUrl('https://custom.myop.dev');

// Set default environment for all components
setEnvironment('staging');

// Get the current CloudRepository instance
const repo = getCloudRepository();

API Reference

MyopComponent Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | componentId | string | - | Component ID to load from Myop cloud | | componentConfig | IComponentInstanceConfig | - | Full component configuration object | | data | any | - | Data passed to myop_init_interface | | on | (action: string, payload?: any) => void | - | Handler for myop_cta_handler events | | onLoad | (proxy: IMyopComponentProxy) => void | - | Callback with component proxy when loaded | | onError | (error: string) => void | - | Callback when component fails to load | | loader | ReactNode | null | Loading component (default: no loader). Use <MyopLoader /> for default Myop loader | | fallback | ReactNode | <MyopFallback /> | Error fallback component (default: Myop-branded fallback) | | fadeDuration | number | 200 | Loader fade-out duration in ms | | environment | string | "production" | Target environment | | preview | boolean | false | Load preview version of component | | scrollEnabled | boolean | false | Enable WebView scrolling | | zoomEnabled | boolean | false | Enable pinch-to-zoom | | selectionEnabled | boolean | false | Enable text selection | | webViewProps | WebViewProps | - | Extra props forwarded to the underlying <WebView> (e.g. { webviewDebuggingEnabled: true }). Controlled props (ref, source, onMessage) can't be overridden | | style | StyleProp<ViewStyle> | - | Container styles |

Either componentId or componentConfig must be provided.

Exported Components

| Component | Description | |-----------|-------------| | MyopComponent | Main component for embedding Myop content | | MyopLoader | Default animated loading state | | MyopFallback | Default error/fallback state |

Exported Functions

| Function | Description | |----------|-------------| | preloadComponents(ids, env?, preview?) | Preload components for instant rendering | | isPreloaded(componentId, env?, preview?) | Check if a component is cached | | enableLocalDev() | Enable local development mode (localhost:9292) | | setCloudRepositoryUrl(url) | Set a custom CloudRepository URL | | setCloudRepository(repository) | Set a custom CloudRepository instance | | setEnvironment(env) | Set the default environment | | getCloudRepository() | Get the current CloudRepository instance |

Types

interface IMyopComponentProxy {
  id: string;
  props: {
    myop_init_interface: (data: any) => void;
    myop_cta_handler: ((action: string, payload?: any) => void) | null;
  };
  element: IElementProxy;
  dispose: () => void;
  hide: () => void;
  show: () => void;
  inspect: () => void;
}

interface IElementProxy {
  set: (path: string, value: any) => void;
  get: (path: string) => Promise<any>;
  style: {
    set: (property: string, value: string) => void;
    get: (property: string) => Promise<string>;
  };
}

interface IComponentInstanceConfig {
  id: string;
  componentId: string;
  componentName: string;
  skinSelector: ISkinSelectorConfig;
  nestedComponents?: IComponentInstanceConfig[];
  resolvedExperiences?: IExperience[];
  resolvedNestedComponents?: IComponentConfig[];
  [key: string]: any;
}

interface MyopLoaderRef {
  fadeOut: (duration?: number) => void;
}

License

MIT