---
title: home_widget generate
description: Generate native widget code and a Dart helper from a schema file.
---

# generate

Generate native iOS and Android widget code, plus a typed Dart helper, from `@HomeWidget` annotated schema files defined with [`home_widget_generator`](/generator).

```bash
dart run home_widget_cli generate [options]
```

## Behavior

- The default input is the `home_widget/` directory at the project root. Pass a different file or directory with `--input`.
- If the input is a directory, every `.dart` file in it is scanned recursively for `@HomeWidget` annotations.
- For each widget found:
  - A Dart helper is written to `lib/src/home_widget/<schema-file>.home_widget.dart` by default, where `<schema-file>` is the schema's file name without extension.
  - iOS code is written under `ios/` if the schema declares an `iOS` config.
  - Android code is written under `android/` if the schema declares an `android` config.
- The Dart helper output location can be overridden:
  - `--dart-out` on the CLI takes priority.
  - Otherwise the schema's `dartOutput` is used.
  - Otherwise the default `lib/src/home_widget/...` is used.
- `--dart-out` resolution rules:
  - A path ending in `.dart` is treated as the exact output file.
  - A path with no extension (or an existing directory) is treated as a directory; the auto-generated file name `<schema-file>.home_widget.dart` is appended.
  - Any other extension is rejected.
- The `home_widget` package is automatically added to your `pubspec.yaml` if it isn't already listed as a dependency.
- Flavored projects need no extra flags — a single `generate` run wires every declared flavor on both platforms. See [Flavors](/generator/flavors).

## App version (iOS)

The widget extension has the same `CFBundleShortVersionString` and `CFBundleVersion` as the app, so App Store Connect does not warn about a mismatch. `generate` writes `ios/Flutter/HomeWidget.xcconfig`, which defaults `FLUTTER_BUILD_NAME` and `FLUTTER_BUILD_NUMBER` and then includes the `Generated.xcconfig` Flutter writes on every build. Every build configuration of the extension is based on that file, with `MARKETING_VERSION = "$(FLUTTER_BUILD_NAME)"` and `CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"`. `flutter build ios --build-name` and `--build-number` reach the extension that way.

