Skip to content

Upgrading

0.6.x to 0.7.x

XWidget 0.7 is a cleanup release: the XML namespaces move to the xwidget.dev domain, configuration and generated schemas move into a .xwidget/ directory, routes and values files get schema validation for the first time, and the APIs deprecated during 0.x are removed. Upgrade xwidget and xwidget_builder together, and update your IDE plugin to 0.2.0 — older plugin versions look for the schema and config at their old locations and lose completion and validation on upgraded projects.

Release contents

Component Version
xwidget 0.7.0
xwidget_builder 0.7.0
xwidget_el 0.7.0
VSCode extension 0.2.0
IntelliJ plugin 0.2.0

Upgrade steps

  1. Set xwidget: ^0.7.0 and xwidget_builder: ^0.7.0 in pubspec.yaml, then run flutter pub get. While the major version is 0, ^0.6.0 cannot resolve to 0.7 — the constraint must be updated by hand.
  2. Run dart run xwidget_builder:generate. The first run migrates xwidget_config.yaml and xwidget_cloud.yaml into .xwidget/, writes the schemas and schema catalog there, and deletes the old root-level schema.
  3. Update the namespace in your fragment files:

    # macOS (BSD sed); on Linux drop the '' after -i
    find resources/fragments -name '*.xml' -exec \
        sed -i '' 's|http://www.appfluent.us/xwidget|https://xwidget.dev/fragments|g' {} +
    

    generate warns with a count while legacy-namespace fragments remain. The runtime doesn't care about the namespace — this only affects IDE validation and completion.

  4. Add xmlns="https://xwidget.dev/values" to the <resources> root of your values files, and xmlns="https://xwidget.dev/routes" to your <routes> file, to get their new schema validation.

  5. Update the IDE plugin to 0.2.0. The VSCode extension rewrites its entry in .vscode/settings.json automatically on the first generate; IntelliJ needs nothing beyond the plugin update.
  6. Replace any of the removed APIs below.

Removed APIs

Removed Replacement
XWidget.navigatorKey XRouter.navigatorKey
XWidget.xmlCacheEnabled none — caching is managed by Resources
XWidget.registerControllerFactory<T> XWidget.registerControllerFactoryForName
XWidget.clearXmlCache() Resources.instance.clearFragmentCache()
XWidget.navigateToFragment() XRouter.navigateToFragment
XWidget.pushFragment() XRouter.navigateToFragment
MaterialStatePropertyOf WidgetStatePropertyOf
<debug> tag none

Other breaking changes

  • generate no longer takes --config; configuration is always read from .xwidget/xwidget_config.yaml.
  • schema.target is no longer configurable — the fragment schema is always written to .xwidget/fragments_schema.g.xsd. A schema.target in your config is ignored with a warning.
  • <fragment> no longer forwards its dependenciesScope attribute to the child fragment as an inherited attribute. This matches what the docs always said; if a nested fragment relied on the leaked value, declare dependenciesScope on it directly.

Downgrading from 0.7.x to 0.6.x

If you need to roll back after upgrading:

  1. Set xwidget: ^0.6.0 and xwidget_builder: ^0.6.0 in pubspec.yaml and run flutter pub get. Confirm pubspec.lock shows 0.6.x.
  2. Move .xwidget/xwidget_config.yaml and .xwidget/xwidget_cloud.yaml back to the project root.
  3. Delete the .xwidget/ directory.
  4. Run dart run xwidget_builder:generate to regenerate the root-level schema and Dart code.
  5. Revert fragment namespaces to http://www.appfluent.us/xwidget (reverse the find-and-replace from step 3 above), and remove the xmlns you added to values and routes files.
  6. The VSCode extension detects the downgrade and restores its old schema registration automatically; IntelliJ needs nothing.

0.5.x to 0.6.x

XWidget 0.6 introduces a new cloud deployment model. Deployments are now immutable and channel-agnostic: every deploy of a version mints a numbered revision, and channels are pointers that select which revision they serve. Deploying stages a bundle; publishing makes it live. Promotion and rollback are both just publishing a chosen revision.

