Build or buy in-app feedback? An honest answer
A mailto link is enough for many apps. When users need to see and vote on each other's requests, here is what building it yourself actually involves.

If all you need is to hear from users, don't pay anyone for in-app feedback: a "Send feedback" button that opens a mailto: link or a Google Form is enough, and it takes ten minutes. A feedback tool only earns its place once users need to see each other's requests and vote on them - and at that point building it yourself is a small product, not a button.
This post exists because of a comment on the fedo homepage, quoted in full: "Feedback inside the app, not exactly a new idea. If I'm writing an app why would I pay you to handle my in app feedback? I don't get it." It is a fair question, and the honest answer starts with agreeing with it.
Key takeaways#
- A
mailto:link or a form is the right answer for many apps. If your feedback volume fits in an inbox, stop there. - The inbox model breaks when you need a shared, public list: without it users cannot see existing requests, so you get duplicates, and without votes you are guessing at priority.
- Building a shared board yourself means list, detail, editor, voting, comments and status screens on Android and iOS, an API and database with one-vote-per-user dedupe, an identity model for users who never signed in, and an admin dashboard - then hosting and maintaining all of it.
- With fedo that is one dependency and two calls, and the Starter plan is free on one app with unlimited users. For most apps the real question is "is this worth a dependency?", not "is this worth paying for?".
- Building your own is the right call if you ship on Flutter or React Native, need offline support, need the data inside your own systems, or feedback is core enough to your product that you want to own every pixel of it.
When is a mailto link or a form enough?#
More often than people selling feedback tools will tell you.
A button that opens mailto:feedback@yourapp.com with the app version pre-filled in the body gets you the user's words, a reply channel, and zero dependencies. A Google Form gets you structured fields and a spreadsheet. Both are free, both take minutes, and both are fine when:
- you get a handful of messages a week and can read every one,
- you mostly want bug reports, which are private by nature,
- you are the only person deciding what to build, and you are happy doing it from memory.
If that describes your app, you do not need fedo, and you do not need to build anything either. Add the button and ship.
Where does an inbox stop working?#
The inbox model has one structural limit: every piece of feedback is private to the person who sent it. Nobody else can see it.
That sounds like a feature until the volume goes up. Forty people ask for dark mode in forty separate emails, because none of them can see the other thirty-nine. You read forty messages, and you still do not know whether dark mode matters more than the export feature that three people asked for in unusually persuasive detail. The loudest request wins, not the most common one.
What fixes that is a shared list: users see what has already been asked, add a vote instead of a duplicate, and watch the status change when you act on it. Voting is what turns a pile of requests into a priority order - I made the longer version of that argument in in-app feedback vs a feedback portal. And the moment you want a shared, votable list, a mailto: link cannot be extended into one. You are building something new.
What does building in-app feedback yourself involve?#
Here is the parts list, written as if you were scoping it. None of it is exotic. There is just a lot of it.
Screens, on each platform you ship.
- A list of requests, with status filters and a way to see only your own.
- A detail view with the full description, the vote count and a comment thread with replies.
- An editor for creating and editing a request, with validation, plus edit and delete for the author.
- Voting from both the list and the detail view, with the count updating immediately.
- Loading, empty and error states for all of the above.
Then do it again, because an Android app and an iOS app are two codebases - Jetpack Compose on one side and SwiftUI on the other.
A backend.
- An API for requests, votes and comments.
- A database schema that ties them to users and to an app.
- Vote dedupe: one vote per user per request, enforced on the server, because a vote count that can be inflated is worse than no count.
- Auth for the API, so one user cannot edit another's request or vote on their behalf.
Identity. This is the part that gets underestimated. If a user has to create an account before they can report a bug, most of them will not report it, so a good feedback system has to work for users your app cannot name. That means minting an anonymous identity, keeping it stable across sessions, and - when the user signs in later - moving their requests, comments and votes onto the real account without leaving a duplicate identity behind that can double-count votes. I wrote up how fedo handles anonymous identity and migration, including the tradeoffs. It is a real design problem, not a column in a table.
An admin side. Users writing feedback is half of it. You need somewhere to read everything, sort by votes, see who asked and who voted, reply in the thread, and move a request between statuses - fedo uses five: In Review, Planned, In Progress, Shipped and Closed. That is a web dashboard with its own auth, which is a third frontend.
Hosting and upkeep. Somewhere to run the API and the database, backups, OS and dependency updates, and fixing the list screen when the next major version of Compose or SwiftUI changes something underneath it. None of this is hard. All of it is permanent.
None of these items is difficult on its own. That is exactly why it is easy to underestimate: each one looks like an afternoon, and the total is a side project you now maintain alongside the app you actually wanted to build.
What does using fedo involve instead?#
One dependency and two calls. On Android:
Fedo.initialize(applicationContext, apiKey = "your-api-key-here")
FedoFeedbackScreen(
onDismiss = { navController.popBackStack() }
)
On iOS it is Fedo.initialize(apiKey:) and the FedoFeedbackView SwiftUI view. That renders the list, details, threaded comments, voting and editor inside your app, and anonymous users are created for you when the screen first opens. The optional identity calls - setUserID, setUserEmail, setUserDisplayName, setUserProperty, logout - are there when your app has accounts. The full reference is in the getting started docs, and the platform walkthroughs are the Android guide and the iOS guide. The dashboard at app.getfedo.com is the admin side.
On the "why would I pay you" part: for one app, you would not. The Starter plan is free for one app with unlimited users; the tradeoff is a "Powered by fedo" badge. Paid plans are for more apps and for removing the badge. So for most people reading this, the real question is not whether in-app feedback is worth money. It is whether it is worth a dependency.
When should you build your own?#
A dependency is a real cost, and sometimes it is the wrong one. Build your own if:
- You ship on Flutter, React Native or the web. fedo has native SDKs for Android and iOS only. There is no Flutter or React Native SDK, so this is not a close call.
- You need offline support or guaranteed delivery. The SDK currently has no retry and no offline support - a failed call has to be made again. If your users are often offline and every submission must arrive, you need your own queue.
- The data has to live in your own systems. If feedback must sit in your database next to everything else, or flow straight into your issue tracker, owning the backend is simpler than syncing out of someone else's.
- Feedback is part of your product, not a side channel. If the board is something you want to design, brand and extend like any other feature, it deserves to be your code.
- You already have most of the pieces. An existing backend, an admin panel and an account system cover a large part of the list above. What is left may be small enough to just write.
- You would rather not add a young dependency. fedo is in early access. That is a legitimate reason to wait or to build, and I would rather you decide that with eyes open.
If none of those apply, and you want users to see and vote on each other's requests, the build list above is what you would be signing up for. If you only want to hear from users, go back to the first section and add the mailto: link. Both are better than an app store review being the only channel you have.


