Bookly is a demo booking mobile application built with React Native + Expo to showcase feature-first organization, modern mobile architecture, and production-ready patterns.
β οΈ This app is for demonstration purposes only. No real payments, reservations, or transactions are processed.
Bookly simulates a complete accommodation booking experience, including authentication, destination search, hotel discovery, and reservation confirmation.
The project is structured to reflect real-world mobile applications, prioritizing:
- Feature-based organization
- Clear separation of concerns
- Scalable routing and state management
- Maintainable and testable architecture
![]() |
![]() |
![]() |
![]() |
![]() |
- Authentication: Email/password and social sign-in.
- Destination Discovery: Search locations, view top destinations, and use geo-based suggestions.
- Accommodation Catalog: Browse, sort, and open hotel details with rich sections.
- Booking & Checkout: Pick dates/occupancy, review details, and confirm a mocked reservation.
- Bookings Management: Track active and past bookings from the dedicated tab.
- Feedback Loop: Built-in bug reporting flow.
You can install the Bookly app directly on your device via the closed test builds.
π Bookly β Closed Test Page
- React Native & Expo
- State management:
zustand(client state) +@tanstack/react-query(server state) - Navigation:
expo-router - Networking:
axios - Forms & validation:
react-hook-form+zod - Styling:
nativewind - Localization:
i18next - Local storage:
react-native-mmkv - Backend Services: Firebase (Auth, Firestore, Crashlytics) + REST API.
Bookly follows a feature-first modular architecture approach.
graph TD
subgraph Presentation ["<b>Presentation Layer</b>"]
UI[Expo Router Screens]
Comp[Reusable UI Components]
end
subgraph AppState ["<b>State Layer</b>"]
SQ[TanStack Query]
CS[Zustand Stores]
end
subgraph Data ["<b>Data Layer</b>"]
Client[Axios API Client]
FeatureAPI[Feature API Modules]
Mapper[DTO / Mappers / Types]
end
subgraph Ext ["Firebase / REST Backend"]
end
subgraph Lo ["MMKV Local Storage"]
end
%% Request
UI --> Comp
Comp --> SQ
Comp --> CS
SQ --> FeatureAPI
FeatureAPI --> Client
%% Response
Ext --> Client
Lo --> CS
Client --> Mapper
Mapper --> SQ
Each feature (e.g., auth, catalog, booking) is self-contained:
app/
βββ (tabs)/ # Main tab routes (home, bookings, profile)
βββ auth.tsx
βββ catalog.tsx
βββ accommodation.tsx
βββ checkout.tsx
βββ ...
src/
βββ core/ # HTTP, interceptors, bootstrap, services
βββ shared/ # Reusable UI, theme, selectors, hooks, stores
βββ features/
β βββ auth/ # Feature: Authentication
β βββ location/ # Feature: Destination and location search
β βββ catalog/ # Feature: Accommodation listing
β βββ booking/ # Feature: Booking flow and history
β βββ checkout/ # Feature: Checkout and confirmation
β βββ ...
βββ i18n/ # Localization setup and translation resources
I split state responsibilities between server and client concerns. TanStack Query handles cache, pagination, and API lifecycle for remote data, while Zustand keeps booking/session state simple and predictable across screens.
- Node.js LTS
- npm
- Expo SDK 55+ toolchain
- Android Studio or Xcode
- CocoaPods (for iOS)
Environment values are provided via .env.
- Configure your environment variables:
EXPO_PUBLIC_API_URL=...
EXPO_PUBLIC_GOOGLE_WEB_CLIENT_ID=...
GOOGLE_MAPS_API_KEY=...-
Create a Firebase project (Auth + Firestore + Crashlytics enabled).
-
Add platform configuration files in
credentials/firebase:
google-services.jsonGoogleService-Info.plist
- Build and run on device/simulator:
npm run android
npm run ios# Install dependencies
npm install
# iOS setup
npx pod-installThe project prioritizes coverage for feature screens, components, hooks, and API modules.
npm run testTo generate coverage data and HTML report:
npm run test:covCurrent line coverage: 80%+
- Assets:
assets/icons,assets/images - Localization: Handled via
i18next+react-i18next(Current locale:en).
Gabriel Peres Bernes
Full-Stack Software Engineer
LinkedIn: https://www.linkedin.com/in/bernesdev/
Email: bernes.dev@gmail.com
This project is intended for educational and demonstration purposes only and does not represent a real commercial product.




