The intl Package for Localization in Flutter: A Deep Dive
Master the intl package for Dart and Flutter localization. Learn date formatting, number parsing, pluralization, and message extraction for global apps.
Published on • September 19, 2026
AI Assistant

The intl Package for Localization in Flutter: A Deep Dive
The intl package is the backbone of localization in Dart and Flutter. It provides internationalization and localization utilities including message formatting, date/number parsing, pluralization, and bidirectional text support.
What is the intl Package?
The intl package (part of the Dart project) implements:
- Date formatting and parsing with locale-aware patterns
- Number formatting and parsing for currencies, percentages, and plain numbers
- Message formatting with ICU message syntax for plurals and selects
- Bidirectional text support for mixed RTL/LTR content
- Character boundary analysis for proper text iteration
Installation
dependencies:
intl: ^0.20.0
Date Formatting
The intl package provides DateFormat for locale-aware date formatting:
import 'package:intl/intl.dart';
// Full date format
final fullFormat = DateFormat.yMMMMd('en_US');
print(fullFormat.format(DateTime(2026, 9, 19)));
// Output: September 19, 2026
// Short date format
final shortFormat = DateFormat.yMMMd('ja_JP');
print(shortFormat.format(DateTime(2026, 9, 19)));
// Output: 2026/09/19
// Custom patterns
final customFormat = DateFormat('EEEE, MMMM d, yyyy', 'de_DE');
print(customFormat.format(DateTime(2026, 9, 19)));
// Output: Samstag, September 19, 2026
// Time formatting
final timeFormat = DateFormat.Hms('fr_FR');
print(timeFormat.format(DateTime(2026, 9, 19, 14, 30, 45)));
// Output: 14:30:45
// Relative time
final relativeFormat = DateFormat.EEEE('ar');
print(relativeFormat.format(DateTime(2026, 9, 19)));
// Output: السبت
Number Formatting
NumberFormat handles locale-aware number, currency, and percentage formatting:
import 'package:intl/intl.dart';
// Currency formatting
final usdFormat = NumberFormat.currency(locale: 'en_US', symbol: '\$');
print(usdFormat.format(1234567.89));
// Output: $1,234,567.89
final eurFormat = NumberFormat.currency(locale: 'de_DE', symbol: '€');
print(eurFormat.format(1234567.89));
// Output: 1.234.567,89 €
// Percentage formatting
final percentFormat = NumberFormat.percentPattern('en_US');
print(percentFormat.format(0.856));
// Output: 86%
// Compact notation (e.g., "1.2M")
final compactFormat = NumberFormat.compact(locale: 'en_US');
print(compactFormat.format(1234567));
// Output: 1.2M
// Decimal patterns
final decimalFormat = NumberFormat.decimalPattern('hi_IN');
print(decimalFormat.format(1234567.89));
// Output: 12,34,567.89
Pluralization with ICU Messages
The intl package supports ICU message syntax for complex pluralization:
import 'package:intl/intl.dart';
// Using Intl.message with plurals
String itemCount(int count) => Intl.plural(
count,
zero: 'No items',
one: '1 item',
other: '$count items',
name: 'itemCount',
args: [count],
desc: 'Number of items in the cart',
examples: const {'count': 5},
);
print(itemCount(0)); // No items
print(itemCount(1)); // 1 item
print(itemCount(5)); // 5 items
Message Extraction
The intl package includes tools for extracting translatable messages from your Dart code:
# Extract messages to ARB files
dart run intl_utils:generate
# This scans your code for Intl.message() calls
# and creates ARB files in your l10n directory
Bidirectional Text
For apps that mix RTL and LTR text (common in Arabic, Hebrew, etc.):
import 'package:intl/bidi.dart';
// Force text direction
final rtlText = Bidi.stripHtmlIfNeeded('مرحبا Hello World');
print(Bidi.textDirection(rtlText)); // TextDirection.RTL
// Embed LTR in RTL context
final mixed = Bidi.embedControls('مرحبا Hello World');
Integration with Flutter
The intl package integrates seamlessly with Flutter’s localization system:
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
import 'package:intl/intl.dart';
class FormattedDateWidget extends StatelessWidget {
final DateTime date;
const FormattedDateWidget({super.key, required this.date});
@override
Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context)!;
final locale = l10n.localeName;
return Text(
DateFormat.yMMMMd(locale).format(date),
style: Theme.of(context).textTheme.headlineSmall,
);
}
}
Best Practices
- Use named parameters in
Intl.messagefor clarity - Always provide descriptions — translators need context
- Use examples to help translators understand format expectations
- Run the extractor regularly to keep ARB files in sync
- Test with plural edge cases — 0, 1, 2, and large numbers
The intl package is an indispensable tool for any Flutter developer building global applications. Its robust formatting, pluralization, and message extraction capabilities make internationalization straightforward and maintainable.