Skip to content

3.0.0 (Dec 1, 2025)

Choose a tag to compare

@Teczer Teczer released this 01 Dec 13:44
· 7 commits to main since this release

🎉 Fast Expo App v3.0.0 - Dual Styling & Enhanced Architecture

🚀 Major Release - Dual Styling System

This is a major release introducing a powerful dual styling system, mandatory MMKV storage, and significant architectural improvements. Choose between NativeWind v4 or Unistyles v3 during project creation!


✨ What's New

🎨 Dual Styling System (NEW!)

Choose your preferred styling solution during CLI setup:

NativeWind v4 🌊

  • Tailwind CSS for React Native
  • Utility-first approach with className
  • 2-theme system (light/dark)
  • MMKV-persisted theme preferences
  • Centralized color utilities in utils/colors.ts
  • Perfect for developers familiar with Tailwind

Unistyles v3 💎

  • Type-safe styling with StyleSheet.create
  • 3-theme system (light/dark/premium)
  • Runtime theme switching with full TypeScript support
  • MMKV-persisted theme preferences
  • Breakpoints and responsive design
  • Better performance for complex UIs
  • Theme configs in constants/themes.ts

💾 Mandatory MMKV Storage

MMKV is now always included (no longer optional):

  • ~30x faster than AsyncStorage
  • Nitro Modules for native performance
  • Used for theme persistence
  • Zustand integration (optional)
  • React Query persistence (optional)

🌓 Enhanced Theme System

For Unistyles:

// 3 themes with smooth cycling
light  dark  premium  light

// Haptic feedback on theme change
// MMKV persistence
// Runtime switching with UnistylesRuntime

For NativeWind:

// 2 themes with toggle
light  dark

// Haptic feedback on theme change
// MMKV persistence
// usePersistedColorScheme hook

🏗️ Better Project Architecture

New Structure:

your-app/
├── lib/                      # Core utilities
│   ├── mmkvStorage.ts       # MMKV storage (mandatory)
│   ├── query-client.ts      # React Query config
│   ├── use-persisted-color-scheme.ts  # NativeWind theme hook
│   └── zustand.ts           # Zustand store (optional)
├── providers/                # React providers (NEW!)
│   └── query-provider.tsx   # React Query provider
├── utils/                    # Utilities (NEW!)
│   └── colors.ts            # Color utilities (NativeWind)
├── constants/                # Constants (NEW!)
│   └── themes.ts            # Theme configs (Unistyles)
├── components/               # React components
│   ├── container.tsx        # Container with SafeArea
│   ├── theme-toggle.tsx     # Theme toggle button
│   └── external-link.tsx    # External link component
└── app/                      # Expo Router screens

Key Changes:

  • providers/ folder for React providers (moved from lib/)
  • utils/ folder for utility functions
  • constants/ folder for theme configurations
  • ✅ All components use kebab-case naming
  • ✅ Conditional file generation based on styling choice

🔧 Conditional Generation

The CLI now generates only what you need:

  • ✅ NativeWind files OR Unistyles files (not both)
  • ✅ Module-specific files only if selected
  • ✅ Clean output with no unused code
  • ✅ Proper imports and configurations

⚡ Performance Enhancements

New dependencies for better UX:

  • react-native-worklets - High-performance animations
  • expo-haptics - Native haptic feedback on theme toggle
  • react-native-edge-to-edge - Modern edge-to-edge display
  • Optimized imports - Absolute paths with @/ prefix

🔄 Breaking Changes from v2.x

1. MMKV is Mandatory

  • ❌ No longer optional in CLI
  • ✅ Always included by default
  • Used for theme persistence

2. Styling Choice Required

  • ❌ Can't skip styling selection
  • ✅ Must choose NativeWind OR Unistyles

3. File Structure Changed

  • lib/query-provider.tsxproviders/query-provider.tsx
  • lib/utils.tsutils/ (for NativeWind colors)
  • New constants/ folder for theme configs

