Dart Import Tricks Every Flutter Developer Should Know

Master Dart's import system — using hide and show to resolve naming conflicts, deferred loading for code splitting, aliasing packages, and conditional imports for platform-specific code.

Dart Import Tricks Every Flutter Developer Should Know

Dart’s import system is more powerful than most developers realize. Beyond the basic import 'package:...', there are several features that help you resolve naming conflicts, reduce bundle size, and organize code cleanly.

show — Import Only What You Need

show lets you import only specific symbols from a library, keeping your namespace clean:

// Without show: brings in everything from material.dart
import 'package:flutter/material.dart';

// With show: only imports Text and Container
import 'package:flutter/material.dart' show Text, Container;

// Now only Text and Container are available — cleaner namespace
Text('Hello');
Container(child: Text('World'));

// This would be an error — Widget wasn't imported
Widget build() { /* ... */ } // Error: Widget not found

hide — Import Everything Except

hide is the inverse — import everything except the listed symbols. This is especially useful when two packages export a name that conflicts:

// Both packages export a 'Text' class — conflict!
import 'package:flutter/material.dart';
import 'package:some_other_package/some_other_package.dart'; // also exports Text

// Solution: hide the one you don't want
import 'package:flutter/material.dart' hide Text;
import 'package:some_other_package/some_other_package.dart' show Text;

// Now 'Text' unambiguously refers to some_other_package's Text

as — Namespace Aliasing

When two libraries export the same name, prefix one with an alias:

import 'package:flutter/material.dart' as material;
import 'package:my_design_system/components.dart' as ds;

// Disambiguate with the prefix
material.Text('Flutter Text');
ds.Text('Design System Text');

Aliases also make it clear where a class comes from in large files:

import 'package:http/http.dart' as http;

final response = await http.get(Uri.parse('https://api.example.com'));
//                   ^^^^ clearly from the http package

Deferred Imports — Code Splitting

deferred as loads a library lazily — only when you actually need it. This is Dart’s built-in code splitting, which reduces initial load time for Flutter Web and Dart apps.

import 'package:my_package/my_file.dart' deferred as my_file;

// The library is NOT loaded at startup
// You must call loadLibrary() before using anything from it
Future<void> loadFeature() async {
  await my_file.loadLibrary(); // Downloads/loads the library
  my_file.MyWidget();          // Safe to use after loading
}

Practical Example: Lazy-Load a Heavy Screen

import 'package:flutter/material.dart';
import 'screens/heavy_analytics_screen.dart' deferred as analytics;

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  bool _analyticsLoaded = false;

  Future<void> _openAnalytics() async {
    // Load the deferred library on demand
    await analytics.loadLibrary();
    setState(() => _analyticsLoaded = true);

    if (mounted) {
      Navigator.push(
        context,
        MaterialPageRoute(builder: (_) => analytics.AnalyticsScreen()),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: _openAnalytics,
          child: const Text('Open Analytics'),
        ),
      ),
    );
  }
}

The AnalyticsScreen and all its dependencies are only downloaded when the user taps the button — not at app startup.

Conditional Imports — Platform-Specific Code

For libraries that need different implementations on different platforms (e.g., web vs native):

// storage.dart — the abstract interface
abstract class Storage {
  Future<void> write(String key, String value);
  Future<String?> read(String key);
}

// Import different implementations based on platform
import 'storage_native.dart'
    if (dart.library.html) 'storage_web.dart';
// storage_native.dart — uses shared_preferences on mobile
import 'package:shared_preferences/shared_preferences.dart';

class Storage {
  Future<void> write(String key, String value) async {
    final prefs = await SharedPreferences.getInstance();
    await prefs.setString(key, value);
  }

  Future<String?> read(String key) async {
    final prefs = await SharedPreferences.getInstance();
    return prefs.getString(key);
  }
}
// storage_web.dart — uses localStorage on web
import 'dart:html';

class Storage {
  Future<void> write(String key, String value) async {
    window.localStorage[key] = value;
  }

  Future<String?> read(String key) async {
    return window.localStorage[key];
  }
}

The right implementation is chosen automatically at compile time.

Part Imports — Splitting a Library Across Files

For large libraries, use part and part of to split code across files while keeping them in the same library:

// math_utils.dart — the main library file
library math_utils;

part 'src/geometry.dart';
part 'src/statistics.dart';
// src/geometry.dart
part of math_utils; // ← declares it's part of the math_utils library

double circleArea(double radius) => 3.14159 * radius * radius;

Note: part/part of is less common in modern Dart. Prefer regular import with barrel files (index.dart) for most cases.

Barrel Files — Clean Re-Exports

A common pattern for organizing a package is a barrel file that re-exports everything:

// lib/my_package.dart — the public API of your package
export 'src/button.dart';
export 'src/card.dart';
export 'src/modal.dart' hide ModalController; // Hide internal types
export 'src/types.dart' show ButtonVariant, CardStyle; // Only expose public types

Consumers import one file and get everything:

import 'package:my_package/my_package.dart';

Button(variant: ButtonVariant.primary);

Quick Reference

FeatureSyntaxUse Case
Import allimport 'package:...'Standard usage
Import specificimport '...' show Foo, BarAvoid namespace pollution
Import exceptimport '...' hide FooResolve naming conflicts
Aliasimport '...' as nameDisambiguate same-name classes
Lazy loadimport '...' deferred as nameCode splitting / on-demand loading
Platform conditionalimport 'x.dart' if (dart.library.html) 'y.dart'Cross-platform libraries

💬 Want to learn, build, and grow with a community of developers? Join the King Technologies Discord — where code meets community!