A high-performance, real-time Todo application built with Expo, Convex, and a custom-designed Theme System. This project showcases modern mobile development practices, including real-time backend synchronization and dynamic dark/light mode persistence.
- Real-time Sync: Powered by Convex, all changes reflect instantly across all devices.
- Dynamic Theming & Status Bar: Custom-built theme provider with smooth transitions, persistent storage via
AsyncStorage, and a dynamically adapting Status Bar. - Enhanced UX: Includes tactile feedback via
expo-hapticsand buttery smooth layout transitions using React Native'sLayoutAnimation. - Modular Components: Clean, maintainable architecture separating UI logic into reusable components.
- Tabbed Navigation: File-based routing with
expo-routerfor a native-feeling UX. - Full CRUD: Create, Update, Toggle, and Delete todos with ease.
- Framework: Expo SDK 54
- Backend: Convex (Real-time Database & Functions)
- Navigation: Expo Router
- Styling: Custom Theme System (Vanilla React Native Styles)
- Feedback & Animations:
expo-hapticsandLayoutAnimation - Persistence:
@react-native-async-storage/async-storage - Language: TypeScript
├── app/ # Expo Router directory
│ ├── (tabs)/ # Main tab-based navigation
│ │ ├── index.tsx # Todo List screen
│ │ ├── settings.tsx # Settings & Theme toggle
│ │ └── _layout.tsx # Tabs configuration
│ └── _layout.tsx # Root layout (Providers)
├── components/ # Reusable UI components
│ ├── Header.tsx # Screens headers
│ ├── TodoItem.tsx # Individual task items
│ ├── SettingItem.tsx # Settings list items
│ └── ... # (ActionItem, StatCard, InputSection, EmptyList)
├── convex/ # Backend schema and functions
│ ├── schema.ts # Database schema
│ ├── todos.ts # Todo CRUD mutations and queries
│ └── _generated/ # Auto-generated Convex files
├── hooks/ # Custom hooks
│ └── useTheme.tsx # Theme context and hook
├── assets/ # Local styles, images, and icons
└── app.json # Expo configuration
Ensure you have Node.js installed and the Expo Go app on your physical device or an emulator ready.
npm installThis project uses Convex for its backend. You need to initialize it:
npx convex devNote: This will prompt you to log in to Convex and create a new project. It will also generate the necessary .env.local or EXPO_PUBLIC_CONVEX_URL.
npm start- Press
afor Android - Press
ifor iOS - Scan the QR code with Expo Go
The app features a robust theme system located in hooks/useTheme.tsx. It provides:
isDark: Boolean state for current mode.colors: A rich color palette for both light and dark modes.toggleTheme(): Function to switch between modes with automatic persistence.
import useTheme from "@/hooks/useTheme";
const MyComponent = () => {
const { colors, isDark } = useTheme();
return <View style={{ backgroundColor: colors.bg }} />;
};Convex functions are located in convex/todos.ts:
getTodos: Fetches all todos.addTodo({ text }): Adds a new todo.toggleTodo({ id }): Toggles completion status.updateTodo({ id, text }): Edits todo text.deleteTodo({ id }): Removes a todo.clearAllTodos(): Wipes all todos.
This project is for demonstration purposes. Feel free to use it as a foundation for your own apps.