4. Theme System Redesigned

  • ✅ MMKV persistence for both styling options
  • ✅ Haptic feedback on theme change
  • ✅ 3 themes for Unistyles (light/dark/premium)
  • ✅ 2 themes for NativeWind (light/dark)

5. Component Naming

  • ❌ PascalCase: ToggleTheme.tsx, Container.tsx
  • ✅ kebab-case: theme-toggle.tsx, container.tsx

6. Unistyles Configuration

  • unistyles.ts moved to project root
  • index.js entry point for proper initialization
  • package.json main field updated to index.js

📦 Migration from v2.x

If you have an existing v2.x project:

  1. Generate a new v3.0.0 project

    bunx fast-expo-app@latest
  2. Copy your custom code

    • Move screens from app/
    • Copy custom components
    • Migrate business logic
  3. Update imports

    // Old
    import { QueryProvider } from '@/lib/query-provider';
    
    // New
    import { QueryProvider } from '@/providers/query-provider';
  4. Adopt new theme system

    • Use MMKV for theme persistence
    • Update theme toggle components
    • Leverage new theme configurations

🎯 Features Comparison

Feature NativeWind v4 Unistyles v3
Styling Utility classes StyleSheet API
Type Safety ⚠️ Limited ✅ Full TypeScript
Themes 2 (light/dark) 3 (light/dark/premium)
Performance ✅ Good ✅ Excellent
Learning Curve Easy (Tailwind) Medium
Bundle Size Larger Smaller
Breakpoints ✅ Yes ✅ Yes
Persistence ✅ MMKV ✅ MMKV
Haptic Feedback ✅ Yes ✅ Yes

🛠️ Technical Improvements

CLI Enhancements

  • ✅ Conditional file generation based on styling choice
  • ✅ Better error handling and validation
  • ✅ Improved module management
  • ✅ Cleaner output with no unused files

Code Quality

  • ✅ Full TypeScript strict mode
  • ✅ ESLint + Prettier pre-configured
  • ✅ Consistent naming conventions
  • ✅ Better file organization

Documentation

  • ✅ Updated AGENTS.md with v3.0.0 details
  • ✅ Comprehensive README.md
  • ✅ New npm package README
  • ✅ Migration guide included

📊 Stats

  • 169 commits since v2.0.1
  • Dual styling system with 2 complete implementations
  • 3-theme support for Unistyles
  • MMKV integration for both styling options
  • Conditional generation for clean projects
  • Documentation: 3,000+ lines updated

🎨 Code Examples

NativeWind Theme Toggle

import { usePersistedColorScheme } from '@/lib/use-persisted-color-scheme';

export function ThemeToggle() {
  const { colorScheme, setColorScheme } = usePersistedColorScheme();
  
  const toggle = () => {
    Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
    setColorScheme(colorScheme === 'light' ? 'dark' : 'light');
  };
  
  return <Pressable onPress={toggle}>...</Pressable>;
}

Unistyles Theme Cycling

import { UnistylesRuntime } from 'react-native-unistyles';
import { mmkvStorage } from '@/lib/mmkvStorage';

const handleThemeChange = () => {
  Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light);
  
  const nextTheme = currentTheme === 'light' ? 'dark' 
    : currentTheme === 'dark' ? 'premium' 
    : 'light';
  
  mmkvStorage.setItem('app-theme', nextTheme);
  UnistylesRuntime.setTheme(nextTheme);
};

🙏 Acknowledgments

Special thanks to:

  • NativeWind team for v4 improvements
  • Unistyles team for v3 architecture
  • MMKV for blazing-fast storage
  • Community feedback and contributions

🔗 Links


📦 Installation

# Using Bun (recommended)
bunx fast-expo-app@latest

# Or using npm
npx fast-expo-app@latest

🎉 What's Next?

  • 🔮 More optional modules (Sentry, Analytics, etc.)
  • 🎨 Additional theme presets
  • 📱 More component examples
  • 🧪 E2E testing setup option
  • 🌍 i18n support

Full Changelog: v2.0.1...v3.0.0


Made with ♥ by Teczer

Star the repo if you find it useful!