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.
npx -y skills add Shankulkarni/RN-Lib-Claude --skill example-appAssembled 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 type | Runs in Expo Go? | How to run |
|---|---|---|
JS-only (--type library) | ✅ Yes | expo start → scan QR |
TurboModule (--type turbo-module) | ❌ No — needs native code | expo run:ios / expo run:android |
Fabric view (--type fabric-view) | ❌ No — needs native code | expo 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: truealways inapp.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: trueinapp.json - JS-only: runs in Expo Go
- Native:
expo-dev-clientin dependencies,startscript uses--dev-client - Native: Metro config set up for local library resolution
- No hardcoded data that should be props