App code using CloudResources needs no changes — the constructor and its parameters are unchanged.

Important

Both xwidget and xwidget_builder must be upgraded together to 0.6.x. This is a coordinated cutover with the XWidget Cloud API: 0.5.x CLI versions are rejected by the server with an upgrade notice. Apps built on 0.5.x keep serving previously downloaded bundles but won't receive bundles deployed with the new model — ship an app update on 0.6 to resume over-the-air updates.

Breaking Changes

xc cloud promote is replaced by publish and unpublish

xc cloud publish -c <channel> -v <version> -r <revision> points a channel at a revision — covering what promote did, plus rollback. xc cloud unpublish removes a channel's pointer without deleting anything. Update any CI scripts that call xc cloud promote.

xc cloud deploy no longer takes --channel

Deploying is channel-less: it uploads the bundle and mints the next revision. The CLI offers to publish afterward, or run xc cloud publish separately.

xc cloud deployment delete scopes changed

Deletion now targets the project: --version plus --revision deletes one revision, --version alone deletes all of a version's revisions. The channel-based scopes are gone — to stop serving a version on a channel, unpublish it instead. Revisions that are live on any channel cannot be deleted until unpublished.

Version format is stricter about build metadata, looser about pre-releases

Build metadata must now be a plain number matching Flutter's build number (1.2.0+42); values like +build.42 or +hotfix are rejected. Pre-release identifiers (1.0.0-beta, 1.0.0-rc.1) are now accepted. The full version string, including the build number, identifies the deployment — bumping the build number starts a fresh revision lineage.

BundleCache interface changed

loadETag()/saveETag() are replaced by loadMetadata()/saveMetadata() using the new BundleMetadata record (channel, version, revision, SHA-256, ETag). This only affects custom BundleCache implementations — the built-in caches migrate transparently, though the first launch after upgrading re-downloads the bundle once.

Analytics event schema changed

Events now report the full version string plus a revision dimension, replacing the old version-number/metadata split. Requires the 0.2.x analytics server. Unsent events queued on-device by a 0.5.x app are discarded during the upgrade.

Migration Steps

  1. Update both dependencies:

    flutter pub upgrade xwidget xwidget_builder
    
  2. Regenerate:

    dart run xwidget_builder:generate
    
  3. If you implemented a custom BundleCache, migrate it to loadMetadata()/saveMetadata().

  4. Update CI scripts that use xc cloud promote or xc cloud deploy --channel to the deploy/publish flow.

  5. Deploy and publish with the 0.6 CLI so your channels serve bundles under the new model.

0.4.x to 0.5.x

XWidget 0.5 restructures initialization around a generated registry and a pluggable resource provider model. One call in main() replaces several, and the resource layer becomes explicit and swappable.

Important

Both xwidget and xwidget_builder must be upgraded together to 0.5.x. Generated code from 0.4.x is not compatible with xwidget 0.5.x.

Breaking Changes

XWidget.initialize() no longer takes fragmentsPath or valuesPath

Resource paths are now configured in xwidget_config.yaml and can be overridden per-provider via the fragmentsPath and valuesPath constructor arguments on LocalResources and CloudResources.

New register parameter on XWidget.initialize()

Registration of generated components is now a single callback. The generator emits registerXWidgetComponents() in lib/xwidget/generated/registry.g.dart that calls the three per-component registrations and sets XWidget.config.

New resources parameter on XWidget.initialize()

Pass an explicit Resources instance (LocalResources or CloudResources) instead of relying on implicit cloud activation via key parameters.

Cloud parameters removed from XWidget.initialize()

projectKey, storageKey, channel, and version are no longer accepted by initialize(). Configure them on CloudResources directly, or use LocalResources.withAnalytics() for analytics without cloud-hosted resources.

xwidget_config.yaml resource paths moved to top level

The resources group is gone. fragmentsPath and valuesPath are now top-level keys.

Before:

resources:
  fragmentsPath: "resources/fragments"
  valuesPath: "resources/values"

After:

fragmentsPath: "resources/fragments"
valuesPath: "resources/values"

