vantage 0.2.0 copy "vantage: ^0.2.0" to clipboard
vantage: ^0.2.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

Vantage

The QA & developer-tools HUD that lives inside your Flutter app.
Simulate any device · inspect any widget · watch every request ·
and turn “it broke on my phone” into a zip a developer can act on.

Flutter Platforms Tests License


Two lines of code. One floating bubble. Every tool your QA loop was missing.

No native setup. No build flavors. No wrapper around every screen. And zero cost in releaseenabled defaults to !kReleaseMode, so the whole thing tree-shakes away.

✨ Features #

  • 🫧 One bubble, every tool. Tap it from any screen. Nothing else changes about your app.
  • 📱 Real device simulation, not a picture of one. ~40 devices with true safe-area insets and pixel ratios — your app genuinely resizes, so a layout that collides with the home indicator fails in preview the way it fails on the phone.
  • 🔍 Tap any widget. Type, size, constraints, padding, ancestor chain. Measure mode: tap two elements, get the gap, with off-grid warnings against your 8pt system.
  • 🌐 Every request, with the truth about it. Status, timing, size, pretty JSON, copy as cURL — and 4xx is not lumped in with 5xx, because a QA tool that cries wolf gets ignored.
  • 🔐 Redaction that actually holds. accessToken, access_token and Access-Token are one rule, plus JWTs, bearer tokens, card numbers and SSNs matched on shape alone. A shared corpus of secret-bearing payloads runs against it on every single build.
  • 🎬 The one-tap bug report. Breadcrumbs, errors, screenshot, network log, route stack and a real device block — zipped and handed to the share sheet. This is the feature that pays for the package.
  • 🖍️ Redact before you send. An opaque mask, not a blur — because blurred PINs and card digits are recoverable, and we'd rather say so than pretend otherwise.
  • Accessibility you can see. Semantics overlay, 48dp/44pt tap-target auditor, WCAG contrast maths, and pseudo-localization — strings that don't turn into Ẽẋpãñdẽd are hardcoded, by construction.
  • 🧭 Deep-link launcher built in. Fire any route from inside the app. No more adb shell am start.
  • Frame-time HUD + jank journal, keyed to the route you were on when it stuttered.
  • 🚩 Flip feature flags without a rebuild, and edit SharedPreferences live.
  • 🧩 A plugin host, not a monolith. Every tool above is a plugin on a small, stable contract — and yours can be too.
  • 🪶 Core depends on the Flutter SDK. Only. dio, riverpod, shared_preferences are separate packages. You never inherit a dependency for a feature you don't use.

🚀 Install #

# Regular dependencies, not dev_dependencies: `Vantage` is imported from
# lib/main.dart. It costs nothing in release — see above.
dependencies:
  vantage: ^0.1.1
  vantage_device_preview: ^0.1.0   # add only the tools you want
  vantage_inspector: ^0.1.0
  vantage_flight_recorder: ^0.1.0

🔌 Two lines to wire it #

void main() => runApp(
  Vantage(
    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. Forget the second line and Vantage tells you with an on-screen banner rather than failing silently.

🧰 The toolbox #

vantage is the host and the contract. The tools ship separately, so you take only what you use:

Package What it adds
📱 vantage_device_preview Device frames, real safe areas, locale, text scale, RTL
🔍 vantage_inspector Tap-to-inspect + measure mode
🌐 vantage_network_core Request inspector, redaction, cURL export
🔌 vantage_dio · vantage_http Transport adapters
🎬 vantage_flight_recorder Breadcrumbs, screenshot, annotate, one-tap bundle
🧭 vantage_routing Route stack + deep-link launcher
vantage_performance Frame-time HUD + jank journal
🚩 vantage_flags Feature-flag overrides
vantage_a11y Semantics, tap targets, contrast, pseudo-localization
🎨 vantage_design Grid, rulers, guides, mockup overlay
💾 vantage_prefs Live SharedPreferences editor
🔄 vantage_state_core · vantage_riverpod State history + diffs

🛠️ 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 — PanelPlugin, OverlayPlugin, AppWrapperPlugin, QuickActionsPlugin, EventSource, ExportContributor. Adding a capability later never breaks existing plugins, and VantageScope.of(context) is the only way a plugin reaches the host. No singletons.

Then prove it works 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 unattached, broadcast event streams, and export artifacts that are safe to put in a bundle.

🎛️ Simulation, applied once #

Plugins never insert their own MediaQuery. They contribute a VantageSimulationData and the host applies it exactly once, so two plugins can never fight over your app's constraints:

VantageScope.of(context).updateSimulation(
  const VantageSimulationData(
    size: Size(320, 568),
    textDirection: TextDirection.rtl,
    viewInsets: EdgeInsets.only(bottom: 336),  // simulate the keyboard
  ),
);

padding is derived from viewPadding - viewInsets, so a simulated keyboard eats the home indicator exactly as a real one does.

🛡️ What we promise, and what we don't #

  • Off in release by default. enabled is !kReleaseMode; when off, Vantage is a pass-through — no scope, no overlay, no capture.
  • Redaction is a requirement, not a setting. Text artifacts are always redacted on the way into a bundle.
  • We document what redaction can't catch rather than claiming a bundle is secret-free. It is pattern matching, not classification — a safety net over data your plugin already redacted, never the only line of defence.
  • We don't over-claim. Where something is cooperative (dark mode) or unfinished (durable flag persistence), the docs say so. Where a tool can't work — a screenshot over a platform view, a bundle on the web — it tells you why instead of failing quietly.

📄 License #

MIT © Natesh Bhat · github.com/nateshmbhat/vantage

0
likes
160
points
317
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

An in-app QA & developer-tools HUD for Flutter — device simulation, widget inspection, and an extensible plugin architecture for building QA tooling.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter, flutter_test

More

Packages that depend on vantage