As a seasoned software engineer working extensively with Flutter and Dart, I often come across questions like:
"When should I use part vs import? What’s the difference between export and import? Is there a clean way to split Dart files while maintaining readability and scalability?"
These questions usually come from developers looking to create well-structured, maintainable codebases. In this post, we’ll deeply explore Dart’s import, export, part, and part of directives — not just what they are, but when, why, and how to use them in real-world Flutter and Dart projects.
1. import: Bringing Code In
What It Does
The import directive is used to include external Dart libraries into your current file so you can use classes, functions, constants, etc., defined elsewhere.
import 'package:flutter/material.dart';
import 'my_utils.dart';
Key Points
Supports both package and relative paths.
Prevents name clashes via
as,show, orhide:
import 'utils.dart' as utils;
import 'math.dart' show add;
import 'math.dart' hide subtract;
When to Use
Always prefer
importwhen including a reusable, standalone file.Use
asfor namespaces in large codebases.
2. export: Sharing Code Out
What It Does
The export directive allows you to re-expose public APIs from one file in another — effectively acting as a public interface.
export 'src/models.dart';
export 'src/utils.dart';
Real-World Example
In a package:
// library.dart
export 'src/button.dart';
export 'src/input.dart';
Now, instead of:
import 'src/button.dart';
import 'src/input.dart';
You just do:
import 'library.dart';
When to Use
Building packages or public libraries.
Creating a clean API surface.
3. part: Breaking a File Into Pieces
What It Does
part is used to split a single Dart library (file) into multiple parts, all of which share the same scope and namespace.
// main.dart
library my_library;
part 'file_a.dart';
part 'file_b.dart';
In file_a.dart:
part of my_library;
Key Points
All
partfiles must declarepart of <library_name>;Code is treated as if written in the main file — same scope.
Useful for splitting large files into smaller chunks.
When to Use
For logically grouped files that are not reusable independently.
Good for code generators (e.g.,
freezed,json_serializable).Avoid in modular/shared code; prefer
importfor those cases.
4. part of: Declaring a Sub-File
What It Does
part of is used in a file that is a subcomponent of a main Dart library file.
part of my_library;
This tells Dart that this file doesn’t stand on its own — it’s part of another file.
Rules
Cannot use
importorexportin apart offile.Cannot run independently.
Choosing Between import and part
Use Case | Recommended Directive |
|---|---|
Independent utility or module |
|
Code-gen driven file grouping |
|
Re-exporting API layers |
|
If you want modular, testable, and scalable architecture — prefer import.
Use part only when files must share scope tightly (e.g., annotated models and their generated code).
Best Practices & Real-World Advice
✅ Use
exportto simplify imports in consumer code.✅ Use
part/part ofonly when it’s required (e.g., code generation).❌ Don’t use
partto avoid writingimport— it creates tight coupling.✅ Keep a consistent folder structure (e.g.,
lib/src/,lib/ui/,lib/models/).✅ Use a
library.dartto aggregate and re-export key modules.
Final Thoughts
Understanding these four keywords is crucial to architecting clean, scalable Dart and Flutter projects. While import and export are your main tools for modularity and reuse, part and part of are valuable in niche cases like code generation and large file organization.
Write code as if you’re creating a public package — even for yourself.
That mindset will guide you toward using these tools wisely.
Happy coding!
