vantage 0.1.0
vantage: ^0.1.0 copied to clipboard
An in-app QA & developer-tools HUD for Flutter — device simulation, widget inspection, and an extensible plugin architecture for building QA tooling.
vantage #
The QA & developer-tools HUD that lives inside your Flutter app.
Simulate any device, inspect any widget, watch every request — and hand a developer a complete bug report in one tap. One floating bubble, one plugin contract, no native setup.
Pre-release. The architecture is settled and 1,648 tests pass across the workspace, but the API may still shift before
1.0. Source, issues and the full package list: https://github.com/nateshmbhat/vantage
Install #
# Regular dependencies, not dev_dependencies: `Vantage` is imported from
# lib/main.dart. It costs nothing in release — `enabled` defaults to
# `!kReleaseMode`, so the HUD is a pass-through and tree-shakes away.
dependencies:
vantage: ^0.1.0
vantage_device_preview: ^0.1.0 # add only the plugins you want
vantage_inspector: ^0.1.0
vantage_flight_recorder: ^0.1.0
Two lines to wire it #
void main() => runApp(
Vantage(
// Zero cost in release: `enabled` defaults to `!kReleaseMode`.
plugins: [
VantageDevicePreviewPlugin.withFrames(),
VantageInspectorPlugin(),
VantageFlightRecorderPlugin(),
],
builder: (context) => const MyApp(),
),
);
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) => MaterialApp(
builder: Vantage.appBuilder, // ← the only change inside your app
home: const HomeScreen(),
);
}
Vantage wraps your app; Vantage.appBuilder re-applies the simulated
MediaQuery / locale / theme inside it. If you forget the second line, Vantage
tells you with an on-screen banner rather than failing silently.
What this package is #
vantage is the host and the contract — the bubble, the HUD shell, the activation
gesture, the plugin registry, and the seams every plugin builds on. The features live
in separate packages so you only take what you use:
vantage_device_preview · vantage_inspector · vantage_network_core (+ vantage_dio,
vantage_http) · vantage_flight_recorder · vantage_routing · vantage_performance ·
vantage_flags · vantage_a11y · vantage_design · vantage_prefs ·
vantage_state_core (+ vantage_riverpod)
This package depends on the Flutter SDK and nothing else — you never inherit
dio or riverpod for a feature you didn't ask for.
Write your own plugin #
The same contract the built-in tools use:
class MyPlugin extends VantagePlugin with PanelPlugin, QuickActionsPlugin {
@override String get id => 'my_plugin';
@override String get title => 'My Tool';
@override IconData get icon => Icons.build;
@override
Widget buildPanel(BuildContext context, VantageScope scope) => const MyPanel();
@override
List<VantageQuickAction> get quickActions => [
VantageQuickAction(
id: 'seed_cart',
label: 'Seed 100 cart items',
onPressed: () => cart.seed(100), // ← your code, one tap, from any screen
),
];
}
Mix in only what you need:
| Mixin | Gives you |
|---|---|
PanelPlugin |
A tab in the HUD |
OverlayPlugin |
A layer painted over the app (pass-through or capturing) |
AppWrapperPlugin |
Wrap the app subtree |
QuickActionsPlugin |
One-tap CTAs that call your code |
EventSource |
Emit breadcrumbs onto the shared timeline |
ExportContributor |
Add artifacts to a bug bundle |
Adding a capability later never breaks existing plugins, and VantageScope.of(context)
is the only way a plugin reaches the host — no singletons.
Verify it with the shared contract kit #
import 'package:vantage/testing.dart';
void main() => runVantagePluginContractTests('MyPlugin', MyPlugin.new);
It checks the things that are easy to get subtly wrong — stable ids, unique quick actions, panels that build without being attached, broadcast event streams, and export artifacts that are safe to put in a bundle.
Simulation, applied once #
Plugins don't insert their own MediaQuery. They contribute a
VantageSimulationData and the host applies it exactly once, so two plugins can
never fight over the app's constraints:
VantageScope.of(context).updateSimulation(
const VantageSimulationData(
size: Size(320, 568),
textDirection: TextDirection.rtl,
viewInsets: EdgeInsets.only(bottom: 336), // simulate the keyboard
),
);
Every field is applied — size, locale, brightness, text scale, direction, insets,
padding, pixel ratio, platform and display features. padding is derived from
viewPadding - viewInsets, so a simulated keyboard eats the home indicator exactly
as a real one does.
Safety #
- Off in release by default.
enabledis!kReleaseMode; when off, Vantage is a pass-through — no scope, no overlay, no capture. - Redaction is mandatory, not optional. Text artifacts are always redacted on the way into an export bundle, and filenames are sanitised so a plugin cannot escape its own folder. We document what redaction can't catch rather than claiming a bundle is secret-free.
License #
MIT © Natesh Bhat.