How I Structure My Cross-Platform Projects (Flutter + React Native)

When working on multiple mobile projects using both Flutter and React Native, one of the biggest challenges is maintaining clean, scalable, and consistent folder structures. Over the past few years, I’ve refined a project structure that works well across both platforms β€” making it easier to onboard new devs, scale features, and manage codebases long-term.

In this post, I’ll walk you through how I organize my cross-platform apps, what patterns I follow, and tips to keep things modular whether you’re using Dart or JavaScript/TypeScript.

🧱 Why Project Structure Matters

A well-structured codebase:

  • 🧠 Reduces cognitive load
  • πŸ“¦ Encourages separation of concerns
  • πŸ”„ Makes scaling features easier
  • πŸ§ͺ Simplifies testing
  • πŸ‘₯ Makes collaboration smooth

πŸ”· Flutter Project Structure (Feature-First)

Here’s a simplified structure I use for most Flutter apps:

lib/
β”œβ”€β”€ core/                 # Shared base utilities (theme, constants, env)
β”‚   β”œβ”€β”€ utils/
β”‚   β”œβ”€β”€ services/
β”‚   └── widgets/
β”œβ”€β”€ features/             # Grouped by feature
β”‚   β”œβ”€β”€ auth/
β”‚   β”‚   β”œβ”€β”€ data/
β”‚   β”‚   β”œβ”€β”€ domain/
β”‚   β”‚   β”œβ”€β”€ presentation/
β”‚   β”œβ”€β”€ home/
β”‚   └── ...
β”œβ”€β”€ app/                  # Routing, DI, App entry
β”‚   β”œβ”€β”€ router.dart
β”‚   └── app.dart
main.dart

βœ… Tips:

  • Each feature/ has its own models, logic, and UI
  • Use core/ only for global, truly shared logic
  • app/ handles GoRouter, GetIt, and entry setup
  • Separate presentation, domain, and data layers for clean architecture

🟣 React Native Project Structure (Feature-First with Hooks)

src/
β”œβ”€β”€ assets/               # Fonts, images, icons
β”œβ”€β”€ components/           # Shared UI components
β”œβ”€β”€ features/             # Feature modules
β”‚   β”œβ”€β”€ auth/
β”‚   β”‚   β”œβ”€β”€ screens/
β”‚   β”‚   β”œβ”€β”€ hooks/
β”‚   β”‚   β”œβ”€β”€ services/
β”‚   β”‚   └── types.ts
β”‚   β”œβ”€β”€ home/
β”œβ”€β”€ navigation/           # React Navigation config
β”œβ”€β”€ context/              # App-wide context providers
β”œβ”€β”€ utils/                # Reusable helper functions
β”œβ”€β”€ config/               # env, constants, themes
App.tsx

βœ… Tips:

  • Each feature/ folder has its own hooks, services, and views
  • Avoid bloated context – use Zustand, or useReducer inside hooks
  • Centralize navigation in /navigation
  • Shared logic like formatDate, apiClient, etc. live in /utils

πŸ”„ What They Have in Common

PrincipleFlutterReact Native
Feature-firstlib/features/src/features/
Global utils/constantslib/core/src/utils/
Routing configlib/app/router.dartsrc/navigation/
Scoped UI componentslib/core/widgets/src/components/
Modular business logicdata/domain layershooks/services per feature

πŸš€ Pro Tips for Cross-Platform Consistency

  • Use naming conventions across both platforms (auth, home, profile, etc.)
  • Match your features/ structure between Dart and JS
  • Define a shared folder structure standard in your team docs
  • Use mono-repo tools like Nx (for RN + web) or Melos (for Flutter) if your projects grow
  • Set up aliases/import paths to avoid deep relative imports

🏁 Conclusion

Whether you’re building in Flutter or React Native, a feature-first structure will keep your project modular, testable, and easier to grow. I’ve used this layout across client projects, startup MVPs, and multi-dev teams β€” and it’s held up every time.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top