Android Instant Apps (now called Google Play Instant) let users run parts of your app without installing it. A user taps a link, and the relevant module loads instantly, no Play Store visit, no download progress bar, no "Open" button. They're using your app within seconds.
The entire Instant Apps experience is built on deep linking. The URL determines which module to load, what content to show, and how to handle the user's session. Getting deep linking right is the difference between a seamless instant experience and a blank screen.
This guide covers how Instant Apps interact with App Links, how to configure deep linking for instant modules, and how to convert instant users into full installs. For the App Links foundation, see the Android App Links complete guide. For understanding fallback behavior when the app isn't installed, see the deep link fallback behavior guide.
How Instant Apps Work
When a user taps a URL that's associated with an Instant App:
- Android checks if the URL maps to an installed app (standard App Links). If yes, the installed app opens.
- If not installed, Android checks if the URL maps to an Instant App module on Google Play.
- If an instant module exists, Android downloads the module (typically 4-10 MB) and runs it immediately.
- If no instant module exists, the URL opens in the browser as normal.
The key insight: Instant Apps use the same URL structure and verification mechanism as regular App Links. The only difference is what happens when the app isn't installed.
User taps URL
├─ App installed? → Open app (standard App Links)
└─ Not installed?
├─ Instant module available? → Load instant module
└─ No instant module? → Open in browser
Prerequisites
Before implementing Instant App deep links:
Your app must be modularized. Instant Apps require Android App Bundles and feature modules. Each instant-enabled feature is a separate module.
App Links must be verified. Instant Apps use the same Digital Asset Links verification as regular App Links. Your
.well-known/assetlinks.jsonmust be valid.Target URL must be declared. Each instant module declares which URLs it handles in the manifest.
Module must be under the size limit. Individual instant feature modules must be under 15 MB (total instant app under 15 MB).
Configuring Deep Links for Instant Modules
Module Structure
A typical Instant App has:
app/ ├── base/ (shared code, always loaded) ├── feature-main/ (main installable feature) ├── feature-product/ (instant-enabled: product detail) └── feature-checkout/ (instant-enabled: checkout flow)Manifest Configuration
Each instant module declares its URL handling in its own
AndroidManifest.xml:<!-- feature-product/src/main/AndroidManifest.xml --> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:dist="http://schemas.android.com/apk/distribution" package="com.example.app.feature.product"> <dist:module dist:instant="true" dist:title="Product Detail"> <dist:fusing dist:include="true" /> </dist:module> <application> <activity android:name=".ProductDetailActivity" android:exported="true"> <intent-filter android:autoVerify="true" android:order="1"> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="https" android:host="yourapp.com" android:pathPattern="/products/.*" /> </intent-filter> <meta-data android:name="default-url" android:value="https://yourapp.com/products" /> </activity> </application> </manifest>Key elements:
dist:instant="true": Marks this module as instant-enabled.android:autoVerify="true": Required for App Links verification.android:order="1": Priority when multiple filters match. Higher numbers are checked first.default-url: The fallback URL if the module can't handle the specific URL.
Build Configuration
In your app-level
build.gradle.kts:android { // Enable Instant Apps dynamicFeatures += setOf( ":feature-product", ":feature-checkout" ) }In each feature module's
build.gradle.kts:plugins { id("com.android.dynamic-feature") } android { // Instant module configuration }Handling Deep Link Data in Instant Modules
Extracting URL Parameters
When the instant module launches, extract the deep link data from the intent:
class ProductDetailActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val uri = intent.data if (uri == null) { // No deep link data; show default product list showProductList() return } // Extract product ID from the URL path // URL: https://yourapp.com/products/abc123 val productId = uri.lastPathSegment // Extract optional query parameters // URL: https://yourapp.com/products/abc123?ref=campaign1 val referralSource = uri.getQueryParameter("ref") if (productId != null) { loadProduct(productId, referralSource) } else { showProductList() } } }Sharing State Between Instant and Installed App
When a user installs the full app after using the instant version, you want to preserve their session. Use the Cookie API to transfer data:
import com.google.android.gms.instantapps.InstantApps // In the instant module: save state before install fun saveInstantState() { val cookie = JSONObject().apply { put("user_session", "session_token_here") put("cart_items", cartItemsJson) put("referral_source", referralSource) } InstantApps.getPackageManagerCompat(this) .setInstantAppCookie(cookie.toString().toByteArray()) } // In the installed app: retrieve state after install fun restoreFromInstant() { val cookieBytes = InstantApps.getPackageManagerCompat(this) .getInstantAppCookie() if (cookieBytes.isNotEmpty()) { val cookie = JSONObject(String(cookieBytes)) val session = cookie.getString("user_session") val cartItems = cookie.getString("cart_items") // Restore the user's session and cart } }The cookie is limited to 16 KB, so store only essential state (session tokens, referral attribution, cart contents).
Converting Instant Users to Full Installs
The goal of an Instant App is to demonstrate value quickly and motivate the full install. Deep links play a role in this conversion.
Show an Install Prompt at the Right Moment
Don't show the install prompt immediately. Let the user experience value first:
// Show install prompt after the user completes a meaningful action fun onProductAddedToCart() { if (InstantApps.isInstantApp(this)) { // The user found a product they want; now prompt for install showInstallPrompt() } } fun showInstallPrompt() { InstantApps.showInstallPrompt( this, intent, // The current intent (preserves deep link data) REQUEST_INSTALL, "referral_source" // Optional referrer string for Play Store attribution ) }Preserve Deep Link Context Through Install
When the user installs from an instant module, the install intent can carry the original deep link data:
fun showInstallPrompt() { val postInstallIntent = Intent(Intent.ACTION_VIEW).apply { data = Uri.parse("https://yourapp.com/products/${currentProductId}") setPackage(packageName) addCategory(Intent.CATEGORY_BROWSABLE) } InstantApps.showInstallPrompt( this, postInstallIntent, REQUEST_INSTALL, null ) }After installation, the full app opens with the same deep link, and the user lands on the same product they were viewing.
Deep Link Routing: Instant vs. Installed
Your deep link routing logic needs to handle both contexts:
class DeepLinkRouter : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) val uri = intent.data ?: return finish() val isInstant = InstantApps.isInstantApp(this) when { uri.path?.startsWith("/products") == true -> { if (isInstant) { // In instant mode: show product detail (read-only) navigateToProduct(uri.lastPathSegment, readOnly = true) } else { // In installed mode: show full product experience navigateToProduct(uri.lastPathSegment, readOnly = false) } } uri.path?.startsWith("/checkout") == true -> { if (isInstant) { // Checkout requires full install showInstallPrompt() } else { navigateToCheckout() } } else -> navigateToHome() } } }Testing Instant App Deep Links
Using ADB
# Launch an instant module via deep link adb shell am start -a android.intent.action.VIEW \ -d "https://yourapp.com/products/abc123" \ --es "callerId" "com.google.android.instantapps.supervisor" \ --es "instantAppPackageName" "com.example.app"Using Android Studio
- Create a run configuration for the instant module.
- Set the launch URL in the configuration.
- Run on a device with Google Play services.
Common Test Scenarios
- Direct URL tap: Tap the URL in a browser. Should load the instant module.
- App already installed: Tap the same URL. Should open the installed app, not the instant module.
- Install from instant: Use the instant module, then install. Session state should transfer.
- Invalid URL: Tap a URL that doesn't match any module. Should fall back to browser.
Instant Apps and Tolinku Deep Links
Tolinku deep links work with Instant Apps through the standard App Links mechanism. When a user taps a Tolinku link:
- If the app is installed, Tolinku's redirect opens the app via App Links.
- If the app is not installed, the redirect falls through to the web fallback or app store.
To support Instant Apps with Tolinku links, ensure your Tolinku domain's redirect chain leads to a URL that your instant module handles. Configure the web fallback in your route settings to point to the URL associated with the instant module.
Limitations and Considerations
Size constraints. Each instant feature module must be under 15 MB. This limits what you can include. Heavy features (video editing, AR, complex maps) may not fit.
API restrictions. Instant Apps can't access certain APIs: background services, device identifiers, notification posting. Check the restricted API list.
Geographic availability. Google Play Instant is available in most countries but may not work on all devices (requires Google Play services 11.8+).
Analytics attribution. Instant App sessions are separate from installed app sessions. Make sure your analytics tool can link instant sessions to subsequent installs.
For the full App Links setup, see the Android App Links guide. For understanding how links are verified, see verified vs. unverified App Links.
Get deep linking tips in your inbox
One email per week. No spam.