agentsclimarketplace

Scaffold

Skill Shankulkarni/react-native-ai-plugin/plugins/rn-ai/skills/scaffold

Write better React Native code from day one - opinionated Claude Code rules, New Architecture ready.

Install
npx -y skills add Shankulkarni/react-native-ai-plugin --skill scaffold

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

One thing to look at

  • 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 creating a new React Native app from scratch -- Expo SDK 52+ managed workflow, NativeWind v4, Expo Router, React Query, zustand-x, EAS config, ESLint/Prettier/Husky.

SKILL.md

5.9 KB, ~1.7k tokens by cl100k_base, as published. Nobody here has run it

App Scaffolding

Stack

Expo SDK 52+ (managed), Expo Router v4, NativeWind v4, React Query, axios, react-hook-form + zod v4, zustand-x, Reanimated v3, Gesture Handler v2, MMKV, expo-secure-store, EAS.

Before You Start

Gather from user:

  • App name (display name + slug)
  • Bundle ID (e.g. com.myorg.myapp)
  • API base URL (or "set up later")
  • Auth type (email/password, OAuth, magic link, or none)
  • Tab structure (main tabs of the app)

Step 1: Create Expo App

bunx create-expo-app@latest MyApp --template blank-typescript
cd MyApp

Step 2: Install Core Dependencies

bunx expo install expo-router react-native-safe-area-context react-native-screens expo-linking expo-constants expo-status-bar
bunx expo install nativewind react-native-reanimated react-native-gesture-handler
bun add tailwindcss@^3.4.0
bunx expo install @tanstack/react-query axios
bunx expo install react-hook-form @hookform/resolvers zod zod-empty
bunx expo install expo-secure-store react-native-mmkv
bunx expo install expo-image
bun add zustand-x mutative

Note: Install tailwindcss separately with bun add tailwindcss@^3.4.0 — do NOT use bunx expo install tailwindcss as it resolves Tailwind v4 which NativeWind v4 does not support. NativeWind v4 requires Tailwind CSS v3.

Step 3: app.json

{
  "expo": {
    "name": "MyApp",
    "slug": "my-app",
    "version": "1.0.0",
    "scheme": "myapp",
    "newArchEnabled": true,
    "ios": {
      "supportsTablet": true,
      "bundleIdentifier": "com.myorg.myapp"
    },
    "android": {
      "adaptiveIcon": { "foregroundImage": "./assets/adaptive-icon.png" },
      "package": "com.myorg.myapp"
    },
    "plugins": [
      "expo-router",
      "expo-secure-store"
    ]
  }
}

Step 4: NativeWind v4 Setup

tailwind.config.js:

/** @type {import('tailwindcss').Config} */
module.exports = {
  content: ['./app/**/*.{js,jsx,ts,tsx}', './src/**/*.{js,jsx,ts,tsx}'],
  presets: [require('nativewind/preset')],
  theme: {
    extend: {
      colors: {
        primary: '#6366f1',
        background: '#ffffff',
      },
    },
  },
}

global.css:

@tailwind base;
@tailwind components;
@tailwind utilities;

metro.config.js:

const { getDefaultConfig } = require('expo/metro-config')
const { withNativeWind } = require('nativewind/metro')
const config = getDefaultConfig(__dirname)
module.exports = withNativeWind(config, { input: './global.css' })

babel.config.js:

module.exports = function (api) {
  api.cache(true)
  return {
    presets: [
      ['babel-preset-expo', { jsxImportSource: 'nativewind' }],
      'nativewind/babel',
    ],
  }
}

Step 5: Folder Structure

app/
├── (auth)/
│   ├── _layout.tsx
│   ├── login.tsx
│   └── register.tsx
├── (app)/
│   ├── _layout.tsx
│   └── (tabs)/
│       ├── _layout.tsx
│       └── index.tsx
├── _layout.tsx
└── +not-found.tsx

src/
├── api/
├── components/
│   ├── ui/
│   └── app/
├── hooks/
├── stores/
├── libs/
│   ├── cn.ts
│   ├── query-client.ts
│   └── axios.ts
└── types/

Step 6: Core Libs

src/libs/cn.ts:

import { clsx, type ClassValue } from 'clsx'
import { twMerge } from 'tailwind-merge'
export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)) }

src/libs/query-client.ts:

import { QueryClient } from '@tanstack/react-query'
export const queryClient = new QueryClient({
  defaultOptions: {
    queries: { staleTime: Infinity, gcTime: Infinity, retry: false, refetchOnMount: false, refetchOnWindowFocus: false },
    mutations: { retry: false },
  },
})

src/libs/axios.ts:

import axios from 'axios'
export const api = axios.create({
  baseURL: process.env.EXPO_PUBLIC_API_URL,
  timeout: 30_000,
})
// Add auth interceptor: attach token from SecureStore

Step 7: Root Layout (app/_layout.tsx)

import '../global.css'
import { QueryClientProvider } from '@tanstack/react-query'
import { Stack } from 'expo-router'
import { queryClient } from '@/libs/query-client'

export default function RootLayout() {
  return (
    <QueryClientProvider client={queryClient}>
      <Stack screenOptions={{ headerShown: false }} />
    </QueryClientProvider>
  )
}

Step 8: EAS

bun add -D eas-cli
bunx eas init
bunx eas build:configure

eas.json:

{
  "cli": { "version": ">= 12.0.0" },
  "build": {
    "development": { "developmentClient": true, "distribution": "internal" },
    "preview": { "distribution": "internal" },
    "production": { "autoIncrement": true }
  },
  "submit": {
    "production": {}
  }
}

Step 9: ESLint + Prettier + Husky

bun add -D eslint @typescript-eslint/eslint-plugin @typescript-eslint/parser prettier husky lint-staged
bunx husky init

eslint.config.js:

import tsPlugin from '@typescript-eslint/eslint-plugin'
import tsParser from '@typescript-eslint/parser'
export default [
  { files: ['src/**/*.{ts,tsx}', 'app/**/*.{ts,tsx}'], languageOptions: { parser: tsParser },
    plugins: { '@typescript-eslint': tsPlugin },
    rules: { '@typescript-eslint/no-explicit-any': 'error', 'no-console': 'error' } },
]

.prettierrc:

{ "singleQuote": true, "semi": false, "trailingComma": "all", "useTabs": true }

.husky/pre-commit:

bun run typecheck && bun run lint

Post-Scaffold Checklist

  • bun run typecheck passes
  • bunx expo start opens in Expo Go
  • newArchEnabled: true in app.json
  • (auth)/ and (app)/ layouts created
  • .env.local with EXPO_PUBLIC_API_URL (never committed)

What ships with it

Read from the repository

Just SKILL.md. No reference files, no scripts.

Keep looking

Skills are one crate of 326,970. 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.