New generated output: registry.g.dart

Initialization is simpler in 0.5. What used to take three registration calls and a handful of config parameters is now a single function you pass to XWidget.initialize(). Less boilerplate, less to get wrong, and the generator keeps it in sync with your config automatically.

The generator produces a fourth file alongside inflaters.g.dart, icons.g.dart, and controllers.g.dart. It exports registerXWidgetComponents() — which registers inflaters, icons, and controllers, and applies paths from your config to XWidget.config. It's always regenerated — --only does not skip it.

Migration Steps

  1. Update both dependencies:

    flutter pub upgrade xwidget xwidget_builder
    
  2. Flatten xwidget_config.yaml resource paths (remove the resources: group, promote fragmentsPath and valuesPath to the top level).

  3. Regenerate:

    dart run xwidget_builder:generate
    

This produces the new registry.g.dart alongside the existing generated files.

  1. Update main(). If you were using the default 0.4 pattern:

Before:

```dart
import 'package:xwidget/xwidget.dart';

import 'xwidget/generated/inflaters.g.dart';
import 'xwidget/generated/icons.g.dart';
import 'xwidget/generated/controllers.g.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await XWidget.initialize(
    fragmentsPath: 'resources/fragments',
    valuesPath: 'resources/values',
  );

  registerXWidgetIcons();
  registerXWidgetInflaters();
  registerXWidgetControllers();

  runApp(MyApp());
}
```

After:

```dart
import 'package:xwidget/xwidget.dart';

import 'xwidget/generated/registry.g.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  await XWidget.initialize(register: registerXWidgetComponents);

  runApp(MyApp());
}
```

The three per-component imports collapse to one. The three registration calls collapse into the register callback. Paths come from XWidget.config, which registerXWidgetComponents populates from your xwidget_config.yaml.

  1. If you were using cloud resources in 0.4 (passing projectKey, storageKey, channel, version to initialize()), move those to a CloudResources instance:

Before:

```dart
await XWidget.initialize(
  fragmentsPath: 'resources/fragments',
  valuesPath: 'resources/values',
  projectKey: '<project-key>',
  storageKey: '<storage-key>',
  channel: 'production',
  version: '1.0.0',
);
```

After:

```dart
await XWidget.initialize(
  register: registerXWidgetComponents,
  resources: CloudResources(
    projectKey: '<project-key>',
    storageKey: '<storage-key>',
    channel: 'production',
    version: '1.0.0',
  ),
);
```
  1. If you want cloud analytics but are keeping UI bundled in the app, use LocalResources.withAnalytics:

    await XWidget.initialize(
      register: registerXWidgetComponents,
      resources: LocalResources.withAnalytics(
        projectKey: '<project-key>',
        version: '1.0.0',
      ),
    );
    
  2. Test your app. Fragment inflation, controller resolution, and value lookups should work unchanged.

What did not change

  • Fragment XML syntax, EL expressions, and tag semantics are unchanged.
  • Generated inflater, icon, and controller code shapes are unchanged.
  • The default paths (resources/fragments, resources/values) are unchanged.

What's new in 0.5

  • Hot reload of fragments and values — edit a fragment or value XML file and the running app updates without a restart. Requires an XWidget IDE plugin. See Hot Reload.

0.3.x to 0.4.x

XWidget 0.4.x fixes Dart 3.4 function type compatibility and simplifies the <builder> tag.

Important

Both xwidget and xwidget_builder must be upgraded together to 0.4.x. Generated inflaters from 0.3.x are not compatible with xwidget 0.4.x.

Breaking Changes

nullable attribute removed from <builder> tag

The nullable attribute is no longer needed. It will be silently ignored if present in existing fragments, but should be removed.

Before:

<PageView.builder>
    <builder for="itemBuilder" vars="_,index" nullable="true">
        <Container>
            <Text data="${toString(index)}"/>
        </Container>
    </builder>
</PageView.builder>

After:

<PageView.builder>
    <builder for="itemBuilder" vars="_,index">
        <Container>
            <Text data="${toString(index)}"/>
        </Container>
    </builder>
