This simple package adds static extension methods and getters to the BuildContext context object from the widgets, material, and cupertino libraries.

xcontext makes it easy for you to add static extensions methods and getters to your context from Flutter's widgets, material, and cupertino libraries. You have total control over which methods and getters you want to add to your context, with all the type safety guarantees Dart provides, while keeping your code concise and clean.

Continuous Integration xcontext Published by dartside.dev GitHub Stars Count

About this package

This package is an experiment to get rid of the SomeClass.of(context).someMethod calls in a codebase. As I was talking to people new to Flutter, I noticed that some people just can't wrap their heads around it, while simple getters and methods just feel intuitive to all of them. The package also simplifies other function calls that require the context to be passed in. I wrote the package in a way that is easy to customize to your needs and selectively add or hide extensions.

Using the package will hopefully make your code easier to type, read and understand.

It's important to mention that the .of static methods should not be considered harmful in any way. If you like that idiom, please feel free to continue using it!


// Add all methods and getters to BuildContext
import 'package:xcontext/xcontext.dart';

BuildContext context;
// then...
context.showCupertinoDialog(builder: b, useRootNavigator: true); // Don't forget to define the builder.
context.showTimePicker(initialTime: TimeOfDay.now());

If you prefer to be even more concise, use the "tiny" version:

// tiny_xcontext uses shorter names and does not add all getters
import 'package:xcontext/tiny_xcontext.dart';

BuildContext context;
// then...
context.theme; // Not all getters are shortened. Theme is short enough already
// context.dividerTheme; // Not all getters are available in "tiny" mode
context.showCupDialog(builder: builder, useRootNavigator: true); // Don't forget to define the builder.
context.showTP(initialTime: TimeOfDay.now());

The libraries of this package

// Add all methods and getters to BuildContext
import 'package:xcontext/xcontext.dart';
// Alternatively, if you want to extend only from some libraries:
import 'package:xcontext/cupertino.dart';
import 'package:xcontext/material.dart';
import 'package:xcontext/widgets.dart';

// Add some methods and getters to BuildContext, some are shortened
import 'package:xcontext/tiny_xcontext.dart';
// Alternatively, if you want to extend only from some libraries with the short version
import 'package:xcontext/tiny_cupertino.dart';
import 'package:xcontext/tiny_material.dart';
import 'package:xcontext/tiny_widgets.dart';

Libraries: xcontext, cupertino, material, widgets, tiny_xcontext tiny_cupertino tiny_material tiny_widgets

From Navigator.of(context) to context.navigator

The xcontext package lets you access Something.of(context).someMethod directly on the context as context.something.someMethod. It adds all the .of static methods from the official widgets, material, and cupertino libraries' return value as getters.

So after you imported 'package:xcontext/xcontext.dart', you will be able to write:

import 'package:xcontext/xcontext.dart';

class Example extends StatelessWidget {
  Widget build(BuildContext context) {
    // Instead of Theme.of(context), just write: 
    final theme = context.theme;
    // ...and use the theme as usual:
    print('Current brightness is ${theme.brightness}');
    // ...
    return RaisedButton(
      onPressed: () {
        // Instead of Navigator.of(context), use context.navigator
      child: Text('Navigator push'),

In case the .of static method accepts extra parameters, those values are exposed in a different getter, such as:

// Navigator.of(context, rootNavigator: true)
// Theme.of(this, shadowThemeOnly: true);

Show this, show that!

All showXYZ methods are added, as well, so now you can write:

import 'package:xcontext/xcontext.dart';
// You can import either xcontext or only material to get showAboutDialog
// import 'package:xcontext/material.dart';

  onPressed: () {
      applicationName: 'xcontext example app',
      applicationIcon: FlutterLogo(),
      applicationLegalese: 'Copyright 2020',
      applicationVersion: '1.2.3',
      children: [
        Text('Thank you for using this package!'),


While the extensions might improve the discoverability of some values, seeing tens of extra methods popping up in your IDE whenever you type "context." can be annoying. For this reason, every getter and method is added as a separate extension, so you can hide or show them as you like.

// // HIDE // //
// If one or more extensions annoy you, hide them.
import 'package:xcontext/material.dart' hide XContextNavigationRailTheme;

// // SHOW // //
// If you only need some extensions, show them, and hide all others.
// Only show context.navigator and context.rootNavigator
import 'package:xcontext/widgets.dart' show XContextNavigator, XContextRootNavigator;

You can export only what you need

You might conclude that, while using some extensions from the package is great, the other extensions are less great, so you want see only a subset of the extensions everywhere.

Just create a new Dart file, for example your_favorite_extensions.dart, export the extensions you like, and import this file in the rest of your codebase.

// your_favorite_extensions.dart
export 'package:xcontext/xcontext.dart'
    show XContextShowGeneralDialog,  // context.showGeneralDialog
         XContextNavigator, // context.navigator
         XContextRootNavigator, // context.rootNavigator
         XContextScaffold,  // context.scaffold
         XContextMediaQuery; // context.mediaQuery

// You may even write your own context extensions here.
// Some other file...
import 'package:your_awesome_app/your_favorite_extensions.dart';

The tiny variation

This package also has a tiny variation of the extensions. The tiny version is great is you prefer brevity. 'package:xcontext/tiny_xcontext.dart' does not include all the possible getters and methods, and some getters were renamed so that you can write less code while keeping everything straightforward:

import 'package:xcontext/tiny_xcontext.dart';

// then...
final isLight = context.mq.platformBrightness == Brightness.light;