Skip to content

Conversation

@JPFrancoia
Copy link

@JPFrancoia JPFrancoia commented Dec 13, 2025

Have you followed these guidelines?

Rationale

At the moment, there is no way in Miniflux (or any other RSS feed reader that I looked at) to "upvote" or "downvote" an entry. I'm using "upvote" and "downvote" in the generic sense of the term, it's the equivalent of like/unlike or thumb up/down. In my opinion, it's a critical building block to implement more advanced features that revolve around optimising the content that we see. Here are a few use cases:

  • Build statistics per feed, to see how useful each feed is. For example if 30% of the articles of a feed are downvoted, maybe it's time to unsubscribe
  • Crowd source the detection of good articles: if your instance of miniflux has several readers and if they all vote for an article, there is a good chance you'll want to read it too
  • Most importantly: recommendation engines. Being able to label articles (upvote for relevant, downvote for irrelevant) is the basis of most recommendation engines. Over time, you can build a labelled dataset of your interests, among all the feeds you're reading. You can then train a recommendation engine on this labelled dataset. I'm voluntarily not mentioning any specific tech here, it could be a good old ML technique or a more modern LLM classification, it doesn't matter, you'll almost always want a labelled dataset.

Why upvote/downvote, and not...

I have considered using the "starred" and "read/unread" statuses, labels, I have hijacked other buttons in other RSS readers, etc. It always feels clunky: too many clicks to classify an article, loss of another feature, etc. I believe a system like upvote/downvote is the clean way to go

Why doesn't it already exist?

I'm not entirely sure if people don't have a need for a relevant/irrelevant classification system, or if there is a lack of the things that come after having implemented such system. I didn't find a lot of open source and self-hosted recommendation engines or pipelines.

I am partial to this; I subscribed to many really good feeds, and I just don't have time to read everything, even if I want to. I need a way to prioritise. I built a recommendation engine from the data I collected with TTRSS, but I'm trying to move away from it (culture, and it was recently abandoned).

I have implemented such a recommendation engine (blog article here and code here. I have been running it "in production" for a few months, and it has been super helpful. Again, I'm not recommending any particular solution for the recommendation part, I just think the community needs basic build blocks to even go there.

How should it work?

It's probably not Miniflux's philosophy to implement recommendation engines, and it probably should be left to the community. The implementation of the engines could live in plugins or in custom third-party solutions. But these solutions all need the labelling of the articles, and I don't think the labelling can live in a plugin (hence this PR).

Please note that I also implemented a setting option to enable/disable the voting buttons, and they're disabled by default.

A picture is worth a thousand words

screen-2025-12-13-19-14-22

@JPFrancoia JPFrancoia marked this pull request as draft December 13, 2025 20:35
@JPFrancoia JPFrancoia marked this pull request as ready for review December 13, 2025 20:36
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request adds a voting feature (upvote/downvote) to Miniflux, enabling users to classify entries as relevant or irrelevant. The feature is designed as a building block for future recommendation engines and analytics. The voting system allows values of -1 (downvote), 0 (no vote), and 1 (upvote), with buttons that can be toggled on/off.

Key changes:

  • Added database schema for storing votes on entries and a user preference to show/hide voting buttons
  • Implemented UI components with JavaScript handlers and CSS styling for voting buttons
  • Added translations for voting button labels across all supported languages

Reviewed changes

Copilot reviewed 35 out of 36 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
internal/database/migrations.go Adds database migration to create vote column on entries table and show_voting_buttons column on users table with appropriate constraints
internal/model/entry.go Adds Vote field to Entry model to store vote values
internal/model/user.go Adds ShowVotingButtons field to User and UserModificationRequest models to control visibility of voting buttons
internal/storage/entry.go Implements UpdateEntryVote method to persist vote changes in the database
internal/storage/entry_query_builder.go Updates query builder to include vote field when fetching entries
internal/storage/user.go Updates user CRUD operations to handle the new show_voting_buttons field
internal/ui/entry_vote.go Implements HTTP handler for processing vote update requests with validation
internal/ui/ui.go Registers the updateEntryVote route in the UI router
internal/ui/static/js/app.js Adds handleVoteAction JavaScript function to handle client-side vote interactions and UI updates
internal/ui/static/css/common.css Adds CSS styling for vote buttons including hover states, active states, and color coding
internal/template/templates/views/entry.html Adds vote buttons to entry detail page with appropriate data attributes
internal/template/templates/common/item_meta.html Adds vote buttons to entry list items in the feed view
internal/ui/form/settings.go Adds ShowVotingButtons field to settings form for user preferences
internal/ui/settings_show.go Includes ShowVotingButtons in settings page rendering
internal/template/templates/views/settings.html Adds checkbox to toggle voting buttons visibility in user settings
internal/locale/translations/*.json Adds translations for upvote/downvote labels and settings checkbox across all supported languages
.gitignore Adds *.envrc pattern (unrelated to voting feature)

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 40 out of 41 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@jvoisin
Copy link
Collaborator

jvoisin commented Jan 1, 2026

Sounds like feature creep to me: "Miniflux is a minimalist and opinionated feed reader.", and having a voting system to implement a recommendation engine is anything but :/

@JPFrancoia
Copy link
Author

Yeah I suspected someone would say that. I can see why, but at the same time the ability to convey "this article was good, this one was bad" seems fundamental to me. It's not just about the recommendation engine, there are other use cases like building stats to curate feeds for example. Of course the recommendation engine is the end game, I'm not gonna lie. I haven't seen anywhere an open source system to rank news according to my own interests. It's important for me to own this because I don't want any company to control what I read every day. But it starts by training the engine on what matters to me, hence this PR.

I considered building the voting feature outside of miniflux, but I couldn't see a way to do that easily.

Anyway, it's up to you/the community to decide if you want this feature. I would totally understand if you don't want it, in this case I'll maintain my own fork, it's just a bit more work for me.

I already built the recommendation engine and integrated it into miniflux in my fork, it looks like this:

example_score

Feel free to close this PR if you made your decision :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants