← Back to Blog

Fix package:flutter_gen Not Found After Flutter 3.32

flutterl10ni18ngen-l10nmigration

Fix package:flutter_gen Not Found After Flutter 3.32

You upgraded to Flutter 3.32 (or later), ran flutter pub get, and suddenly your whole app is red:

Target of URI doesn't exist: 'package:flutter_gen/gen_l10n/app_localizations.dart'.
Error: Not found: 'package:flutter_gen/gen_l10n/app_localizations.dart'

Nothing is wrong with your ARB files or your translations. What changed is where Flutter puts the generated AppLocalizations class. This is a one-time migration, and below is the exact before/after you can copy-paste to get a green build back.

Why the import broke

For years, flutter gen-l10n wrote your localizations into a synthetic package called package:flutter_gen. It lived in .dart_tool/, never in your source tree, and Flutter injected it into package_config.json behind the scenes. That's why the old import looked like it referenced a real dependency you never added to pubspec.yaml.

The Flutter team deprecated this mechanism. The change landed in 3.28.0-0.0.pre and shipped in the 3.32.0 stable release: the tool no longer generates the synthetic package:flutter_gen or edits package_config.json. In stable releases after that, package:flutter_gen support is removed entirely. Localized messages are now generated into your lib/ source directory like any other Dart file.

So the import fails for a simple reason: the package it points to no longer exists. The fix is to tell gen-l10n where to write the files, then import them from that real path.

Step 1 — Flip synthetic-package to false in l10n.yaml

Open l10n.yaml at the root of your project (create it if you don't have one). This is the single most important change.

Before:

arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart

After:

arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
output-class: AppLocalizations

# The line that fixes the build:
synthetic-package: false

# Optional: send generated files somewhere other than arb-dir
output-dir: lib/l10n/gen

With synthetic-package: false, the generated Dart lands in the path from output-dir, or in arb-dir if you omit output-dir. Keeping generated code alongside your ARB files in lib/l10n is the least surprising choice. If you prefer to isolate generated output (handy for .gitignore rules or lint excludes), point output-dir at a dedicated folder like lib/l10n/gen.

If you maintain a shared package or plugin rather than an app, use output-package to name the package the files are generated for. For a normal app you can ignore it — the files simply belong to your app's own package.

For a full field-by-field breakdown of every l10n.yaml option, see our l10n.yaml configuration guide.

Step 2 — Confirm generate: true in pubspec.yaml

Source generation requires the generate flag. Without it, flutter gen-l10n refuses to run and prints "Attempted to generate localizations code without having the flutter: generate flag turned on."

flutter:
  generate: true
  uses-material-design: true

Make sure flutter_localizations and intl are present too:

dependencies:
  flutter:
    sdk: flutter
  flutter_localizations:
    sdk: flutter
  intl: any

Step 3 — Regenerate the files

Run the generator explicitly so you can see exactly what gets written:

flutter gen-l10n

You should now see the generated files appear in your source tree — for the config above, in lib/l10n/gen/:

lib/l10n/gen/app_localizations.dart
lib/l10n/gen/app_localizations_en.dart
lib/l10n/gen/app_localizations_es.dart

These are real files in lib/ now, not hidden inside .dart_tool/.

Step 4 — Rewrite every old import

This is the part that turns the whole app red, and it's mechanical. The old synthetic import becomes a normal package: import pointing at your own app.

Before:

import 'package:flutter_gen/gen_l10n/app_localizations.dart';

After (replace your_app with the name: from your pubspec.yaml, and match the output-dir path):

import 'package:your_app/l10n/gen/app_localizations.dart';

A relative import works too if you're inside the same directory tree:

import 'l10n/gen/app_localizations.dart';

Your MaterialApp wiring does not change — only the import line does:

import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:your_app/l10n/gen/app_localizations.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(
      title: 'Localizations Sample App',
      localizationsDelegates: AppLocalizations.localizationsDelegates,
      supportedLocales: AppLocalizations.supportedLocales,
      home: HomePage(),
    );
  }
}

Rewrite them all in one command

Don't hunt for imports by hand. From your project root:

# macOS / BSD sed
grep -rl 'package:flutter_gen/gen_l10n' lib test \
  | xargs sed -i '' \
  's|package:flutter_gen/gen_l10n/app_localizations.dart|package:your_app/l10n/gen/app_localizations.dart|g'

On Linux, use sed -i without the empty '' argument. After running it, do a final check that nothing references the old path:

grep -rn 'flutter_gen' lib test

Step 5 — Commit the generated files

Because the code now lives in lib/, decide deliberately how to treat it. Two valid approaches:

  • Commit the generated files. Simplest for CI and for teammates — a fresh checkout builds without a generation step, and code review can see localization changes in the diff. This is the recommended default.
  • Gitignore them and generate in CI. Add lib/l10n/gen/ to .gitignore and run flutter gen-l10n (or let flutter build trigger it) in your pipeline. Keeps the diff clean but requires the generation step everywhere.

Pick one and be consistent. If you commit them, add the files now:

flutter gen-l10n
git add lib/l10n/gen
git commit -m "Migrate l10n off synthetic flutter_gen package"

Gotcha: Pub workspaces

If your project is a Dart pub workspace (a monorepo using resolution: workspace), generate: true can throw "not supported unless explicit-package-dependencies is enabled." Enable the flag:

flutter config --explicit-package-dependencies

Then re-run flutter gen-l10n. This is the most common stumbling block for monorepos on 3.32+, and it's unrelated to your ARB content.

Verify

A clean pass looks like this:

flutter clean
flutter pub get
flutter gen-l10n
flutter analyze

No Not found: 'package:flutter_gen/...', no analyzer errors on AppLocalizations, and your generated files sitting in source. That's the migration done.

Keep your ARB files healthy

The migration only moves where code is generated — it doesn't validate your translations. Missing keys or a dropped ICU plural category (like an absent few/many for Arabic, Polish, or Russian) still slip through gen-l10n silently and surface as runtime gaps.

FlutterLocalisation is a dedicated ARB editor and translation-management platform for exactly these app_<locale>.arb files: edit translations across every locale in a UI instead of raw JSON, and lean on built-in ICU plural-syntax validation that flags a locale missing a plural category its language actually requires. Compare plans on the pricing page.

Try FlutterLocalisation free and keep your ARB files clean while the rest of your l10n pipeline modernizes.