agentsclimarketplace

Example app

Skill Shankulkarni/RN-Lib-Claude/plugins/rn-lib-claude/skills/example-app

Ship production-grade RN libraries faster — scaffold, audit, and publish with Claude Code.

Install
npx -y skills add Shankulkarni/RN-Lib-Claude --skill example-app

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use when working on the Expo example app inside a React Native library repo — demo patterns, Expo SDK 52+, dev client vs Expo Go, metro config for local resolution, and testing the library in a real app context.

SKILL.md

5.2 KB, as published. Nobody here has run it

Example App

Every library ships with an Expo example app in example/. Expo SDK 52+, newArchEnabled: true always.

Expo Go vs Dev Client — Know This First

Library typeRuns in Expo Go?How to run
JS-only (--type library)✅ Yesexpo start → scan QR
TurboModule (--type turbo-module)❌ No — needs native codeexpo run:ios / expo run:android
Fabric view (--type fabric-view)❌ No — needs native codeexpo run:ios / expo run:android

Native libraries require a dev client build. Expo Go cannot load custom native modules.

Structure

example/
├── app/
│   ├── _layout.tsx       ← root layout
│   └── index.tsx         ← main demo screen
├── components/           ← demo-only components
├── app.json
├── package.json
├── metro.config.js       ← required for native libraries
└── tsconfig.json

app.json

{
  "expo": {
    "name": "MyLibExample",
    "slug": "my-lib-example",
    "version": "1.0.0",
    "orientation": "portrait",
    "newArchEnabled": true,
    "ios": { "supportsTablet": true },
    "android": { "adaptiveIcon": { "foregroundImage": "./assets/adaptive-icon.png" } }
  }
}

newArchEnabled: true always — no exceptions.

package.json (example)

JS-only library

{
  "name": "my-lib-example",
  "private": true,
  "scripts": {
    "start": "expo start",
    "ios": "expo run:ios",
    "android": "expo run:android"
  },
  "dependencies": {
    "expo": "~52.0.0",
    "expo-router": "~4.0.0",
    "react": "18.3.1",
    "react-native": "0.76.x",
    "my-lib": "file:../"
  }
}

Native library (TurboModule or Fabric view)

{
  "name": "my-lib-example",
  "private": true,
  "scripts": {
    "start": "expo start --dev-client",
    "ios": "expo run:ios",
    "android": "expo run:android"
  },
  "dependencies": {
    "expo": "~52.0.0",
    "expo-dev-client": "~4.0.0",
    "expo-router": "~4.0.0",
    "react": "18.3.1",
    "react-native": "0.76.x",
    "my-lib": "file:../"
  }
}

expo-dev-client enables running custom native code without ejecting. Always include it for native libraries.

Metro Config (native libraries — required)

example/metro.config.js:

const { getDefaultConfig } = require('expo/metro-config')
const path = require('path')

const config = getDefaultConfig(__dirname)
const root = path.resolve(__dirname, '..')

config.watchFolders = [root]
config.resolver.nodeModulesPaths = [
  path.resolve(__dirname, 'node_modules'),
  path.resolve(root, 'node_modules'),
]

module.exports = config

Without this, Metro cannot resolve the local file:../ library on native builds.

Demo Screen Pattern

import { ScrollView, StyleSheet, Text, View } from 'react-native'
import { MyComponent, useMyHook } from 'my-lib'

export default function App() {
  return (
    <ScrollView contentContainerStyle={styles.container}>
      <Section title="Basic Usage">
        <MyComponent label="Default" />
      </Section>

      <Section title="Variants">
        <MyComponent variant="primary" label="Primary" />
        <MyComponent variant="secondary" label="Secondary" />
      </Section>

      <Section title="Edge Cases">
        <MyComponent label="" />
        <MyComponent label="Very long label that might overflow the container" />
      </Section>
    </ScrollView>
  )
}

function Section({ title, children }: { title: string; children: React.ReactNode }) {
  return (
    <View style={styles.section}>
      <Text style={styles.sectionTitle}>{title}</Text>
      <View style={styles.sectionContent}>{children}</View>
    </View>
  )
}

const styles = StyleSheet.create({
  container: { padding: 16, gap: 24 },
  section: { gap: 8 },
  sectionTitle: { fontSize: 13, fontWeight: '600', color: '#666', textTransform: 'uppercase' },
  sectionContent: { gap: 8 },
})

Running

JS-only library

cd example && bun install
bun run start   # scan QR with Expo Go

Native library

cd example && bun install
bun run ios     # builds native + launches simulator
bun run android # builds native + launches emulator

First native build is slow (CocoaPods install + Gradle). Subsequent builds are fast.

Rules

  • Demo every exported component and hook — no hidden APIs
  • Show variants, edge cases, and interactive examples
  • Use file:../ to reference local library — never a versioned dep
  • Keep example app simple — no extra state management, no network calls
  • newArchEnabled: true always in app.json
  • JS-only libraries must work in Expo Go (no native deps)
  • Native libraries must include expo-dev-client
  • Metro config required for all native libraries

Checklist

  • Every export has a demo
  • newArchEnabled: true in app.json
  • JS-only: runs in Expo Go
  • Native: expo-dev-client in dependencies, start script uses --dev-client
  • Native: Metro config set up for local library resolution
  • No hardcoded data that should be props

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.