How to Add Push Notifications to Your Expo App

DavidDavid August 1, 2026 7 min read
A smartphone displaying a push notification with an app icon in the upper left
Original image, App Store Launch Club

How Expo Push Notifications Work

When a user installs your app, you can request a device-specific push token from Expo's service. This token identifies where to send a notification to that specific device. Your backend stores the token. When you want to send a notification, you POST to Expo's push API with the token and your message. Expo routes it to Apple (APNs) or Google (FCM) on your behalf. You never need to manage APNs certificates or FCM keys directly.

Setting Up the Package

Run npx expo install expo-notifications expo-device expo-constants. Add the permission configuration to your app.json under expo.ios.infoPlist and expo.android.permissions. Then in your app, request permission with Notifications.requestPermissionsAsync() and get the token with Notifications.getExpoPushTokenAsync(). Store that token in your database against the user.

Sending a Notification from Your Backend

POST to https://exp.host/--/api/v2/push/send with a JSON body containing the token, title, body, and optional data payload. Expo handles routing to the correct platform. For small volumes, direct HTTP is fine. For production scale, use the expo-server-sdk package (available for Node.js, Python, and others) which handles batching and error handling.

Best Practices for Retention

The permission prompt is the most important UX moment. Do not ask for notification permission on first launch - users have no context yet and most decline. Ask after the user has experienced value from the app: after they complete an action, achieve something, or come back a second time. Frame the prompt around the benefit ('Get notified when your results are ready') not the permission ('Allow notifications').

Free app-building tips, straight to your inbox

Short, practical drops on app ideas, validating fast, store listings, and passing app review. No spam, unsubscribe anytime.

Frequently asked questions

Do I need a paid Expo account to use push notifications?

No. Expo's push notification service is free with no hard caps on the free plan for reasonable usage. You pay only if you use EAS Build and other EAS services.

Can I send push notifications from the client side without a backend?

In development you can trigger test notifications locally. In production, you should never send push notifications from the client - the token would be exposed and anyone could send notifications on your behalf. Always route through a server or a service like Firebase Functions.

How do I handle users who deny notification permission?

Do not pester them. Store their preference and move on. You can surface a soft prompt later (e.g., in app settings) if there is a clear benefit to show. Never lock features behind notification permission.

Last reviewed by David on August 1, 2026

David

Written by

David

Founder and app builder

Keep reading

App StoreLaunch

App Store Phased Release: How the 7-Day Rollout Works, How to Pause It, and When to Skip It

App Store phased release rolls a version update out to a random sample of users with automatic updates on over 7 days: 1 percent on day one, then 2, 5, 10, 20, 50 and 100. You can pause it for up to 30 days in total, or release to everyone with one button. Here is exactly what Apple says it does, what it does not do, and how I decide when an Expo app update should use it.

David 8 min
Read article
ExpoClaude Code

How to Add Haptic Feedback to Your Expo App

How to add haptic feedback to your Expo app: install expo-haptics, then call the right method for the moment - selectionAsync for pickers, impactAsync for taps and gestures, notificationAsync for outcomes. Here is the exact mapping, the reason the simulator stays silent, and the one rule that keeps haptics from feeling cheap.

David 8 min
Read article

Ready to build it yourself?

Join App Store Launch Club, the #1 community for building and launching apps, for $9/month.

← Back to the blog