Resolving Dependency Conflicts
Fix dependency conflicts and duplicate packages when installing the Digia Engage SDK — dependency_overrides in Flutter, and overrides / resolutions in npm, Yarn, pnpm, and Bun.
The Digia Engage SDK depends on common packages your app very likely already uses — image caching, storage, device info, SVG rendering. When your app pins a different version than the SDK asks for, the install either fails outright or quietly installs two copies.
Both are fixed the same way: pick one version and force it with an override.
1. What goes wrong
The symptom differs by ecosystem, which is why the fix looks different.
Pub allows only one version of a package across your whole dependency graph. If your app and digia_engage ask for incompatible ranges, flutter pub get refuses to resolve:
Because digia_engage >=1.17.0 depends on device_info_plus ^10.1.0 and
my_app depends on device_info_plus ^12.0.0, version solving failed.This is a hard failure at install time — loud, and it blocks the build until you resolve it. Nothing is silently duplicated.
npm and friends happily install two copies at different paths in node_modules. Nothing fails at install time, and the damage shows up later:
Native modules break.
react-native-svgand@react-native-async-storage/async-storageeach ship native code. Autolinking registers one native implementation, but two JS copies may be loaded — so one of them talks to a native module that isn't there. Typical symptoms areInvariant Violation, a null native module, or views that render blank.Bundle size grows for every duplicated package.
This is a silent failure, which makes it the more dangerous of the two.
Packages most likely to collide
Flutter
device_info_plus, package_info_plus, share_plus
The _plus family bumps major versions often
Flutter
shared_preferences, path_provider, url_launcher, dio, video_player
Near-universal in production apps
React Native
react-native-svg, @react-native-async-storage/async-storage
Native modules — duplication actually breaks them
React Native
@floating-ui/core, react-native-uuid
Pure JS; duplication costs bundle size, not correctness
2. Which version to pick
Use the version your app already depends on, provided it still satisfies the SDK's constraint.
That is the whole point of the override: collapse two versions into one, and the app's version is almost always the right survivor. Your app's code is far larger than the SDK's usage of that package, your team has already tested against it, and other packages in your tree are likely built against it too.
Before you commit to it, check the direction of the mismatch:
App's version is newer and API-compatible
Override to the app's version. This is the common case.
App's version is older than the SDK's floor
Prefer upgrading your app's dependency. Forcing the older one can break the SDK at runtime — it may call an API that version doesn't have.
Versions differ by a major in either direction
Read that package's changelog before forcing either. A major bump means a breaking change that one side has not been tested against.
An override bypasses the resolver's safety check. You are telling the tool "trust me, these are compatible." Nothing verifies that claim, so test the affected features after applying one — for the SDK side that means checking that campaigns still render.
3. Flutter — dependency_overrides
Add a dependency_overrides section to your app's pubspec.yaml, alongside dependencies:
Then:
dependency_overrides only works in the root package — the app you actually build. Pub ignores the dependency_overrides of any package you depend on. If you maintain an internal package that wraps Digia, the override must go in the app's pubspec.yaml, not your wrapper's.
You can also pin an exact version (device_info_plus: 12.0.1) or point at a local path or Git ref while testing a fix.
4. React Native — overrides by package manager
Every package manager solves this, but the field name and file location differ. Use the one matching the lockfile in your repo.
Add an overrides block to your app's package.json:
Because "use the version my app already depends on" is the normal intent, npm has shorthand for it — $ references your own direct dependency, so the two can never drift apart:
To restrict the override to Digia's subtree only, rather than your whole project:
Yarn uses resolutions, in your app's package.json. This works in both Yarn Classic (1.x) and Yarn Berry (2+):
Glob patterns let you scope the override:
Put overrides in pnpm-workspace.yaml at the root of your project:
Parent selectors scope an override to one package's subtree:
pnpm 11 silently ignores pnpm.overrides in package.json — no warning, no error, no deprecation notice. If you are upgrading from pnpm 10 and your overrides simply stop taking effect, this is why. Move them to pnpm-workspace.yaml.
Bun reads both npm's overrides and Yarn's resolutions from your app's package.json — use whichever your team already knows:
Bun supports top-level overrides only — the nested form that scopes an override to one parent package is not supported. An override in Bun always applies to your entire dependency tree.
Every one of these is read from the root package.json (or pnpm-workspace.yaml) only. An override declared inside a workspace package or an installed dependency is ignored.
Reinstall cleanly
Overrides change how the tree resolves, so a stale lockfile or node_modules will hide the fix:
pod install matters whenever the duplicated package ships native code — the CocoaPods lockfile still references the old resolution until you re-run it.
5. Confirm the duplicate is gone
flutter pub get succeeding is itself strong evidence — pub cannot resolve at all while a genuine conflict remains.
Ask your package manager who depends on the package. You want exactly one version in the output:
A healthy result lists a single version, even if several packages depend on it. Two version numbers means the override has not taken effect — check that you edited the root manifest and did a clean reinstall.
Then run the app and confirm a campaign still renders. An override silences the resolver, so a real runtime check is the only thing that proves the two versions were actually compatible.
6. When an override is the wrong fix
The SDK needs a newer major than your app can move to. Forcing the old version will fail at runtime instead of install time. Upgrade the app's dependency, or contact support so we can check whether the constraint can be widened.
Two packages need genuinely incompatible majors. No single version satisfies both; one of them has to move.
You are shipping a library, not an app. Your
dependency_overrides(Flutter) oroverrides(npm) are ignored by your consumers. Widen your own constraints instead, so your users can resolve it in their app.
Related pages
Overview — installing the SDK
SDK Debug Settings — inspecting SDK state on-device
Last updated