A calm habit tracker built with Expo SDK 57, local reminders, and push-notification deep links.
- Create, edit, and delete habits
- Schedule local reminder notifications for daily or weekly habits
- Mark habits done and keep a streak count
- Open a habit detail screen from a notification tap
- Register for Expo push tokens in a dev build on a physical device
- Copy the push token from Settings for test sends
Video link : https://youtu.be/fJUbIMQxu5o
- Install dependencies
npm install- Start the app
npm run start- Run on a device or emulator
npm run android
# or
npm run iosPush registration and push delivery require a development build or a supported simulator.
Expo Go can still show local reminders, but it cannot receive push notifications.
If getExpoPushTokenAsync complains about a missing project id, make sure the Expo project is linked in EAS and that Constants.easConfig.projectId or expoConfig.extra.eas.projectId is available in the build.
- Open Settings in the app and copy the Expo Push Token.
- Run the helper script:
EXPO_PUSH_TOKEN="ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]" \
HABIT_ID="demo-habit" \
TITLE="Hydrate now" \
BODY="Tap to open the habit detail screen." \
node scripts/send-test-push.mjsThe payload uses this shared data contract:
{
"screen": "/habit",
"habitId": "demo-habit"
}Local notifications are scheduled by the device and do not need a server. Push notifications are sent remotely through Expo's push service and require a token plus a dev build.
A push ticket is the immediate response from Expo after you submit a push. A receipt is the later delivery result for that ticket. Tickets confirm acceptance; receipts confirm whether delivery succeeded.
The device token is no longer valid for push delivery. In practice, remove that token from your backend and stop sending pushes to it.
Expo Go does not support remote push notifications for SDK 53+ on Android, and the same limitation applies for this project's push workflow. Local notifications still work in Expo Go.
Android notification channels define importance, sound, and behavior before the permission flow and scheduling happen. Creating the custom high-importance channel first avoids the fallback Miscellaneous channel and keeps reminder behavior consistent.
Capture these flows for the final review:
- Create a habit with daily and weekly schedules
- Edit a habit and reschedule reminders
- Mark a habit done and show the streak update
- Delete a habit and confirm its reminders are removed
- Permission denied state in Settings with the open-settings action
- Local notification tap opening a habit detail screen
- Push notification tap opening the same habit detail screen
- Foreground push banner vs background tap behavior
- Habits are stored locally with AsyncStorage.
- Reminder scheduling only cancels the specific habit's notification IDs.
- The shared notification tap handler routes both local and push payloads.