Releases: miniflux/v2
Miniflux 2.2.17
Security
- Do not expose the Miniflux version on unauthenticated endpoints (deprecated since version 2.0.49).
- Improve HTML sanitizer by switching from the tokenizer to the
golang.org/x/net/htmlparser to better match browser behavior and reduce the risk of injection issues. - Enforce blocked resource checks on
srcsetURLs. - Improve blocked resource handling (including updates to blocked URL substrings).
- Add validation for
TRUSTED_REVERSE_PROXY_NETWORKSconfiguration to prevent silent misconfiguration. - Prevent possible deadlock when cleaning removed entries.
- Ensure HTTP response bodies are always closed, even on client errors.
Improvements
-
Rewrite
srcsetparser to follow HTML specifications (WebKit-style parsing) and handle edge cases more correctly. -
Improve sanitizer performance (various optimizations, including reduced allocations and better attribute handling).
-
Handle deeply nested HTML more robustly in the sanitizer.
-
Add scraper and rewrite rules for:
bleepingcomputer.comvnexpress.net
-
Improve JSON Feed support:
- Support malformed feeds with
authorobjects in theauthorsarray. - Avoid panic when parsing
nullfeeds. - Improve title fallback logic.
- Include
external_urlin JSON entry hash fallback.
- Support malformed feeds with
-
Ignore WordPress
wp-jsonAPI endpoint during JSON feed discovery. -
Add unread status filter to search results.
-
Improve timezone handling internals and performance.
-
Improve API payload structures and Godoc comments.
-
Improve JavaScript code readability and keyboard shortcut handling.
-
Restore cmd/ctrl/shift-click behavior on main navigation.
-
Fix Safari PWA behavior for the
vshortcut to open links in the main browser.
Bug Fixes
- Do not keep old enclosures when an updated entry has none.
- Handle
sql.ErrNoRowsproperly inIconByFeedID. - Change
FindRemoteIPto fall back to127.0.0.1.
Configuration Changes
- Removed
FILTER_ENTRY_MAX_AGE_DAYS.
This option can be replaced with a filter rule such asmax-age:<duration>.
Global environment variables should be reserved for process-level configuration.
Dependencies
-
Update
github.com/lib/pqto 1.11.2. -
Update:
golang.org/x/netto 0.50.0golang.org/x/cryptoto 0.48.0golang.org/x/imageto 0.36.0golang.org/x/oauth2to 0.35.0golang.org/x/termto 0.40.0
-
Update Debian packager Docker image to Trixie.
As always, thank you to all contributors who helped improve Miniflux in this release.
Miniflux 2.2.16
Security
- Disallow the media proxy from fetching resources on private networks to mitigate potential SSRF issues. This behavior is configurable at the instance level.
- Disallow fetching feed icons from private networks to reduce the SSRF attack surface. This is also configurable at the instance level.
- Add the
TRUSTED_REVERSE_PROXY_NETWORKSconfiguration option to prevent spoofing of HTTP headers such asX-Forwarded-For,X-Forwarded-Proto, andX-Real-Ip. This option must be configured whenAUTH_PROXY_HEADERis enabled. - Stop logging generated Google Reader API tokens, even when debug mode is enabled.
- Remove the CORS handler from the Google Reader API, as it is not intended to be used by web clients, reducing the overall attack surface.
Performance and Storage
- Avoid indexing the content of removed entries, significantly reducing database index size after cleanup.
- Minor storage and database refactoring to simplify code paths and reduce unnecessary formatting overhead.
API and Integrations
- Add a new API endpoint to import entries into an existing feed.
- Execute the content sanitizer when updating or importing entries through the API to ensure consistent sanitization.
- Improve Google Reader API compatibility by removing unnecessary output parameter checks and aligning behavior with other open-source RSS readers.
- Add an auto-push option to the Readeck integration.
User Interface
- Add smooth page transitions for a more polished navigation experience.
- Add a route to view individual starred entries directly from a category’s starred list.
- Add a link to the GitHub contributors page in templates.
- Update all translations.
Documentation and Tooling
- Improve consistency and fix typos in the
miniflux(1)manual page. - Remove the obsolete
versionkey from Docker Compose examples. - Update the Go devcontainer image to
go:1-trixie. - Update the Distroless container base image to Debian 13.
- Update GitHub Actions dependencies.
As always, thank you to all contributors who helped improve Miniflux in this release.
Miniflux 2.2.15
✨ New Features
- New configuration option to disable the Miniflux API
- Added option to save entries to a specific Linkwarden collection
- YouTube subscription improvements:
- Provide multiple feeds for YouTube content: Channel, videos only, short videos, live streams
- Better canonical URL detection (now has its own dedicated step)
- Improved YouTube channel parsing, including default playlists
- Allow feed entries with
<i>and<small>tags - URL Cleaner: Remove additional trackers from URLs
🐛 Bug Fixes
- YouTube embeds: Avoid Error 153 (
video player configuration error) in various scenarios - API:
fetchContentendpoint now properly rewrites media URLs when using the media proxy - Security: Only relative paths are now allowed for the
redirectURLparameter - CI fixes:
- Improved CodeQL workflow (language matrix + dynamic analysis)
- Fixed missing GitHub Actions permissions
- Fixed RPM package versioning for scheduled and pull_request triggers
🧹 Refactoring & Maintenance
- JavaScript optimizations: use
replaceinstead ofremove/add, minor regex cleanup - Performance improvement: removed string concatenation in loops
- Updated Polish translation
- Updated Postgres volume path in Docker Compose examples
- Added new CI workflow to mirror the Git repo to Codeberg
📦 Dependency Updates
This release includes updates to several dependencies:
golang.org/x/*modules (net,oauth2,image,crypto)github.com/tdewolff/minify/v2github.com/coreos/go-oidc/v3github.com/go-webauthn/webauthngithub.com/PuerkitoBio/goquery- Docker base image updates (Alpine 3.23)
- GitHub Actions:
actions/checkoutv6actions/upload-artifactv5golangci/golangci-lint-actionv9
For more details, look at the Git commit history.
Miniflux 2.2.14
✨ New Features
- Go Client: Allow passing a custom
http.Clientand add context support to API methods. - UI: Redirect users back to the original page after logging in.
- Template: Improved Content Security Policy: extracted CSP generation into a function, added systematic nonces, and changed
default-srcto'none'for stronger security. - Integrations:
- Added tags option for the Karakeep integration.
- Added new Archive.org integration.
- Rewrite Rules:
- Added
remove_img_blur_paramsrule. - Added
add_image_titlerule for explainxkcd.com.
- Added
🧰 Improvements & Refactoring
- Replaced custom modal with native
<dialog>element for simpler, more accessible UI. - Simplified date parsing in the reader and XML encoding logic.
- Optimized sanitizer functions (
hasRequiredAttributes,hasValidURIScheme,isBlockedResource). - Replaced
fmt.Errorfwitherrors.Newwhere applicable. - Removed dependency on
hstorein the database layer and relaxed implicitNOT NULLfor serial types. - Simplified Fever API slice sizing and various internal cleanups.
- Preallocated slices and optimized string/number conversions for better performance.
🧪 Tests
- Added test cases for XML encoding behavior.
🐛 Bug Fixes
- Fixed CSS layout overflow when external links are too long.
- Fixed JSON Feed parser to fallback to
external_urlwhenurlis missing. - Updated scraper rule for Dark Reading.
📚 Documentation
- Clarified the
POLLING_FREQUENCYenvironment variable in the documentation.
🏗️ Build & CI
-
Updated dependencies:
github.com/tdewolff/minify/v2→ 2.24.4golang.org/x/net→ 0.46.0golang.org/x/image→ 0.32.0golang.org/x/oauth2→ 0.32.0github.com/coreos/go-oidc/v3→ 3.16.0github/codeql-action→ 4
-
Updated
make lintand enabled additional Go linters (perfsprint,goheader).
📝 Additional Notes
If you are seeing this Postgres error: Error: pq: must be owner of extension hstore, you can fix it by running the following SQL command as a superuser for the Miniflux database:
DROP EXTENSION hstore;This error means you initially created the hstore extension as a different database user than the one you are currently using for Miniflux.
For more details, look at the Git commit history.
Miniflux 2.2.13
✨ New Features
- UI: Added a "Back to top" link for easier navigation.
- Integrations:
- Added support for Wallabag tags.
- Added support for LinkTaco service to save articles.
🐛 Bug Fixes
- API: Fixed issue where
removedentries could still be returned. It was generating an error when fetching entries. - Icons: Improved handling of relative icon URLs within subfolders.
- Timezone: Ensured only current IANA time zones are used. This avoids issues with Debian Trixie where deprecated time zones have been removed.
🛠 Refactoring & Improvements
- Complete rewrite of the config parser with validation and consistency improvements.
- Combined YouTube subscription parsing functions into a single function.
- Simplified and optimized JavaScript files (
modal_handler.js, removedisTouchSupported()). - Refactored internal code to consistently use
time.Durationfor time values across CLI, server, fetcher, metrics, and HTTP components. - Replaced "Bookmarks" with "Starred" across UI and codebase for consistency.
- Template and UI cleanups: explicit template dependencies, moved inline SVGs to
sprite.svg, improvedlayout.htmlconsistency. - Strengthened the JavaScript Trusted Types policy to enhance security.
- Updated translations for German, Polish, and French.
⚡ Performance
- XML Parsing: Optimized
filterValidXMLChars(~4% faster). - Sanitizer: Improved sanitization performance by ~10% using
slices.Contains. - Converted slices to arrays in some internal structures for efficiency.
📦 Dependency Updates
- go-webauthn/webauthn: 0.13.4 → 0.14.0
- golang.org/x/net: 0.43.0 → 0.44.0
- golang.org/x/image: 0.30.0 → 0.31.0
- golang.org/x/crypto: 0.41.0 → 0.42.0
- golang.org/x/term: 0.34.0 → 0.35.0
- golang.org/x/oauth2: 0.30.0 → 0.31.0
- tdewolff/minify/v2: 2.23.11 → 2.24.3
- prometheus/client_golang: 1.23.0 → 1.23.2
- GitHub Actions:
setup-goandsetup-pythonbumped from v5 → v6
Miniflux 2.2.12
✨ New Features
- Keep only metadata of removed entries to reduce database size.
- Removed entry status is now immutable and cannot be changed back to
unreadorreadstatus. - SVG favicons are now minified before storing them in the database.
- Added support for resizing WebP images.
- Main menu now includes icons.
- Added Progressive Web App (PWA) shortcuts for quick access to common actions.
- Added direct link to the Apache 2.0 license on the About page.
- Feed-level webhook URLs now take priority when saving entries.
- New option:
POLLING_LIMIT_PER_HOSTto limit concurrent requests per host.
Limits the number of concurrent requests to the same hostname when polling feeds.
This helps prevent overwhelming a single server during batch processing by the worker pool. - Added a rewrite rule to remove useless heading images on Phoronix articles.
- Use Golang's built-in VCS feature to get commit and build date when not specified by
LDFLAGS. - Disable OAuth2 and WebAuthn routes when the feature is not enabled.
- Added request URI logging in authentication handlers.
🛠 Fixes
- Limited
tsvectorindexing to the first 500K characters to avoid PostgreSQL limits. - Use
rel=apple-touch-iconinstead ofrel=apple-touch-icon-precomposed.png. - Fixed broken WebAuthn error alert message on the settings page.
- Reverted
SameSiteStrictcookie mode because it forces people to authenticate each time when using the PWA on Android. - Prevent stale data by forcing reload when navigating back from articles (fix for Chrome's bfcache).
- Fixed URL detection capturing newlines in media descriptions.
⚡ Performance Improvements
- Optimized SQL queries (
FetchJobs,markFeedAsRead) by removing unnecessary joins and heavy-weight operations. - Improved memory usage by minimizing SVGs, static images, and templates.
- WebAuthn script (
webauthn.js) is no longer loaded when the feature is disabled. - Replaced regex-based YouTube and Invidious video ID extraction with URL parsing.
- Introspect the translation files at load time.
- Parse and merge filters only once per refresh.
🔧 Refactoring & Internal Changes
- Extensive refactoring across UI, templates, storage, and fetcher to simplify code and reduce memory allocations.
- Replaced
interface{}withany(Go 1.18+ idiomatic usage). - Reorganized JavaScript code: simplified functions, reduced duplication, and modernized handlers.
app.jsbundle and service worker files are now loaded as a JavaScript module.- Use request builder in media proxy handler.
📚 Documentation
- Fixed typos and updated default values in the man page.
- Removed
ChangeLogfile (release notes are visible on GitHub and the official website - use the commit history for more details).
🛠 Dependencies
-
Updated GitHub Actions workflows to use Go version 1.25.
-
Updated dependencies:
golang.org/x/net→ 0.43.0golang.org/x/image→ 0.30.0golang.org/x/term→ 0.34.0github.com/tdewolff/minify/v2→ 2.23.11github.com/coreos/go-oidc/v3→ 3.15.0github.com/prometheus/client_golang→ 1.23.0- GitHub Actions:
actions/checkoutbumped to v5
✅ Tests
- Added API integration tests for fetching categories with counters.
- Added tests for icon URL discovery, SVG minification error handling, and version format enforcement.
- Added unit tests for
RequestBuilder. - Avoided building a temporary binary for integration tests.
For more details, look at the commit history.
Miniflux 2.2.11
✨ New Features
- TLS support for Unix sockets: Miniflux can now serve TLS over Unix domain sockets using
CERT_FILEandKEY_FILE(#fcf86e3). - RSS fallback: If a feed entry has no URL, Miniflux now uses the enclosure URL as a fallback (#d9de9d1).
- Bearer token for Linkwarden: The Linkwarden integration now uses Bearer token authorization instead of cookies (#1d11623).
- Cookie policy improvement:
SameSiteStrictModeis enforced for cookies when OAuth2/OIDC is not used (#135ce1d). - Readability engine: Avoid removing elements with the
contentclass during readability parsing (#66b269e).
🛠️ Improvements
-
Massive readability engine refactoring and performance optimizations:
- Improved performance of
getClassWeight,getLinkDensity, andtransformMisusedDivsIntoParagraphs. - Simplified and optimized internal logic of
removeUnlikelyCandidates,getSelectionLength, andgetArticle. - Reduced memory allocation in sanitizer and readability components.
- Improved performance of
-
Storage optimization: Strings are now truncated on the Go side to respect
tsvectorlimits, reducing DB load and ensuring valid UTF-8 (#703f113). -
Simplified and clarified internal code structure:
- Major cleanup and size optimization of internal structs (
Feed,FeedCreationRequest, etc.). - Reduced memory use and improved CPU cache locality.
- Numerous refactors across
config,template,locale,subscription, andfetchermodules.
- Major cleanup and size optimization of internal structs (
🐛 Bug Fixes
- Fixed an issue with feeds having excessive leading whitespace causing parser buffer issues (#54abd0a).
- Properly preserve UTF-8 when truncating strings for full-text search (#703f113).
- Fixed logic error in enclosure type detection (#50d5cb9).
- Fixed incorrect filter rule parsing of Windows-style newlines (#dc81725).
- Fixed a panic in
startAutoCertTLSServerfunction when using Let's Encrypt automatic certificates (#f7a6b02) - Improved UI spacing consistency around header/footer (#32fbb4e).
⚠️ Breaking Changes
- Windows binary no longer distributed: Windows is no longer a supported platform for binary distribution. Users must build from source if needed (#b470b18).
🧪 Tests & CI
- Test coverage significantly increased for modules like
readability,sanitizer,processor,locale, andstorage. - Commit linter updated to support new Git revert message format.
🐘 Docker & Environment
- Base Docker image updated to Alpine 3.22.
- PostgreSQL Docker example updated to use the latest version.
🌐 Localization
- Updated Chinese and German translations.
🔒 Dependency Updates
- Bumped
github.com/go-webauthn/webauthnto0.13.4 - Bumped
github.com/tdewolff/minify/v2to2.23.10 - Bumped
golang.org/x/*modules:image,net,term,crypto - Bumped
github.com/andybalholm/brotlito1.2.0
Miniflux 2.2.10
- test(sanitizer): add unit test for 0x0 pixel tracker
- test(sanitizer): add test case to cover Vimeo iframe rewrite without query string
- refactor(youtube): Remove a regex and make use of
fetchWatchTime - refactor(youtube): initialize two maps to the proper length
- refactor(tests): use
b.Loop()instead of for rangeb.N - refactor(server): avoid double call to
Sprintf - refactor(sanitizer): use global variables to avoid recreating slices on every call
- refactor(sanitizer): use a map for iframe allow-list
- refactor(sanitizer): remove two useless
www.prefixes - refactor(sanitizer): make
isValidAttribute()check O(1) - refactor(rewrite): rename
Rewriterfunction toApplyContentRewriteRules - refactor(processor): simplify Bilibili processing
- refactor(processor): remove a useless type declaration
- refactor(processor): remove a duplicated function call
- refactor(processor): refactor common code into a
fetchWatchTimefunction - refactor(processor): move filters to a
filterpackage - refactor(processor): move
FilterEntryMaxAgeDaysfilter to filter package - refactor(processor): move
RewriteEntryURLfunction torewritepackage - refactor(processor): minor simplification of a loop
- refactor(internal): add an
urllib.DomainWithoutWWWfunction - refactor(http): rename package from
httpdtoserverfor consistency - refactor(http): don't hardcode TLS configuration
- refactor(filter): avoid code duplication between
IsBlockedEntryandIsAllowedEntryfunctions - refactor(database): drop 3 columns in a single transaction
- refactor(crypto): use
rand.Text()instead of a custom implementation - refactor(config): remove deprecated config options
- refactor(js): no need to check if always present elements are always present
- perf(xml): optimized
NewXMLDecoder - perf(xml): optimize XML filtering
- perf(validator): slightly optimize a regex
- perf(timezone): cache
getLocation's results - perf(storage): pre-allocate a slice in
RefreshFeedEntries - perf(storage): optimize away two
Sprintfcalls - perf(sanitizer): use a switch-case instead of a map
- perf(sanitizer): minor simplifications of the sanitizer
- perf(sanitizer): extract a call to
url.Parseand make intensive use of it - perf(rss): optimize a bit
BuildFeed - perf(rss): early return when looking for an item's author
- perf(rewrite): make
getPredefinedRewriteRulesO(1) - perf(reader): use a non-cryptographic hash when possible
- perf(reader): optimize
RemoveTrackingParameters - perf(readability): minor regex improvement
- perf(media): minor regex simplification
- perf(fetcher): pre-allocate the
cipherSuites - perf(database): use
TRUNCATEinstead ofDELETE FROMin migrations - perf(database): marginally speeds migrations up
- perf(api): use
math/rand/v2instead ofmath/randfor better performance - fix(readability): do not remove elements within code blocks
- fix(karakeep): correct method name and improve error handling in
SaveURL - fix(filter): skip invalid rules instead of exiting the loop
- feat(ui): display external link in single entry view because the URL was not visible on mobile (no mouse over)
- feat(ui): avoid showing an excessive number of tags
- feat(ui): add user setting to control
target="_blank"on links - feat(sanitizer): validate MathML XML namespace
- feat(sanitizer): consider images of size 0x0 as pixel trackers
- feat(sanitizer): add validation for empty
widthandheightattributes in img tags - feat(sanitizer): add support for
fetchpriorityanddecodingattributes in img tags - feat(rewrite): add support for YouTube Shorts video URL pattern
- feat(rewrite): add
parkablogs.comto the referer override list - feat(oidc): use
preferred_usernamefirst instead ofemailclaim - feat(locale): update Polish translations
- feat(locale): update locales using machine translation
- feat(locale): update Indonesian translations
- feat(locale): update German translations
- feat(locale): update Chinese translations
- feat(integration)!: remove Pocket integration (Pocket will no longer be available after July 8, 2025)
- feat(filter): add
EntryDate=max-age:durationfilter - feat(css): add margin-bottom to input for consistent spacing
- feat(config)!: remove
SERVER_TIMING_HEADERconfig option - feat: allow multiple listen addresses
- feat: adding support for saving entries to Karakeep
- feat: add entry filters at the feed level
- docs(readme): document a couple of nifty features
- docs: add
CONTRIBUTING.mdfile - chore(template): remove
X-UA-Compatiblemeta tag specific to Internet Explorer - build(go): bump to go 1.24
- build(deps): bump
library/alpinein/packaging/docker/alpine - build(deps): bump
golang.org/x/netfrom0.40.0to0.41.0 - build(deps): bump
golang.org/x/imagefrom0.27.0to0.28.0 - build(deps): bump
golang.org/x/cryptofrom0.38.0to0.39.0
Miniflux 2.2.9
- refactor(googlereader): remove redundant log message
- refactor(googlereader): move constants to separate files
- fix(webauthn): correct argument in debug log
- fix(sanitizer): MathML tags are not fully supported by
golang.org/x/net/html - fix(migrations): prevent failure at version 45 with long entry URLs
- fix(locale): localize Git commit label in about page
- fix(googlereader): return a 400 instead of 500 for invalid edit requests
- fix(googlereader): handle various item ID formats
- fix(googlereader): avoid panic for inexisting feed or category
- fix(googlereader):
/items/contentsshould accept short form item IDs - feat(webauthn): prefer creation of a client-side discoverable credential
- feat(urlcleaner): remove the
refparameter from url - feat(settings): replace
div.panelwith paragraph tags for OAuth2 links - feat(settings): add validation for entry order and categories sorting order
- feat(settings): add option to always open articles externally
- feat(server): add liveness and readiness probes
- feat(sanitizer): add MathML tags to the sanitizer
- feat(sanitized): allow Spotify iframes
- feat(rssbridge): support authentication token for RSS-Bridge
- feat(response): change error response content type to plain text and escape HTML
- feat(reader): populate feed description automatically
- feat(locale): update Russian translation
- feat(locale): update Polish translation
- feat(locale): update French translation
- feat(googlereader): avoid SQL query to fetch username in streamItemContentsHandler
- feat(googlereader): add
mark-all-as-readendpoint - feat(api): add new endpoints to manage API keys
- ci: remove deprecated
reviewersfield fromdependantbot.yml - chore(gitignore): ignore miniflux binary in root directory
- build(deps): bump
golangci/golangci-lint-actionfrom7to8 - build(deps): bump
golang.org/x/oauth2from0.29.0to0.30.0 - build(deps): bump
golang.org/x/netfrom0.39.0to0.40.0 - build(deps): bump
golang.org/x/imagefrom0.26.0to0.27.0 - build(deps): bump
golang.org/x/cryptofrom0.37.0to0.38.0 - build(deps): bump
github.com/tdewolff/minify/v2from2.23.3to2.23.8 - build(deps): bump
github.com/tdewolff/minify/v2from2.23.1to2.23.3 - build(deps): bump
github.com/go-webauthn/webauthnfrom0.12.3to0.13.0
Miniflux 2.2.8
- refactor(js): replace
DomHelpermethods with standalone functions - refactor: avoid logging twice the feed errors in the background worker
- fix(api):
hide_globallycategories field should be a boolean - fix(ui): add missing
awaitwhen callingnavigator.share()method - fix(ui): replace share link with a form button for better accessibility
- feat(telegrambot): replace "Go to website" button with "Go to Miniflux"
- feat(locale): update Polish translation
- feat(locale): update German translation
- feat(locale): update Chinese translation
- feat(config): add
SCHEDULER_ROUND_ROBIN_MAX_INTERVALoption - feat(cli): add
-reset-feed-next-check-atargument - feat(api): add
update_contentquery parameter to/entries/{entryID}/fetch-contentendpoint - feat: use
Cache-Controlmax-age andExpiresheaders to calculate next check - feat: implement proxy URL per feed
- feat: add proxy rotation functionality
- ci(linter): replace commitlint with a Python script
- ci: add documentation issue template
- build(deps): bump
golang.org/x/oauth2from0.28.0to0.29.0 - build(deps): bump
golang.org/x/netfrom0.38.0to0.39.0 - build(deps): bump
golang.org/x/imagefrom0.25.0to0.26.0 - build(deps): bump
github.com/tdewolff/minify/v2from2.22.4to2.23.1 - build(deps): bump
github.com/PuerkitoBio/goqueryfrom1.10.2to1.10.3 - build(deps): bump
github.com/prometheus/client_golang - build(deps): bump
github.com/mattn/go-sqlite3from1.14.24to1.14.28 - build(deps): bump
github.com/go-webauthn/webauthnfrom0.12.2to0.12.3 - build(deps): bump
github.com/coreos/go-oidc/v3from3.13.0to3.14.1