Air Framework πŸš€

Air Framework Logo

pub package License: MIT style: lint docs

A modular, reactive, and scalable framework for Flutter. Build industrial-grade apps with a decoupled architecture inspired by enterprise app concepts.

Why Air Framework?

As apps grow, they become harder to maintain. Air Framework solves this by enforcing strict module boundaries, unidirectional data flow, and explicit dependencies. It's not just a state management library; it's a complete architecture for teams building large-scale Flutter applications.


✨ Features

Feature Description
🧩 Modular Architecture Self-contained, independent modules with clear boundaries
πŸ”Œ Adapters Headless service integrations (HTTP, analytics, error tracking)
⚑ Reactive State Built-in state management using Air State controller with typed flows
πŸ’‰ Dependency Injection Type-safe DI with scoped services and lifecycle management
πŸ”’ Security Permission system, secure logging, and audit trails
πŸ›£οΈ Routing Integrated routing with go_router support
πŸ› οΈ DevTools Built-in debugging panels for state, modules, adapters, and performance
πŸ§ͺ Testing Utilities Mock controllers and test helpers included

πŸ—οΈ Architecture

Every feature is a Module. Modules declare their dependencies explicitly and communicate via a typed Event Bus.

App Shell
β”œβ”€β”€ Notes Module
β”œβ”€β”€ Weather Module
└── Dashboard Module
    β”œβ”€β”€ depends on β†’ Notes
    └── depends on β†’ Weather

Core Framework
β”œβ”€β”€ AirDI          (Dependency Injection)
β”œβ”€β”€ AirRouter      (Routing)
β”œβ”€β”€ EventBus       (Cross-module communication)
β”œβ”€β”€ AirState       (Reactive state management)
β”œβ”€β”€ AdapterManager (Infrastructure services)
└── DevTools       (Debugging inspector)

πŸ“¦ Installation

Add air_framework to your pubspec.yaml:

dependencies:
  air_framework: # latest version from pub.dev

For the complete development experience, also install the CLI:

dart pub global activate air_cli

πŸš€ Quick Start

1. Create a Module

Define a module by extending AppModule. This encapsulates your routes, bindings, and initialization logic.

import 'package:air_framework/air_framework.dart';

class CounterModule extends AppModule {
  @override
  String get id => 'counter';

  @override
  List<AirRoute> get routes => [
    AirRoute(
      path: '/counter',
      builder: (context, state) => const CounterPage(),
    ),
  ];

  @override
  void onBind(AirDI di) {
    // Register dependencies lazily
    di.registerLazySingleton<CounterState>(() => CounterState());
  }
}

2. Define State

Use the @GenerateState annotation to magically generate reactive Flows and Pulses.

Simply modify fields like a standard Dart class (e.g. count++), and the framework automatically detects the change and updates only the widgets listening to that value. No boilerplate, no notifyListeners()β€”just pure logic.

import 'package:air_framework/air_framework.dart';

part 'state.air.g.dart';

@GenerateState('counter')
class CounterState extends _CounterState {
  // Private fields become reactive StateFlows
  int _count = 0;

  // Public methods become dispatchable Pulses
  @override
  void increment() {
    count++;
  }
}

3. Build Reactive UI

Use AirView to listen to state changes efficiently. It automatically tracks which flows are accessed and rebuilds only when necessary.

class CounterPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: AirView((context) {
          // Auto-subscribes to 'count'
          return Text('Count: ${CounterFlows.count.value}');
        }),
      ),
      floatingActionButton: FloatingActionButton(
        // Triggers the 'increment' pulse
        onPressed: () => CounterPulses.increment.pulse(null),
        child: const Icon(Icons.add),
      ),
    );
  }
}

4. Initialize Your App

Register your modules in main.dart.

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // 1. Configure Air State
  configureAirState();

  // 2. Register Adapters (infrastructure β€” BEFORE modules)
  final adapters = AdapterManager();
  await adapters.register(DioAdapter(baseUrl: 'https://api.example.com'));

  // 3. Register Modules (features β€” can use adapter services)
  await ModuleManager().register(CounterModule());

  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      title: 'Air App',
      routerConfig: AirRouter().router,
    );
  }
}

πŸ”Œ Adapters

Adapters are headless service integrations. Unlike modules, they have no routes or UI β€” they register infrastructure services (HTTP clients, error tracking, analytics) in AirDI for modules to consume.

class SentryAdapter extends AirAdapter {
  @override
  String get id => 'sentry';

  @override
  void onBind(AirDI di) {
    super.onBind(di);
    // Register the abstract contract, not the concrete class
    di.registerLazySingleton<ErrorReporter>(() => SentryReporter());
  }
}

Key rule: every adapter must expose an abstract contract so modules never couple to a specific library.

lib/adapters/<service>/
β”œβ”€β”€ contracts/
β”‚   β”œβ”€β”€ <service>_client.dart     ← abstract interface
β”‚   └── <service>_response.dart
β”œβ”€β”€ <service>_adapter.dart         ← AirAdapter subclass
└── <service>_impl.dart            ← concrete implementation

Generate with the CLI: air g adapter sentry


πŸ”§ CLI Tools

The Air CLI allows you to scaffold modules and generate state files instantly.

# Create a new project
air create my_app --template=starter

# Generate a new module
air generate module inventory

# Generate an adapter
air generate adapter sentry

# Generate state code
air generate state cart --module=inventory

Package Description
air_cli Command-line scaffolding tool
air_state Core reactive state package
air_generator Build runner code generation

🀝 Contributing

Contributions are welcome! Please read our contributing guidelines first.

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.


πŸ“– Documentation

For the full documentation, guides, and API reference visit:

πŸ‘‰ air-framework.flutter.md


Made by Andrey D. Araya

Libraries

air_framework
Air Framework A modular and reactive framework for Flutter.
core/adapter_manager
core/air_adapter
core/app_module
core/core
core/module_manager
framework/bridge/secure_air_delegate
framework/communication/communication
Communication module exports
framework/communication/event_bus
framework/communication/module_context
framework/communication/schema_validation
framework/communication/version_resolver
framework/devtools/debug_inspector
framework/devtools/devtools
Developer tools module exports
framework/devtools/devtools_cli
framework/devtools/module_logger
framework/devtools/performance_monitor
framework/devtools/tabs/adapters_tab
framework/devtools/tabs/air_graph_tab
framework/devtools/tabs/di_tab
framework/devtools/tabs/logs_tab
framework/devtools/tabs/modules_tab
framework/devtools/tabs/performance_tab
framework/devtools/tabs/pulses_tab
framework/devtools/tabs/state_tab
framework/devtools/tabs/tabs
framework/devtools/widgets/shared_widgets
framework/di/di
framework/framework
framework/generator/annotations
Annotations for Air Framework code generation INNOV-010: GeneraciΓ³n de CΓ³digo con Build Runner
framework/generator/generated_base
framework/generator/generator
Air Framework Code Generation INNOV-010: GeneraciΓ³n de CΓ³digo con Build Runner
framework/router/air_route
framework/router/air_router
framework/router/router
framework/security/air_audit
framework/security/air_logger
framework/security/identity
framework/security/permissions
framework/security/secure_service_registry
framework/security/security
Security module exports
framework/state/air
framework/testing/testing
framework/utils/air_di
framework/utils/analytics
framework/utils/federated_modules
framework/utils/hot_reload
framework/utils/utils