Skip to content

Latest commit

Β 

History

124 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

cover

πŸ“± React Native Template

react native react node license

An opinionated production starter for React Native apps β€” strict TypeScript, Redux Toolkit, stack navigation, MMKV-backed persistence, Unistyles theme tokens, i18n, shared UI primitives, and small app-facing adapters around native capabilities.

It ships an AGENTS.md / CLAUDE.md pair, four vendored skills, and a plugin registration for the rest, so coding agents get the project's conventions and procedures the moment you generate an app. See πŸ’– Companion skills.

npx @react-native-community/cli@latest init MyApp \
  --template https://github.com/ltatarev/react-native-template.git

⚑ Usage

Make sure your machine is ready for React Native development, then create a new app from the template:

npx @react-native-community/cli@latest init MyApp --template https://github.com/ltatarev/react-native-template.git

Replace MyApp with your app name. If npx asks to install @react-native-community/cli, confirm with y.

Do not use npx react-native init; React Native now treats that command as deprecated and exits before creating the app.

Current template runtime:

  • React Native 0.87.0
  • React 19.2.7
  • Node.js >=22.11.0
  • Yarn 4.17.0
  • Ruby 2.7.7
  • CMake for iOS/Hermes pods

πŸ› οΈ Setup

From a generated app or the template/ directory in this repository:

corepack enable
yarn
bundle install
yarn install-pods

Run the app:

yarn start
yarn ios
yarn android

πŸ“œ Scripts

Script Purpose
yarn lint Run ESLint flat config.
yarn tsc Run strict TypeScript without emitting files.
yarn test:unit Run the unit Jest harness.
yarn madge Check circular dependencies.
yarn madge:image Generate a dependency graph image.
yarn sanity Run lint, TypeScript, and Madge checks.
yarn install-pods Install iOS Pods through Bundler.

πŸ—οΈ Architecture

src/
β”œβ”€β”€ common/            # Pure shared hooks, types, helpers
β”œβ”€β”€ modules/
β”‚   β”œβ”€β”€ design-system/ # Primitive gallery (development only)
β”‚   β”œβ”€β”€ feature-flag/  # Typed boolean gates
β”‚   β”œβ”€β”€ home/          # Neutral reference feature
β”‚   β”œβ”€β”€ main/          # App shell and root navigator
β”‚   β”œβ”€β”€ navigation/    # Route helpers, screen options, navigation ref
β”‚   β”œβ”€β”€ onboarding/    # First-run gate
β”‚   β”œβ”€β”€ redux/         # Store, persistor, typed hooks
β”‚   └── settings/      # Appearance and about
β”œβ”€β”€ theme/
β”‚   β”œβ”€β”€ redux/     # Persisted appearance mode
β”‚   β”œβ”€β”€ ui/        # Shared UI primitives
β”‚   β”œβ”€β”€ gutter.ts  # Device metrics
β”‚   β”œβ”€β”€ scales.ts  # Spacing, radii, type, motion, size, z-index
β”‚   β”œβ”€β”€ styles.ts
β”‚   β”œβ”€β”€ theme.ts   # The two palettes
β”‚   β”œβ”€β”€ types.ts
β”‚   └── unistyles.ts
└── utils/
    β”œβ”€β”€ app-state/
    β”œβ”€β”€ error-handling/
    β”œβ”€β”€ haptic-feedback/
    β”œβ”€β”€ logger/
    β”œβ”€β”€ services/
    β”œβ”€β”€ storage/
    └── toast.tsx

i18n/
β”œβ”€β”€ en_EN.json
β”œβ”€β”€ index.ts
└── resources.ts

The codebase is package-by-feature. Feature modules live under src/modules/<feature> and expose their public API through src/modules/<feature>/index.ts.

Cross-module imports should use the public module surface:

import { HomeScreen } from 'modules/home';

Do not reach into another module's internals:

import { HomeScreen } from 'modules/home/screens/HomeScreen';

ESLint enforces this with no-restricted-imports.

🧭 Aliases

Aliases are configured in both TypeScript and Babel.