</PageView.builder>

Builder tag simplified

The <builder> tag no longer manages typed wrapper functions internally. Type adaptation is now handled by the generated inflater via addFnArg. This change is transparent — existing fragments work without modification (aside from removing nullable). See builder for the updated reference.

Generated inflaters require regeneration

The inflater generator now emits addFnArg for all Function-typed constructor parameters. You must regenerate inflaters after upgrading.

Migration Steps

  1. Update both dependencies:

    flutter pub upgrade xwidget xwidget_builder
    

  2. Regenerate inflaters:

    dart run xwidget_builder:generate
    

  3. Remove any nullable attributes from <builder> tags in your fragments.

  4. Test your app — all builders should work without changes.


0.2.x to 0.3.0

XWidget 0.3.0 introduces cloud integration for server-driven UI delivery and analytics.

Breaking Changes

Resources.instance.loadResources() replaced with XWidget.initialize()

The old resource loading call has been replaced with a unified initialization method that handles resources, cloud configuration, and analytics setup in one call.

Before:

void main() async {
   WidgetsFlutterBinding.ensureInitialized();
   await Resources.instance.loadResources('resources');

   // register XWidget components
   registerXWidgetIcons();
   registerXWidgetInflaters();
   registerXWidgetControllers();

   runApp(MyApp());
}

After:

void main() async {
   WidgetsFlutterBinding.ensureInitialized();
   await XWidget.initialize(
      fragmentsPath: 'resources/fragments',
      valuesPath: 'resources/values',
   );

   // register XWidget components
   registerXWidgetIcons();
   registerXWidgetInflaters();
   registerXWidgetControllers();

   runApp(MyApp());
}

To enable cloud resources and analytics, add the cloud parameters:

await XWidget.initialize(
projectKey: '<your-project-key>',
storageKey: '<your-storage-key>',
channel: 'production',
version: '1.0.0',
);

See CloudResources for the current cloud integration documentation.

Logging dependency changed

Replaced package:logger/logger.dart with package:logging/logging.dart. If your code references the logger directly, update your imports.

Minimum Dart SDK increased to 3.4

Update your pubspec.yaml SDK constraint:

environment:
   sdk: '>=3.4.0 <4.0.0'

Migration Steps

  1. Update your dependencies:

    flutter pub upgrade xwidget xwidget_builder
    

  2. Replace Resources.instance.loadResources() with XWidget.initialize() in your main() function.

  3. Update any package:logger imports to package:logging.

  4. Regenerate components:

    dart run xwidget_builder:generate
    

  5. Verify your Dart SDK constraint is >=3.4.0.


0.1.x to 0.2.0

XWidget 0.2.0 updates the Flutter and Dart minimum version requirements.

Breaking Changes

  • Increased Flutter version constraint from >=1.17.0 to >=3.10.0
  • Increased Dart SDK constraint from >=2.19.6 to >=3.0.0
  • Updated xwidget_el dependency from 0.2.0 to 0.2.2
  • Added support for AssetManifest.bin with fallback to .json for older Flutter versions

Migration Steps

  1. Ensure your Flutter version is 3.10.0 or higher:

    flutter --version
    

  2. Update your dependencies:

    flutter pub upgrade xwidget xwidget_builder
    

  3. Regenerate components:

    dart run xwidget_builder:generate
    


0.0.x to 0.1.0

XWidget 0.1.0 separates development tools from the runtime into a dedicated xwidget_builder package.

Breaking Changes

  • Code generators and initializers moved to xwidget_builder (dev dependency).
  • The dart run xwidget:generate command becomes dart run xwidget_builder:generate.
  • The dart run xwidget:init command becomes dart run xwidget_builder:init.

Migration Steps

  1. Install the development tools as a dev dependency:

    flutter pub add dev:xwidget_builder
    

  2. Regenerate components using the new command:

    dart run xwidget_builder:generate
    

  3. Update any scripts or CI pipelines that reference xwidget:generate or xwidget:init to use xwidget_builder:generate and xwidget_builder:init.