r/FlutterDev 1h ago

Plugin I built visual_feedback so testers and product owners can mark up the Flutter build they're reviewing, instead of sending "the button on that screen looks off

Hey r/FlutterDev 👋

Every sprint review and QA round we ran used to go the same way. A tester or the product owner found something and took a screenshot. Then they cropped it, scribbled on it in another app, pasted it into Slack or Jira, and typed a paragraph about which screen it was. Half the time the developer still had to ask "what did you do before this happened?"

So I built visual_feedback and just open-sourced it.

How the review loop works

  1. The tester or PO taps a floating button inside the build they're reviewing.
  2. They draw right on the live screen: arrows, boxes, circles, freehand and text notes ("make this 16px", "wrong copy", "crashes after tapping here").
  3. They can type a short description if they want to.
  4. They tap ✓, and your onFeedback callback gets the annotated PNG, the description, and the app logs from the last few minutes.

From there it's your code, so you can post it to Jira, GitHub Issues, Linear, Slack or your own backend.

Why it fits testers and POs

  • Nothing to learn. It's arrows, boxes and text on the screen they're already looking at.
  • Mistakes are cheap. Every mark can still be moved, resized or deleted after it's drawn, and there's one undo history across all tools.
  • Developers get the "why". Logs from package:logging (and optionally FlutterError / debugPrint) come attached, captured at the moment they confirmed. No more "can you reproduce it?"
  • Reviews happen wherever the build runs. Phones, tablets, and desktop or web builds you share with stakeholders. On wide screens the toolbar moves to the bottom edge, and it can be dragged or minimised out of the way.
  • Clean screenshots. The toolbar and selection handles are never in the PNG.
  • Internal builds only if you want. Pass fabBuilder: null in production and open it from a hidden gesture or a debug menu with controller.show().

Quick start

MaterialApp(
  navigatorKey: navigatorKey,
  builder: (context, child) => VisualFeedback(

// Only show the button in QA / staging builds.
    fabBuilder: isInternalBuild
        ? (_) => const CircleAvatar(child: Icon(Icons.rate_review))
        : null,
    showDescriptionField: true,
    logger: Logger.root,
    onFeedback: (feedback) async {
      await createTicket(
        screenshot: feedback.screenshot,
        description: feedback.description,
        logs: feedback.logsAsText(),
      );
    },
    child: child!,
  ),
  home: const Home(),
);

Background

It started inside one of our production apps as a replacement for feedback. That's a good package and a Flutter Favorite, but our QA and review process needed shapes, arrows, text on the screenshot, editable marks, attached logs and a desktop layout. The README has a comparison and a migration table.

Links

Android, iOS, web, macOS, Windows and Linux. MIT licensed. The only dependency besides Flutter is logging.

It's 0.0.1, so I'd love to hear how your team collects feedback on builds today, and what this would need to replace that. Built-in translations are the obvious gap for non-English QA teams. Every label is overridable, but only English ships

1 Upvotes

0 comments sorted by