A configuration that is based on another `.xcconfig` keeps it. It gets the two version settings only when that file, with what it includes, defines both variables, as `Flutter/Debug.xcconfig` does through `Generated.xcconfig` once Flutter has written it. Otherwise its version settings stay as they are and `generate` warns; include `Generated.xcconfig` in that file to fix it. See [Sync CFBundleVersion](/setup/ios#bonus) to set this up by hand.

- `ios/Flutter/HomeWidget.xcconfig` belongs to `generate`, which rewrites it on every run. Commit it, and keep settings of your own in another file.
- A widget extension target you created in Xcode keeps the version settings and the configuration file it has.
- CocoaPods does not replace a configuration file a target already has. If you add the widget extension target to your `Podfile`, base its configurations on a file of your own that includes both the target's Pods `.xcconfig` and `Generated.xcconfig`, the way `Flutter/Debug.xcconfig` and `Flutter/Release.xcconfig` do for the app.

## Manual signing (iOS)

Every build configuration of the widget extension signs the way the app target's configuration of the same name does. The generator copies `DEVELOPMENT_TEAM`, `CODE_SIGN_STYLE` and `CODE_SIGN_IDENTITY` from it, conditional variants such as `DEVELOPMENT_TEAM[sdk=iphoneos*]` included. It reads them the way Xcode does, from the target, the project level and the `.xcconfig` the configuration is based on. A typical release setup that signs manually for devices only:

```text
CODE_SIGN_STYLE = Manual;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=iphoneos*]" = ABCDE12345;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "App Prod";
```

gives the extension the same settings, with a profile of its own:

```text
"PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "App Prod WeatherHomeWidget";
```

- **Automatic**: where the app signs automatically, or sets neither a `CODE_SIGN_STYLE` nor a `PROVISIONING_PROFILE_SPECIFIER`, so does the extension. It gets no identity or profile.
- **Manual**: where the app signs manually, the extension does too, with the app's identity. A configuration that sets no `CODE_SIGN_STYLE` but names a `PROVISIONING_PROFILE_SPECIFIER` counts as manual, as Xcode signs it with that profile; the extension gets `CODE_SIGN_STYLE = Manual` there. Its `PROVISIONING_PROFILE_SPECIFIER` goes under the same keys the app uses. The name comes from `provisioningProfile` on [`HomeWidgetIOSConfiguration`](/generator/annotation#homewidgetiosconfiguration), or on the flavor's [`HomeWidgetIOSFlavor`](/generator/flavors#homewidgetiosflavor). Without one it is the app's profile name followed by the extension's name, `<Widget>HomeWidget`. See [Profile name placeholders](#profile-name-placeholders).
- **No profile name**: a configuration the app signs manually without a `PROVISIONING_PROFILE_SPECIFIER` to derive a name from, for example one that names its profile by UUID in `PROVISIONING_PROFILE`. The generator leaves the extension's `CODE_SIGN_STYLE`, `CODE_SIGN_IDENTITY` and `PROVISIONING_PROFILE_SPECIFIER` as they are there, so signing you set up by hand in Xcode stays; on a newly created target they start as Automatic. Only the team is still synced. `generate` warns and names the configuration. Set `provisioningProfile` to a name without `{appProfile}` to have the generator sign it manually.
- **Not embedded**: a configuration the extension is not embedded in, because the widget's `flavors:` leave that flavor out, sets `CODE_SIGNING_ALLOWED = NO` and signs automatically without a profile, whatever the app does.

The generator does not create certificates or profiles. After a run that changed the project, it lists every profile the extension expects with its bundle ID. Create those profiles for the extension's bundle IDs in your Apple Developer account.

### Profile name placeholders

`provisioningProfile`, on the widget and per flavor, can hold two placeholders. They are filled in per build configuration and per `PROVISIONING_PROFILE_SPECIFIER` key:

| Placeholder | Replaced by |
| --- | --- |
| `{appProfile}` | The app's `PROVISIONING_PROFILE_SPECIFIER` under that same key in that configuration. |
| `{extensionName}` | The extension target's name, `<Widget>HomeWidget`. |

The default, when `provisioningProfile` is not set, is `'{appProfile} {extensionName}'`. A project whose extension profiles follow another scheme sets its own template:

```dart
iOS: HomeWidgetIOSConfiguration(
  groupId: 'group.com.example.app',
  provisioningProfile: '{appProfile}.{extensionName}',
),
```

With the app signing `Debug` with `App Dev` and `Release` with `App Prod`, the extension signs with `App Dev.WeatherHomeWidget` and `App Prod.WeatherHomeWidget`. Because `{appProfile}` differs per configuration, Debug and Release can get different profiles from one template.

- A value with `{appProfile}` names a profile only under the keys where the app names one. In a manually signed configuration where the app names none, it gives no profile name, which is the **No profile name** case above.
- A value without `{appProfile}`, such as `'Weather Widget Prod'` or `'Widgets {extensionName}'`, is used as it is in every configuration it applies to, Debug, Release and Profile alike. Where the app names no profile, it goes under the keys of the conditions the app signs manually in.
- Any other `{…}` placeholder is a validation error.

A profile belongs to one bundle ID. When the same resolved name ends up on manually signed configurations whose extension bundle IDs differ, for example a name without placeholders applied to `com.example.app.dev.WeatherHomeWidget` and `com.example.app.stg.WeatherHomeWidget`, `generate` warns with the profile and the bundle IDs. Use `{appProfile}` or set `provisioningProfile` per flavor.

### Export options

`flutter build ipa --export-options-plist` needs a profile for every bundle ID in the archive. The generator updates every `.plist` directly in `ios/` whose name contains `ExportOptions`, as long as it sets `signingStyle` to `manual` and has a `provisioningProfiles` dictionary. For each app bundle ID listed there, it looks at the app's `Release` and `Release-<flavor>` configurations with that bundle ID:

- **Embedded and signed manually**: `<bundle ID>.<Widget>HomeWidget` is added, or updated, with the profile the extension signs device builds with.
- **Not embedded in any of them**: an existing `<bundle ID>.<Widget>HomeWidget` entry is removed.
- **Embedded without a profile**, because the app signs automatically there or the generator has no profile name for the extension: an existing entry is left alone.
- **No configuration with that bundle ID**: an existing entry is left alone.

When several of those configurations share a bundle ID but sign the extension with different profiles, the plist gets the first one's, and `generate` warns with the bundle ID and the configurations.

Every other entry keeps its value and the file keeps its layout and comments. A rewritten file is not guaranteed to be byte-identical beyond that: text that was escaped without need, such as `&gt;`, is written back as the plain character.

## Options

| Option                  | Description                                                              | Default         |
| ----------------------- | ------------------------------------------------------------------------ | --------------- |
| `-i, --input=<path>`    | Path to schema file or directory.                                        | `home_widget/`  |
| `--dart-out=<path>`     | Output path for the generated Dart helper. Can be a `.dart` file path or a directory. | `lib/src/home_widget/<schema>.home_widget.dart` |

## Examples

Generate from the default `home_widget/` directory:

```bash
dart run home_widget_cli generate
```

Generate from a specific schema file:

```bash
dart run home_widget_cli generate --input home_widget/my_widget.dart
```

Write the Dart helper into a custom directory:

```bash
dart run home_widget_cli generate --dart-out lib/widgets/
```
