A React Native (TypeScript) daily habit tracker with time logging and priority management, built with Expo for easy testing with Expo Go.
- Daily Habit Tracking: Create habits that automatically repeat every day
- Today's Checklist: View and manage all habits for the current day
- Status Management: Mark habits as Pending or Done
- Time Logging: Record completion time and duration (hours/minutes) when completing habits
- Planned Time: Set and edit planned time for each habit (e.g., "Gym at 6:00 AM")
- Critical Priority: Mark habits as critical - they appear at the top until completed
- History View: Browse past days and view read-only habit records
- Smart Sorting:
- Critical pending habits appear first
- Non-critical pending habits sorted by planned time
- Completed habits moved to bottom, sorted by planned time
- Visual Indicators: Critical habits show red badge (!), red border, and red text
- Confirmation Dialogs: Confirmation alerts for important actions (delete, mark pending)
- Read-Only History: Past days cannot be edited, preserving data integrity
- Soft Deletion: Deleting a habit removes it from today and future days, but preserves history
- React Native with TypeScript: Type-safe development
- Expo Managed Workflow: No native code compilation required
- Expo Go Compatible: Test directly on device without building
- Platform-Aware Storage: SQLite on native, localStorage on web
- Stack Navigator: Three-screen navigation (Today, Add Habit, History)
- React Navigation: Industry-standard navigation library
- SQLite Database: Local storage using
expo-sqlite - Automatic Migration: Database schema updates handled automatically
- Error Recovery: Automatic database reinitialization on connection errors
- Web Compatibility: localStorage adapter for web platform
- Time Picker: Native time picker for completion and planned times
- Duration Input: Hours and minutes input with validation
- Error Boundary: Graceful error handling with fallback UI
- Modal Dialogs: Professional modals for habit completion and time editing
- TypeScript: Full type safety
- Error Handling: Comprehensive error handling and recovery
- Code Organization: Clean separation of concerns (database, services, screens, components)
Stores habit definitions and metadata.
CREATE TABLE habits (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
createdAt TEXT NOT NULL, -- ISO date string
deletedAt TEXT, -- ISO date string, null if active
scheduledTime TEXT, -- HH:MM format (24-hour), e.g., "06:00"
isCritical INTEGER DEFAULT 0 -- 1 if critical, 0 if not
);Fields:
id: Unique identifiername: Habit name (e.g., "Exercise", "Read")createdAt: When the habit was created (ISO timestamp)deletedAt: When the habit was deleted (ISO timestamp, null if active)scheduledTime: Planned time in 24-hour format (e.g., "06:00" for 6 AM)isCritical: Boolean flag (0 = false, 1 = true) for priority habits
Stores daily status and completion data for each habit.
CREATE TABLE habit_records (
id INTEGER PRIMARY KEY AUTOINCREMENT,
habitId INTEGER NOT NULL,
date TEXT NOT NULL, -- YYYY-MM-DD format
status TEXT NOT NULL DEFAULT 'pending', -- 'pending' or 'done'
durationMinutes INTEGER, -- Total minutes (null if not logged)
completionTime TEXT, -- HH:MM format (24-hour)
FOREIGN KEY (habitId) REFERENCES habits(id),
UNIQUE(habitId, date)
);Fields:
id: Unique identifierhabitId: Foreign key to habits tabledate: Date in YYYY-MM-DD format (e.g., "2025-12-30")status: Either 'pending' or 'done'durationMinutes: Total duration in minutes (e.g., 90 for 1 hour 30 minutes)completionTime: Time when habit was completed in HH:MM format (e.g., "14:30")
Constraints:
- Unique constraint on
(habitId, date)ensures one record per habit per day - Foreign key ensures referential integrity
CREATE INDEX idx_habit_records_date ON habit_records(date);
CREATE INDEX idx_habit_records_habitId ON habit_records(habitId);These indexes improve query performance when filtering by date or habit.
- Node.js (>= 18)
- Expo CLI (install globally:
npm install -g expo-cli) - Expo Go app installed on your Android device (from Google Play Store)
-
Install dependencies:
npm install
-
Start the Expo development server:
npm start
or
expo start
-
Run on Android with Expo Go:
- Open the Expo Go app on your Android device
- Scan the QR code displayed in the terminal or browser
- The app will load on your device
Alternatively, you can press
ain the terminal to open on Android emulator (if configured).
To create an APK for distribution:
-
Install EAS CLI:
npm install -g eas-cli
-
Login to Expo:
eas login
-
Configure EAS Build:
eas build:configure
-
Build APK:
eas build --platform android --profile preview
For production builds:
eas build --platform android --profile productionMyHabit/
βββ src/
β βββ components/
β β βββ DurationInput.tsx # Duration input (hours/minutes)
β β βββ ErrorBoundary.tsx # Error boundary component
β β βββ TimePicker.tsx # Time picker component
β βββ database/
β β βββ database.ts # SQLite database layer (expo-sqlite)
β β βββ webStorage.ts # Web storage adapter (localStorage)
β βββ navigation/
β β βββ AppNavigator.tsx # Navigation setup
β βββ screens/
β β βββ TodayScreen.tsx # Main today's habits screen
β β βββ AddHabitScreen.tsx # Create new habit screen
β β βββ HistoryScreen.tsx # View past days (read-only)
β βββ services/
β β βββ habitService.ts # Business logic for habits
β βββ types/
β βββ index.ts # TypeScript type definitions
βββ App.tsx # Root component
βββ index.js # Expo entry point
βββ app.json # Expo configuration
βββ package.json
expo: ~54.0.0 (Expo SDK 54)react-native: ^0.81.5react: 19.1.0typescript: ^5.6.3
@react-navigation/native: ^6.1.18@react-navigation/stack: ^6.4.1react-native-screens: ~4.16.0react-native-safe-area-context: ~5.6.0react-native-gesture-handler: ~2.28.0
expo-sqlite: ~16.0.10 (Expo-compatible SQLite)
@react-native-community/datetimepicker: ^8.4.4 (Time picker)
- The app uses local SQLite storage only (no cloud sync)
- All data persists across app restarts
- History is immutable - past records cannot be edited or deleted
- Habits are automatically created for each day when viewing that date
- Critical habits remain visually indicated even after completion
- Built with Expo SDK 54 for maximum compatibility with Expo Go
- Ensure your device and computer are on the same Wi-Fi network
- Try using the tunnel connection:
expo start --tunnel - Check that your firewall isn't blocking the connection
- The database is created automatically on first launch
- If you encounter database errors, try clearing the Expo Go app data and restarting
- The app includes automatic database reinitialization on connection errors
See LICENSE file for details.