Getting started
Install
dependencies:
back_stack: ^0.6.0Hello world
Three pieces: typed destinations, a screen per destination, and the stack.
BackStackApp renders it — that's the whole app:
import 'package:back_stack/back_stack.dart';
import 'package:flutter/material.dart';
// Destinations — plain Dart types. Arguments are real fields.
abstract class AppKey extends NavKey { const AppKey(); }
class Home extends AppKey { const Home(); }
class Product extends AppKey { const Product(this.id); final int id; }
final entries = NavEntries<AppKey>()
..on<Home>((context, key) => const HomeScreen())
..on<Product>((context, key) => ProductScreen(id: key.id));
final stack = NavStack<AppKey>.of(const Home());
void main() => runApp(BackStackApp<AppKey>(stack: stack, entries: entries));System back, the Android predictive-back gesture, and the hardware button already flow into the stack — nothing to wire.
Navigate by changing the list
The stack is a List you own. There's no go vs push — one operation,
mutate the list:
stack.push(const Product(42)); // forward
stack.pop(); // back
stack.replaceAll([const Home()]); // reset a flow (e.g. after login)Navigate from a screen
Every screen can reach the stack with BackStack.of<AppKey>(context) — pass
the key type so the lookup finds your stack:
onTap: () => BackStack.of<AppKey>(context).push(const Product(42)),of doesn't rebuild on change (right for event handlers). Pass listen: true
when a widget should rebuild when the stack changes.
Without BackStackApp
BackStackApp is convenience, not magic. NavDisplay is a plain widget that
renders a stack — host it inside your own MaterialApp, or anywhere in an
existing app:
MaterialApp(home: NavDisplay<AppKey>(stack: stack, entries: entries));You then wire the Router yourself if you want URLs — see
Deep links → Full control. Whoever creates a stack
disposes it (stack.dispose()); BackStackApp leaves ownership with you.
Where to next
- Core concepts — the model end to end.
- Deep links — the URL table, one entry per destination.
- Auth gating — redirects and async gates, loop-proof.