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

@yahoo/uds-create-sidecar

v5.56.2

Published

Readme

UDS Create Sidecar

@yahoo/uds-create-sidecar lets an Expo development build render Create previews inside the customer's own app. The preview therefore uses the same native packages, configuration, and package versions as that app.

The package contains the existing Sidecar pairing UI, preview-room client, authenticated and integrity-checked bundle loader, and renderer host. The only required component prop is an explicit module registry:

Create browser ── signed room token ──> UDSCreateSidecar
                                           │
Customer app ── exact modules + versions ──┘
                                           │
                                           └──> real app dependencies

The standalone app in apps/create-sidecar consumes this same package and is the reference implementation.

Requirements

This first package targets Expo SDK 57 development builds with React Native 0.86. It is not supported in Expo Go because registered packages may contain native code.

Install the host and the shared JSON renderer as development dependencies:

bun add --dev --exact @yahoo/uds-create-sidecar @json-render/react
bunx expo install react-native-safe-area-context

Install and configure every native package used by the design system in the usual way. Sidecar does not replace that package's native setup. UDSCreateSidecar must be rendered below the app's SafeAreaProvider.

What the package expects from the app

Every package Sidecar needs from the app is a declared peer dependency, so a missing one is reported at install time:

  • react, react-native, react-native-safe-area-context, and expo are the app's own copies. Sidecar renders its pairing UI with them.
  • @json-render/react is the renderer every Create preview bundle imports. Sidecar never imports it itself, but the registry requires it as a module, so the app must install it and register it.

What the package carries

The preview-room client is built on Yjs and the Hocuspocus provider. Both are compiled into the package, together with their lib0 and y-protocols internals, so the app does not install them and the app's own versions never matter. Compiling them in also lets the package replace lib0's Web Crypto binding with a small shim over @noble/hashes, the package's one runtime dependency, so React Native needs no Web Crypto polyfill. Yjs uses those values only for client and document identifiers.

An app that also uses Yjs sees one console error the first time the Sidecar screen loads, Yjs was already imported, shown as a LogBox error in a development build. It is Yjs noticing a second copy of itself. Sidecar's documents never cross into the app's Yjs, so the two copies never meet and the message can be dismissed.

1. Define the host registry

Create one module that statically imports everything a downloaded preview may use. Metro must see these imports when it builds the app; downloaded JavaScript cannot discover or import an arbitrary installed native package later.

This example exposes react-native-maps, a package that is intentionally not built into the standalone Sidecar:

// src/create-sidecar-registry.ts
import * as JsonRenderReact from "@json-render/react";
import { createUDSCreateSidecarRegistry } from "@yahoo/uds-create-sidecar/registry";
import * as React from "react";
import * as ReactJsxRuntime from "react/jsx-runtime";
import * as ReactNative from "react-native";
import * as ReactNativeMaps from "react-native-maps";
import appPackage from "../package.json";

export const createSidecarRegistry = createUDSCreateSidecarRegistry({
  hostName: "Acme mobile app",
  hostVersion: appPackage.version,
  modules: {
    "@json-render/react": JsonRenderReact,
    react: React,
    "react/jsx-runtime": ReactJsxRuntime,
    "react-native": ReactNative,
    "react-native-maps": ReactNativeMaps,
  },
  packageVersions: {
    ...appPackage.dependencies,
    ...appPackage.devDependencies,
  },
});

The versions for every exposed package must be exact strings such as 1.2.3, not ranges such as ^1.2.3. Pin those dependencies in package.json or provide exact versions from the app's lockfile. The registry rejects a missing or non-exact version immediately.

Subpath imports must be registered separately, but they use the package root's version. For example, registering react/jsx-dev-runtime still uses the react version.

How Create checks the registry

Each preview build lists the packages it imports, the version the design system declares for each, and the exact import paths it reads. The connected host advertises the registry, and Create and the phone run the same comparison:

  • A required package or import path that is not registered is missing.
  • A registered version whose major or minor differs from the required version is a mismatch. Patch versions may differ.

While the phone is connected, Create's phone controls name the packages the host cannot provide. The phone repeats the check before evaluating a bundle and refuses with an error naming the package and, for a mismatch, both versions. Either side can move: install the version the design system declares, or update the version the design system declares for that package.

2. Add a development-only route

The app, rather than the component, owns the production gate. This lets the standalone Sidecar remain a normal release build while a customer app can make the route impossible to activate in production.

For Expo Router, guard the package load as well as the rendered route:

// app/create-preview.tsx
import { Redirect } from "expo-router";
import { createSidecarRegistry } from "../src/create-sidecar-registry";

declare const require: (
  id: "@yahoo/uds-create-sidecar",
) => typeof import("@yahoo/uds-create-sidecar");

export default function CreatePreviewRoute() {
  if (!__DEV__) return <Redirect href="/" />;

  const { UDSCreateSidecar } = require("@yahoo/uds-create-sidecar");
  return <UDSCreateSidecar registry={createSidecarRegistry} />;
}

Use the equivalent compile-time development constant and production fallback with another router. Do not gate only a navigation link: the route itself must return before loading or rendering Sidecar. The package test compiles this pattern with __DEV__ set to false and verifies that the Sidecar reference is removed from the route's execution path.

The two entry points are split for this gate. @yahoo/uds-create-sidecar/registry holds only the registry builder, imports nothing, and is safe to import at module top level in every build, including production. The root entry holds the pairing UI, the preview-room client, and the compiled-in Yjs, so it stays behind the compile-time check.

3. Pair with Create

Open the development route. UDSCreateSidecar uses production Create by default and shows the same origin chooser, short-code pairing, status UI, disconnect behavior, and full-screen design preview as the standalone app. A custom origin remains selected while the component is mounted; a new launch returns to production.

Full-screen designs fill the device viewport and own their safe-area layout. Sidecar hides the native status bar while showing a design and restores the host's status bar when returning to settings or component previews. The floating Sidecar settings button stays inside the device's safe area.

It also accepts an existing Sidecar deep link when the host app routes that URL to the component; short-code pairing is the portable default for an embedded host with its own URL scheme.

When the host router mounts this screen from a deep link, pass the route values to the component. This avoids relying on a link event that may have fired before the route mounted:

import type { UDSCreateSidecarDeepLink } from "@yahoo/uds-create-sidecar";
import { useLocalSearchParams } from "expo-router";

const params = useLocalSearchParams<UDSCreateSidecarDeepLink>();
const deepLink =
  params.origin && params.room && params.token && params.ws
    ? {
        origin: params.origin,
        room: params.room,
        token: params.token,
        ws: params.ws,
      }
    : undefined;

return (
  <UDSCreateSidecar registry={createSidecarRegistry} deepLink={deepLink} />
);

Create's QR code uses the uds-create-sidecar scheme. An embedded app must route that scheme to its development-only preview screen to use QR pairing. Apps that do not own that route should use the short pairing code.

In Create, open Connect phone, choose Connect Sidecar, and enter the code from the app. The embedded host advertises the registry's exact package versions through the existing preview protocol; no protocol or token changes are required.

Security boundary

The host downloads a bundle only from the selected Create origin, sends the room-scoped bearer token, limits the response to 5 MiB, and verifies the manifest's SHA-256 hash before evaluation. Module resolution is limited to the explicit registry.

This is not a JavaScript sandbox. An authorized Create bundle runs inside the development app's JavaScript process and can use normal JavaScript globals in addition to registered modules. Expose only modules intended for preview, use only a trusted Create deployment, and keep the route hard-disabled in production.