A modern Expo template with a robust stack for building React Native applications using best practices and high-performance libraries.
- π§° Expo Router - File-based routing with nested tabs and drawer navigation
- π Zustand - Simple, fast state management
- β Zod - TypeScript-first schema validation
- π Expo Secure Store - Secure local storage
- π¨ React Native Paper - Material Design components and icons
- πΎ Drizzle ORM - SQLite database with type-safe queries
- β‘ @shopify/flash-list - High-performance lists
- π§© @paralleldrive/cuid2 - Collision-resistant IDs
- π Biome - Fast linting and formatting
- π Markdown Rendering - Build-time markdown to component conversion
- π Environment Variables - Runtime configuration with Expo's EXPO_PUBLIC_ system
bunx create-expo-app --template consensual-expo-template
-
Install dependencies
cd your-app-name bun install
-
Set up environment variables
cp .env.example .env
Then edit
.env
with your own values. -
Start the app
bun run start
-
Open on your preferred platform
# iOS bun run ios # Android bun run android # Web bun run web
your-app/
βββ app/ # Main application code (Expo Router)
β βββ (tabs)/ # Bottom tab navigator screens
β β βββ index.tsx # Home screen
β β βββ explore.tsx # Explore screen
β βββ about/ # About screen (accessible via drawer)
β βββ examples/ # Example screens
β βββ settings/ # Settings screen (accessible via drawer)
β βββ _layout.tsx # Root layout with drawer navigator
βββ assets/ # Static assets
β βββ fonts/ # Custom fonts
β βββ images/ # App icons and images
β βββ markdown/ # Markdown content files
β βββ generated/ # Auto-generated content
βββ components/ # Reusable components
β βββ examples/ # Example components
β βββ forms/ # Form components
β βββ ui/ # UI components
βββ constants/ # App constants
βββ contexts/ # React contexts
βββ db/ # Database configuration
β βββ migrations/ # Database migrations
β βββ schema.ts # Database schema
βββ hooks/ # Custom React hooks
βββ lib/ # Utility functions
βββ schemas/ # Zod validation schemas
βββ scripts/ # Build and utility scripts
βββ stores/ # Zustand stores
βββ .env.example # Example environment variables
βββ .env # Your environment variables (gitignored)
βββ CLAUDE.md # AI Assistant guidelines
- Drawer Navigation - Main navigation with hamburger menu
- Tab Navigation - Bottom tabs for main app sections
- Dark Mode Support - Automatic theme detection with React Native Paper
- State Management - Zustand for global state
- Form Validation - Zod for schema validation
- Optimized Lists - FlashList for better performance
- Database Support - SQLite persistence with Drizzle ORM
- Environment Variables - Runtime configuration using Expo's public vars
- Feature Flags - Toggle features via environment variables
- Markdown Rendering - Convert markdown files to React Native components
# Start development server
bun run start
# Run on iOS
bun run ios
# Run on Android
bun run android
# Run on Web
bun run web
# Run linting
bun run lint
# Run formatting
bun run format
# Run tests
bun run test
# Generate markdown components
bun run generate-content
The template includes a build-time markdown-to-component conversion system that allows you to:
- Convert markdown files to React Native components
- Display rich formatted content with proper styling
- Support for code blocks with syntax highlighting
- Proper theme support for both light and dark mode
- Tables, lists, links, and other markdown elements
Markdown files are processed during build time, which means:
- No runtime parsing overhead
- Type-safe components
- Optimized for performance
To add a new markdown file to be converted:
- Add your markdown file to
/assets/markdown/
- Update the
MARKDOWN_SOURCES
array in/scripts/generate-markdown-components.js
- Run
bun run generate-content
The generated components can be imported and used with theme support:
import { ReadmeContent } from '@/assets/generated/ReadmeContent';
// or import { ExampleMarkdownContent } from '@/assets/generated/ExampleMarkdownContent';
function MyScreen() {
const theme = useTheme();
return <ReadmeContent theme={theme} />;
}
The template uses environment variables for configuration, which are loaded from a .env
file. This allows you to:
- Keep sensitive data out of your codebase
- Customize the app for different environments (dev, staging, production)
- Easily switch between different configurations
The template uses two types of environment variables:
- Build-time variables - Used during app building only
- Runtime variables - Accessible in your app code (prefixed with
EXPO_PUBLIC_
)
Variable | Description | Default |
---|---|---|
EXPO_APP_NAME |
The display name of your app | Consensual Expo App |
EXPO_APP_SLUG |
The unique slug for your app on Expo | consensual-template |
EXPO_APP_VERSION |
The version of your app | 1.0.0 |
EXPO_APP_OWNER |
Your Expo account name | anonymous |
EXPO_PROJECT_ID |
Your Expo project ID | your-project-id |
EXPO_UPDATES_URL |
URL for Expo updates | https://u.expo.dev/your-project-id |
ANDROID_PACKAGE_NAME |
Android package name | com.consensual.template |
URL_SCHEME |
URL scheme for deep linking | consensual |
Variable | Description | Default |
---|---|---|
EXPO_PUBLIC_API_URL |
API base URL | https://api.example.com |
EXPO_PUBLIC_DB_NAME |
Database file name | app.db |
EXPO_PUBLIC_ENABLE_ANALYTICS |
Enable analytics | false |
EXPO_PUBLIC_ENABLE_CRASH_REPORTING |
Enable crash reporting | false |
EXPO_PUBLIC_LOG_LEVEL |
Logging level (debug, info, warn, error) | debug (dev) or info (prod) |
EXPO_PUBLIC_ENVIRONMENT |
Current environment | development or production |
Environment variables can be accessed in your app using the Env
constant:
import { Env } from '@/constants/Env';
// App information
console.log(Env.app.name); // App name
console.log(Env.app.version); // App version
console.log(Env.isDevelopment); // Whether running in dev mode
// Configuration
console.log(Env.api.baseUrl); // API URL
console.log(Env.db.name); // Database name
console.log(Env.environment); // Current environment
// Feature flags
console.log(Env.features.enableAnalytics); // Analytics enabled
console.log(Env.features.enableCrashReporting); // Crash reporting enabled
// Logger configuration
console.log(Env.logger.level); // Log level
The template supports different environment files:
.env # Default environment, used in all builds
.env.local # Local overrides (not committed to git)
.env.development # Development environment
.env.production # Production environment
Environment-specific files take precedence over the default .env
file when the corresponding environment is active.
The template includes several example screens to help you get started:
- Database Example - CRUD operations with Drizzle ORM and SQLite
- Validation Example - Form validation using Zod schemas
- Zustand Example - State management with persistence
- Markdown Example - Rendering markdown content with theme support
These examples demonstrate best practices for common tasks in React Native apps. They can be accessed from the Examples section in the app.