Skip to content

feat(package_info_plus): add opt-in compile-time package info accessor#3874

Open
Ortes wants to merge 1 commit into
fluttercommunity:mainfrom
Fullphysio:package-info-compile-time-version
Open

feat(package_info_plus): add opt-in compile-time package info accessor#3874
Ortes wants to merge 1 commit into
fluttercommunity:mainfrom
Fullphysio:package-info-compile-time-version

Conversation

@Ortes

@Ortes Ortes commented Jun 12, 2026

Copy link
Copy Markdown
Contributor

Description

On the web, PackageInfo.fromPlatform() resolves the version by fetching version.json from the server at runtime (with a cache buster). That file reflects whatever is currently deployed — not the bundle actually executing in the browser. The two states routinely diverge:

This makes the reported version actively misleading rather than merely missing — and the version is the whole point of the plugin. Its two canonical uses, showing the running version and checking whether an update is needed, are both defeated when the value is the server's. An update gate built on it can never fire for the very users it targets, since stale clients self-report as up to date.

This PR

Adds a small opt-in library, package_info_plus_environment.dart, exposing PackageInfoEnvironment.packageInfo:

import 'package:package_info_plus/package_info_plus_environment.dart';

final info = await PackageInfoEnvironment.packageInfo;
  • Web — returns a PackageInfo built from compile-time PACKAGE_INFO_PLUS_* defines (flutter build web --dart-define=PACKAGE_INFO_PLUS_VERSION=1.2.3 ...). These are embedded in the running bundle and cannot diverge from it. A web build that omits PACKAGE_INFO_PLUS_VERSION fails to compile (a kIsWeb-conditional const assert), so a misleading version can never ship silently.
  • All other platforms — delegates to PackageInfo.fromPlatform(), which reads the installed binary and is already reliable. The defines are not required there.

Design choices that keep this safe and non-breaking:

  • PackageInfo.fromPlatform() is untouched. No behavior change for existing users.
  • Opt-in via a separate library that the package barrel does not export. The compile-time guard is evaluated per compiled library, so it only affects code that explicitly imports package_info_plus_environment.dart. Apps that don't opt in are completely unaffected — no new build requirement is imposed package-wide.
  • Cross-platform by construction (single accessor, platform-appropriate source), per the contributing guide's rule against single-platform features.
  • The framework-side requests to expose the build version were declined ("Static" versioning in flutter web flutter/flutter#149725, [WEB] Web Cache invalidation based on pubspec.yaml version flutter/flutter#149031), so a plugin-level opt-in seems to be the only avenue available to users today. If Flutter later injects build name/number defines, this accessor can read them with no API change.

flutter analyze is clean and the existing + new tests pass. The web compile-time enforcement is verified by a compilation test (a web build without the define does not compile) rather than a runtime test.

Related Issues

Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
  • I titled the PR using Conventional Commits.
  • I did not modify the CHANGELOG.md nor the plugin version in pubspec.yaml files.
  • All existing and new tests are passing.
  • The analyzer (flutter analyze) does not report any problems on my PR.

Breaking Change

  • Yes, this is a breaking change.
  • No, this is not a breaking change.

Adds an opt-in library, package_info_plus_environment.dart, exposing
PackageInfoEnvironment.packageInfo. It returns the *running* app's
PackageInfo: on web from compile-time PACKAGE_INFO_PLUS_* dart-defines,
on every other platform by delegating to PackageInfo.fromPlatform().

On web there is no reliable runtime source for the running version:
version.json is fetched from the server, so it reflects the deployed
version rather than the executing (possibly cached) bundle, and the fetch
can fail entirely (offline, CORS, hosting rewrites). The compile-time
constants are embedded in the bundle and cannot diverge from it. A web
build that omits PACKAGE_INFO_PLUS_VERSION fails to compile, so a
misleading version can never ship silently. Native builds are unaffected.

PackageInfo.fromPlatform() is unchanged and the new library is not
exported by the package barrel, so this is purely additive and opt-in.

Related: fluttercommunity#2675, fluttercommunity#225, fluttercommunity#456, flutter/flutter#149031.
@Ortes Ortes force-pushed the package-info-compile-time-version branch from e31c344 to 13e02bd Compare June 12, 2026 11:22
@Ortes Ortes changed the title feat(package_info_plus): support compile-time package info via dart-defines feat(package_info_plus): add opt-in compile-time package info accessor Jun 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: [package_info_plus] Web: Version info returns next version in server

1 participant