Cross-platform monorepo for EasyBoard: one Expo (expo-router) app serving iOS, Android and web, plus Firebase Cloud Functions.
├── runtimes/
│ ├── app/ # Expo app: iOS, Android and web
│ │ ├── src/
│ │ │ ├── app/ # Routes only (expo-router)
│ │ │ ├── screens/ # Screen components the routes render
│ │ │ ├── components/ # UI components (Uniwind / Tailwind 4)
│ │ │ ├── contexts/ # React Contexts for global state
│ │ │ ├── helpers/ # Utility functions
│ │ │ ├── hooks/ # React Hooks
│ │ │ ├── provider/ # App level providers (Theme, Auth, etc.)
│ │ │ ├── services/ # Firebase and Google API abstractions (.native.ts / .web.ts pairs)
│ │ │ ├── stores/ # State management stores
│ │ │ └── types/ # TypeScript interfaces
│ │ ├── assets/
│ │ ├── plugins/ # Expo config plugins
│ │ └── app.config.ts, metro.config.js, tailwind.config.ts, global.css
│ └── functions/ # Firebase Cloud Functions
├── wiki/ # Project documentation
└── package.json # Root package.json with workspaces
- Node.js >= 20
- Yarn 4.18.1
# this should be sufficient to enable yarn in most Node.js installations
corepack enableClone the repository and install dependencies:
yarn installRefer to the .env.example files and create corresponding .env files with the required values.
If you are developing for Android or iOS locally, ensure you have the following prerequisites installed (refer to the most updated instructions here):
Install Watchman and JDK
brew install watchman
brew install openjdk@17For openjdk@17, you may need to add it to your PATH and JAVA_HOME. Add the following to your shell config file (e.g., ~/.zshrc or ~/.bash_profile):
export PATH="/opt/homebrew/opt/openjdk@17/bin:$PATH"
export JAVA_HOME="/opt/homebrew/opt/openjdk@17/libexec/openjdk.jdk/Contents/Home"Install Xcode Command Line Tools
xcode-select --installIf you are on Windows, follow these steps to set up the Android development environment:
- Install OpenJDK 17: You can use Chocolatey:
choco install openjdk17. - Install Android Studio: Download and install from official site.
- Configure SDK: Ensure "Android SDK Platform" and "Android Virtual Device" are installed.
- Environment Variables: Set
JAVA_HOMEto your JDK path andANDROID_HOMEto your Android SDK location. Add theplatform-toolsandemulatordirectories to yourPATH.
Run the following to create a development build. Typically you would only need to run these commands once unless you are making changes to the native configs (note that MacOS is required for iOS build/development):
# in the monorepo root
yarn app:prebuild
yarn app:android # For Android
# and/or
yarn app:ios # For iOS (macOS only)If you are running the above commands for the first time, the dev server will automatically start after the build is completed. For subsequent runs, you can simply run yarn dev
For more detailed instructions (Android Studio, iOS Simulator, etc.), refer to the official Expo Environment Setup Guide.
To run all services (Functions emulator and the Expo dev server; the web app is at http://localhost:8081, press w to open it):
yarn dev- Expo dev server (web at http://localhost:8081; press
wto open it):yarn app:dev - Native iOS:
yarn app:ios - Native Android:
yarn app:android
Component stories (*.stories.tsx next to each component) run in Storybook 10 on React Native Web with Vite, styled by the same Uniwind/Tailwind setup as the app:
yarn workspace app storybook # http://localhost:6006
yarn workspace app build-storybook # static build in runtimes/app/storybook-static- Build all:
yarn build(the app's build is a static web export inruntimes/app/dist) - Build specific:
yarn turbo build --filter=<app-name>
- Lint:
yarn lint - Format:
yarn format
Many errors (especially Typescript/import errors) an be resolved by deleting node_modules and running yarn install. There is a convenience script to delete the various node_modules folder:
yarn cleanFor React Native/Expo specific errors, it might be worth doing the above and then generating a new build
yarn app:prebuild
yarn app:android # For Android
# and/or
yarn app:ios # For iOS (macOS only)- Gneneral workflow:
- Create primitive UI in
runtimes/app/src/components. - Compose screens in
runtimes/app/src/screens. - Register routes in
runtimes/app/src/app(expo-router). The same routes serve iOS, Android and web. Import with the@/alias, e.g.@/screens.
- Create primitive UI in
- Business logic should reside in
runtimes/app/src/services. - Use Uniwind (Tailwind 4
className) for styling across all platforms.
- One codebase: iOS, Android and web are one Expo app routed by expo-router. Platform differences live in
.web.ts/.native.tsfile pairs. - Uniwind: Tailwind CSS 4 for universal styling.
- Firebase Integration: Unified services for Auth, Database, and Functions.
- Type Safety: Full-stack TypeScript support.