Alias Resolves to
assets/* src/assets/*
common/* src/common/*
modules/* src/modules/*
theme/* src/theme/*
utils/* src/utils/*

🎨 Styling

Styling uses react-native-unistyles.

  • Import StyleSheet from react-native-unistyles.
  • Keep shared primitives in src/theme/ui.
  • Use tokens from theme.ts (the two palettes) and scales.ts (gutter, typography, radii, motion, size, shadow, z-index).
  • Avoid color literals in feature UI.
  • Appearance is system / light / dark, persisted in theme/redux and pushed into Unistyles by useAppearanceSync.

Example:

const styles = StyleSheet.create(theme => ({
  title: {
    color: theme.colors.text,
    fontSize: theme.typography.fontSize.lg,
    marginBottom: theme.gutter.md,
  },
}));

πŸ—ƒοΈ State And Persistence

  • Root store setup lives in src/modules/redux.
  • Use useAppDispatch and useAppSelector from modules/redux.
  • Feature state uses Redux Toolkit slices and selectors.
  • Redux persistence uses MMKV through utils/storage.

🌍 Internationalization

i18n is initialized from src/index.ts.

  • Resources live in i18n/en_EN.json.
  • Components use useTranslation() from react-i18next.
  • User-facing feature text should render through t(...).

πŸ”Œ Adapters

Feature code should not import native SDKs directly. Use the app-facing adapters in src/utils:

  • utils/storage β€” Redux Persist storage, plus appPreferences for values read before the first frame
  • utils/toast
  • utils/logger
  • utils/error-handling
  • utils/haptic-feedback
  • utils/app-state β€” foreground/background transitions
  • utils/services β€” platform checks, app version

docs/growing-the-app.md describes the shape each of the common next capabilities takes β€” bottom tabs, native sheets, notifications, SQLite, image picking, widgets, subscriptions β€” none of which the template installs.

🧱 UI primitives

theme/ui ships the set every app re-derives otherwise:

Screen, Text, View, Row, Touchable, Button, IconButton, Icon, Card, Divider, Pill, SectionHeader, EmptyState, Skeleton, ProgressBar, Switch, TextInput, Sheet, ConfirmDialog, LoadingScreen, StatusBar, KeyboardAwareScrollView, plus the toast viewport.

modules/design-system's gallery screen renders all of them in the live theme β€” add a new primitive there, and review both themes in one pass. Motion presets (usePressScale, useModalPresence) come from theme/ui/motion.ts and every animation honors Reduce Motion.

βž• Adding A Module

  1. Create src/modules/<name>/const.ts with MODULE_NAME and route names built from RouteService.constructRouteName.
  2. Create src/modules/<name>/index.ts as the public surface.
  3. Add screens under screens/, built from theme/ui primitives.
  4. Add Redux slice/selectors under redux/ if the module owns state.
  5. Register the reducer in modules/redux/store.ts when needed.
  6. Register routes in modules/main/navigator.tsx.
  7. Add text keys to i18n/en_EN.json.
  8. Export only the API other modules need from the module barrel.

A route name two modules both need goes in modules/navigation/routes.ts, which depends on nothing β€” that is what keeps sibling features from importing each other just to navigate.

πŸ€– Agent context

Template-specific guidance ships inside the project so agents pick it up from a generated app's root:

  • template/AGENTS.md / template/CLAUDE.md β€” conventions, anti-patterns, commands
  • template/CONTEXT.md β€” vocabulary and module boundaries
  • template/docs/growing-the-app.md β€” the shape each common next capability takes
  • template/.claude/skills/ β€” vendored skills: add-feature, build-ui, validate-change, rozenite-agent
  • template/.claude/settings.json β€” registers the rest of the library as a plugin

See πŸ’– Companion skills for how the two fit together.

πŸ’– Companion skills

ltatarev/skills β€” the adora plugin β€” is a Claude Code marketplace of agent skills that encode this template's conventions: building UI, scaffolding feature modules, writing tests, validating changes, iOS widgets, launch screens, plus a commit and ticket workflow set. Paired with this template they need no configuration β€” the module anatomy, the theme/ui kit, and the Jest unit harness they target are all already here.

A generated app gets them two ways.

Vendored. add-feature, build-ui and validate-change are copied into template/.claude/skills/ and pinned in template/skills-lock.json, alongside rozenite-agent for the live-debugging setup. They are committed, so they work on a fresh clone with no install step. Refresh them with:

npx skills@latest update

As a plugin. template/.claude/settings.json registers the adora-skills marketplace and enables the adora plugin, so opening a generated app in Claude Code prompts you to trust and install the full library. It then resolves as /adora:<skill-name> β€” write-tests, verify, commit-changes, gitmoji, unistyles, truesheet-usage, domain-model, grill-plan, ticket-shaping, implement-ticket, ios-widget, bootsplash, xcode-cloud. By hand:

/plugin marketplace add ltatarev/skills
/plugin install adora@adora-skills
/plugin marketplace update adora-skills

On a harness other than Claude Code, install the same library with the skills.sh picker β€” see template/.agents/README.md:

npx skills@latest add ltatarev/skills

πŸ’€ License

MIT Β© ltatarev

About

πŸ’» React Native JS template featuring popular libraries

Topics

Resources

Code of conduct

Contributing

Stars

0 stars

Watchers

1 watching

Forks

Used by

Contributors

Languages