You picked Expo for a reason. Fast iteration, managed workflow, no Xcode rabbit holes. The last thing you want is an attribution SDK that forces you to eject, add native modules, or bloat your binary with 20MB of tracking infrastructure.
Most mobile attribution tools were built for a different era. They assume you're running a native project with full access to the build pipeline. They want native modules, custom build phases, and configuration files that Expo's managed workflow doesn't support without ejecting. For a lot of Expo developers, that's a dealbreaker. You chose managed Expo specifically to avoid that kind of friction.
So you end up with nothing. No attribution at all. You share your App Store link on TikTok, Reddit, Twitter, and your newsletter. Purchases come in through RevenueCat. And you have no way to connect any purchase to the marketing that caused it.
Why most attribution SDKs don't work with Expo
The big attribution platforms — AppsFlyer, Adjust, Branch — rely on native code. They need to hook into the app launch cycle at a system level, read device identifiers, and intercept deep links using platform-specific APIs.
Expo's managed workflow abstracts all of that away. You don't have direct access to AppDelegate on iOS or MainApplication on Android. The build process is handled by EAS Build, and any native dependency needs to be either supported by Expo or handled through a config plugin.
Some of these platforms offer React Native SDKs, but they're wrappers around their native SDKs. You still need native modules installed and linked. In practice, that means running expo prebuild, managing native code, and losing the simplicity that made Expo attractive in the first place.
There's a halfway option — using Expo config plugins — but even that requires EAS Build and means you can't test attribution in Expo Go during development. For a solo developer who just wants to know whether TikTok or Reddit is driving sales, this is all massive overkill.
What you actually need
Take a step back from the enterprise attribution playbook and think about what you're actually trying to learn. It's pretty simple: when someone buys your premium tier, which marketing link brought them in?
You don't need device fingerprinting. You don't need probabilistic attribution models. You don't need a 40-page integration guide. You need tracked links that carry a campaign identifier through to the purchase event.
The flow works like this:
- You create a tracked link for each marketing channel (one for your TikTok bio, one for a Reddit post, one for an influencer)
- Someone taps the link, which records the click and redirects to your App Store listing
- They install the app and open it
- The app reads the attribution data (stored from the link tap)
- When they make a purchase, the attribution data gets sent along with the transaction
That's it. No native modules. No device IDs. No fingerprinting. Pure JavaScript, compatible with Expo Go.
Setting it up
The npm package is @linkowlnew/react-native. It's a pure JavaScript implementation with no native dependencies.
Install it:
npx expo install @linkowlnew/react-native
Initialise it when the app launches. If you're using Expo Router, your root layout is a good place:
import { LinkOwl } from '@linkowlnew/react-native';
// In your root layout or App component
useEffect(() => {
LinkOwl.init('your-api-key');
}, []);
That's the entire client-side integration. The SDK stores the attribution data locally and exposes it when purchases happen.
The purchase attribution happens server-side through webhooks. If you're using RevenueCat (and most Expo apps are), you add a webhook URL in your RevenueCat dashboard. When a purchase or subscription event fires, RevenueCat sends it to LinkOwl, which matches it against the link that brought the user in.
No native modules. No ejecting. No config plugins. Works in Expo Go during development and in production builds through EAS.
Creating tracked links
Once your app is registered on LinkOwl, you create links through the dashboard. Each link gets a unique identifier and redirects to your App Store listing.
For a typical setup, you might create:
linkowl.app/c/tiktok-bio— your TikTok profile linklinkowl.app/c/reddit-fitness— a post in r/fitnesslinkowl.app/c/sarah-review— an influencer's review videolinkowl.app/c/newsletter-march— your email newsletter
When someone taps any of these, the click gets recorded with the campaign identifier, and they land on your App Store page. If they install and purchase, you see exactly which link started the chain.
What this looks like in practice
Say you've built a meditation app with Expo. You've got a free tier and a £4.99 lifetime premium unlock through RevenueCat. You're marketing across three channels: TikTok (organic posts), Reddit (comments in r/meditation and r/anxiety), and one paid Instagram influencer.
After a month of tracking, your LinkOwl dashboard shows:
- TikTok bio link: 580 clicks, 42 installs, 4 purchases (£19.96)
- Reddit comments: 95 clicks, 31 installs, 8 purchases (£39.92)
- Instagram influencer: 1,200 clicks, 89 installs, 2 purchases (£9.98)
The Instagram influencer cost you £150. Two purchases at £4.99 means you lost £140 on that deal. Meanwhile Reddit — which cost you nothing but time — drove twice the revenue of TikTok with a fraction of the traffic. Each Reddit click converts to a purchase at 8.4%, compared to 0.7% for TikTok and 0.2% for Instagram.
Without attribution, you'd look at the raw click numbers and think the influencer campaign was your best performer. You might even book another one. With attribution, you can see that Reddit is your goldmine and you should probably be spending more time there.
Expo Go compatibility matters
This is worth spelling out because it trips people up. A lot of React Native libraries technically support Expo but only through development builds. They won't run in Expo Go.
That matters because Expo Go is where you iterate quickly. If your attribution SDK only works in production builds, you can't test the flow during development without building and installing a full development client. For a solo developer, that's a 15-minute build cycle every time you want to verify something.
LinkOwl's SDK is pure JavaScript. It runs in Expo Go, in development builds, and in production. You can test the entire attribution flow on your phone through Expo Go without waiting for a build.
What about deep linking?
If your app handles deep links (most Expo apps use expo-linking or Expo Router's built-in link handling), you might wonder how attribution fits in.
They're separate concerns. Deep linking is about sending users to a specific screen in your app. Attribution is about knowing which marketing link drove the install. You can use both together — a tracked attribution link that also deep links to a specific screen — but you don't have to.
For most indie apps, simple attribution (which link drove the purchase) is all you need. Deep linking is a nice-to-have for onboarding flows or campaign-specific landing screens, but it's not required for attribution to work.
The cost
LinkOwl charges 5p per attributed purchase. No monthly fee. If your Expo app gets 30 purchases in a month, that's £1.50. You don't get billed until you cross £5 in total (100 purchases), and anything below that threshold rolls over.
Compare that to AppsFlyer, which starts at around $500/month. Or Adjust, which doesn't publish pricing but requires a sales call — always a sign that solo developers aren't the target customer.
For an Expo app making a few hundred quid a month, paying 5p per sale to know where your customers come from is a sensible trade. You're paying for information that directly tells you where to spend your marketing time.
Getting started
- Sign up at linkowl.app (free, no card required)
- Register your app and copy your API key
- Install the SDK:
npx expo install @linkowlnew/react-native - Add
LinkOwl.init('your-api-key')to your root component - Connect your RevenueCat webhook in two minutes
- Create tracked links for each marketing channel
First 100 attributed purchases are free. After that, 5p per purchase, billed at the £5 threshold.
Your Expo app deserves attribution that fits the way you build — lightweight, no native code, and ready in 10 minutes.