What's the best practice to keep all the constants in Flutter?

My preferred solution is to make my own Dart library.

Make a new dart file named constants.dart, and add the following code:

const String SUCCESS_MESSAGE=" You will be contacted by us very soon.";

Edit: 99% of the time you don't need to explicitly name your dart libraries with a statement like library library_name; at the top of your file, and you probably shouldn't (reference).
Even if you leave out this line your file will still be library! It will just be implicitly named.

Then add the following import statement to the top of any dart file which needs access to the constants:

import 'constants.dart' as Constants;

Note if constants.dart is in different directory then you will need to specify the path to constants.dart in your import statement.

In this example:

enter image description here

You could use a relative path:

import '../assets/constants.dart' as Constants;

Or an absolute path from the lib directory:

import 'package:<your_app_name>/assets/constants.dart' as Constants;

Now you can easily access your constants with this syntax:

String a = Constants.SUCCESS_MESSAGE;

EDIT

Now that the flag --dart-define has been added to the different command lines of Flutter, the following answer no-longer applies.

Instead just declare constants wherever you want, and potentially refer to other answers.


While there are no technical issues with static const, architecturally you may want to do it differently.

Flutter tend to not have any global/static variables and use an InheritedWidget.

Which means you can write:

class MyConstants extends InheritedWidget {
  static MyConstants of(BuildContext context) => context. dependOnInheritedWidgetOfExactType<MyConstants>();

  const MyConstants({Widget child, Key key}): super(key: key, child: child);

  final String successMessage = 'Some message';

  @override
  bool updateShouldNotify(MyConstants oldWidget) => false;
}

Then inserted at the root of your app:

void main() {
  runApp(
    MyConstants(
      child: MyApp(),
    ),
  );
}

And used as such:

@override
Widget build(BuilContext context) {
  return Text(MyConstants.of(context).successMessage);
}

This has a bit more code than the static const, but offer many advantages:

  • Works with hot-reload
  • Easily testable and mockable
  • Can be replaced with something more dynamic than constants without rewriting the whole app.

But at the same time it:

  1. Doesn't consume much more memory (the inherited widget is typically created once)
  2. Is performant (Obtaining an InheritedWidget is O(1))

That's completely up to you.
Using static has no disadvantages.
Actually const is required for fields in a class.