bloomBUILD•SHIP•BLOOM
.md
Rapid Onboarding

5-Minute Quickstart

Build a reactive full-stack Bloom application with file-based routing, Signals state management, and dependency injection in under five minutes.

1

Create a New Project

Run bloom create to scaffold a modern Bloom application:

Terminal
bash
bloom create quickstart_app
cd quickstart_app
2

Add a Controller with Signals Reactivity

Controllers extend BloomController and manage fine-grained reactive signals:

lib/features/counter/counter_controller.dart
dart
// lib/features/counter/counter_controller.dart
import 'package:bloom_framework/bloom.dart';

class CounterController extends BloomController {
  late final count = createSignal<int>(0, debugLabel: 'counter.count');

  void increment() {
    count.value++;
  }

  void decrement() {
    if (count.value > 0) {
      count.value--;
    }
  }

  void reset() {
    count.value = 0;
  }
}
3

Create a Filesystem Route

Create lib/routes/counter.dart. Bloom automatically generates typed routing definitions in lib/app/routes.g.dart:

lib/routes/counter.dart
dart
// lib/routes/counter.dart
import 'package:flutter/material.dart';
import 'package:bloom_framework/bloom.dart';
import '../features/counter/counter_controller.dart';

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

  @override
  Widget build(BuildContext context) {
    // Resolve controller via Bloom DI
    final controller = inject<CounterController>();

    return Scaffold(
      appBar: AppBar(
        title: const Text('Bloom Counter'),
        actions: [
          IconButton(
            icon: const Icon(Icons.refresh),
            onPressed: controller.reset,
          ),
        ],
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            const Text(
              'Current Count:',
              style: TextStyle(fontSize: 18, color: Colors.grey),
            ),
            const SizedBox(height: 8),
            // Rebuilds ONLY this text widget when controller.count updates
            Watch((context) => Text(
              '${controller.count.value}',
              style: const TextStyle(fontSize: 56, fontWeight: FontWeight.bold),
            )),
            const SizedBox(height: 24),
            Row(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                FilledButton.tonal(
                  onPressed: controller.decrement,
                  child: const Icon(Icons.remove),
                ),
                const SizedBox(width: 16),
                FilledButton(
                  onPressed: controller.increment,
                  child: const Icon(Icons.add),
                ),
              ],
            ),
          ],
        ),
      ),
    );
  }
}
4

Register Controller in Bootstrapper

Open lib/app/boot.dart and register dependencies inside onBoot:

lib/app/boot.dart
dart
// lib/app/boot.dart
import 'package:bloom_framework/bloom.dart';
import '../features/counter/counter_controller.dart';

class AppBootstrapper implements BloomBootstrapper {
  @override
  Future<void> onBoot(BloomContainer container) async {
    // Register CounterController as a lazy singleton
    container.provideSingleton<CounterController>((c) => CounterController());
  }
}
5

Launch Developer Server

Terminal
bash
bloom dev
Interactive Keyboard Controls
  • r Trigger Hot Reload
  • R Trigger Hot Restart
  • w Wireless QR Pairing
  • d Open Flutter DevTools