Video demonstration:
This project was built as an exercise to showcase the libraries and architecture I usually recommend for an hybrid mobile app.
It is a chat app with basic functionalities:
- Simple sign in with username;
- Creating and navigating through chat rooms;
- Messaging other users and reacting to the messages.
Besides the working app and the documentation, please check the Pull Requests. They have a comprehensive overview of the work done.
This project uses the following technologies:
- TypeScript
- React Native
- Expo
- Expo Router: file-based router
- Supabase: BaaS, database, messaging
- Tanstack Query: data fetching, caching, and state management
- NativeWind v4: styling utility based on Tailwind CSS
- gluestack-ui v2: component library, design system, accessibility
- Jest: testing, mocking, and code coverage
The project is structured in layers, inspired by Clean Architecture principles. The focus is on separation of concerns and modularity. While not very usual in React Native projects, it allows for better organization and testability of the code. Here’s a breakdown of each layer:
- Handles UI components and user interaction
- Contains reusable components and hooks
- Manages layout and visual structure
- Implements use cases
- Orchestrates business logic
- Coordinates between presentation and domain layers
- Defines core business models and rules
- Specifies repository interfaces
- Implements repository interfaces
- Manages external system interactions
- Handles data persistence
Besided the folders organized according to the architecture layers, I want to bring attention to a few others:
It contains all code related to the navigation, which is specific to the expo-router
library. You'll find that any redirection and authentication requirements are done there.
The screens and the high level layouts are actually in the Presentation
folder/layer.
The base components generated by the gluestack-ui
lib all sit in the /presentation/components/ui
folder.
Other reused components are placed in the /presentation/components
root folder. If components are used in a single screen, we co-locate them in the same file.
pnpm requires Node.js version 18 or above. If you don’t have this version, please update Node before proceeding.
To install pnpm, run:
npm install -g pnpm
- pnpm offers faster installs, saves disk space, and provides isolated node_modules.
- For other installation methods, refer to the pnpm installation guide.
You can use npm to install the Expo CLI command line utility:
npm install -g expo-cli
Follow this guide if you need help setting up your environment.
When the environment is ready, open your terminal and type the following commands:
# clone the project and cd into it
git clone https://github.com/scalfs/trashlab-chat-app; cd ./trashlab-chat-app
# install dependencies
pnpm install
pnpm start
This will run the Metro bundler and open the Expo Tools in your terminal, providing options to run the app on:
- iOS Simulator
- Android Emulator
- Physical device (using the Expo Go app)
- Install Expo Go, if you haven't already, on your iOS or Android device.
- Scan the QR code displayed in the Expo Developer Tools to open the app on your device.
Note: Ensure your device and development machine are on the same Wi-Fi network.
After following these steps, you should see your Expo app running on the device or simulator.
- Need to verify if a chat already exists before creating a new one
- Chat rooms are not updating the displayed time, neither their ordering
- Messages are not automatically updated. We can leverage Supabase's real time subscription to solve that.
- Hide env variables in a secret storage
- Add a CI/CD pipeline for basic flows like testing, linting and deploying.
- Apply optimistic updates and add skeleton elements for chat rooms and messages
- There's not a single animation in the app, besides the native navigation, toaster and loading spinner. There are many opportunities for animated micro interactions in this app.
- Use
tsyringe
for proper dependency injection. But the Dependencies Context should be fine by now
- Needs an appropriate authentication
- Needs further work on policies for ensuring that
- Anyone can create a new conversation
- Users can only see conversations they're part of
- Users can only see and add messages to conversations they're part of
- Users can see other participants in conversations they're part of
We can leverage the supabase CLI to update the interfaces whenever there's a update. [Documentation Link] For now, I'm generating it in the dashboard and copying the file to the project.
supabase gen types typescript --project-id abcdefghijklmnopqrst > database.types.ts