4 min read
How deep linking vendors lock you in, and how to avoid it
A deep linking vendor is hard to leave when it owns your link domain or your link format, and Firebase Dynamic Links shows how badly that can end.
Rewritten in October 2026. The February 2025 version was an unfinished stub.
By the time you want to leave a deep linking vendor, a surprising amount of your app and your marketing is shaped around it, and the links you've already sent out are the hardest part to take with you. I only thought about that properly after using Branch on an earlier startup.
The extreme case is Firebase Dynamic Links. When Google shut it down on 25 August 2025, every page.link URL started returning 404 (Firebase FAQ), including the ones on posters, in old emails and pinned in Discord servers, and nobody who'd used them could do anything about it because the domain was Google's. Most lock-in is milder than that, but it works through the same few mechanisms.
The domain
If your links live on app.link or bnc.lt (Branch), abr.ge (Airbridge) or page.link, the domain belongs to the vendor. Leave, and every link already out there points at a server you don't pay for any more, and you can't redirect them because you can't change DNS on a domain you don't own. Both Branch and Airbridge offer custom domains, with conditions: as of October 2026 Branch's comes with the Activation Basics plan at $199 a month, and Airbridge's has to be a dedicated subdomain.
The link format, and links that only exist in a database
Even on your own domain the vendor can own the shape of the link. Branch long links on a custom domain need an /a/key_live_… segment carrying your Branch key (link docs), and routing by path goes through a $deeplink_path parameter that Branch says "requires custom logic". Airbridge links look like abr.ge/@yourapp/.... The format leaks into your app, because the routing code ends up reading vendor fields rather than a URL, and switching means rewriting the routing as well as swapping the SDK.
Some links are really rows in someone else's database. Airbridge links have to be created first, in the dashboard, Google Sheets or the API (tracking links), so before you can leave you have to export every one and recreate it somewhere else, and any the export misses break.
The SDK is the last part. An attribution SDK brings its own init, its own consent handling and its own identifiers (Airbridge's collects IDFA and GAID by default, per its identifiers page), and once your onboarding is built around how it behaves, including how it waits on the ATT prompt, removing it is a project rather than an afternoon's work.
What I'd do instead
Put links on your own domain from day one, on a subdomain like go.yourapp.com, so if the vendor goes away you point the DNS somewhere else. Make the links plain URLs: https://go.yourapp.com/events/42?invite=K7Q means the same thing to any server, and your app should only ever need to read a path and a query string. If your backend can make a link by writing a string, there's no link database to export. And wrap whatever SDK you use in a function of your own, ideally one init call and one "what did the user tap" call, so replacing it touches one file.
DeepLinkNow is built along those lines. Any path and query on your domain is a link with nothing created first, the app gets path, queryParams and fullPath back, and the integration is initialize plus checkDeferredDeepLink. It has its own lock-in, which is that on the free plan your links live on yourapp.deeplinknow.com, my domain. Custom domains start on the Startup plan at $49 a month. Adding one later doesn't split your links, since the same path on the subdomain and on the custom domain is the same link, but the links you've already printed keep pointing at the subdomain. A custom domain also stops answering if you drop back to the free plan, while the deeplinknow.com subdomain keeps working on every plan. For links going anywhere you can't edit later, like print, I'd start on Startup.