Skip to content
 
 

Repository files navigation

Miniflux 2

Miniflux is a minimalist and opinionated feed reader. It's simple, fast, lightweight and super easy to install.

Official website: https://miniflux.app

SQLite Edition

This fork, based on Miniflux 2.3.2, replaces PostgreSQL with SQLite via modernc.org/sqlite — a pure-Go driver with zero CGO dependencies. The entire application compiles into a single static binary, eliminating all external database requirements.

Key implementation details

  • Driver: modernc.org/sqlite (no CGO), WAL journal mode, single connection pool (MaxOpenConns=1) to avoid SQLITE_BUSY under concurrent feed refreshes.
  • Connection: DATABASE_URL accepts a file path (miniflux.db) or :memory:; defaults to /var/lib/miniflux/miniflux.db in the Docker image.
  • Schema: single-version initial migration — all tables, indexes, and FTS5 triggers are created in one step.
  • Full-text search: FTS5 external-content virtual table (entries_fts) with unicode61 tokenizer, kept in sync via INSERT/UPDATE/DELETE triggers. Relevance ranking (ts_rank) is dropped; results are ordered by published_at.
  • Data types: timestamptz → TEXT (stored in Go's time.Time.String() format; read through a custom model.Time scanner), bool → INTEGER, text[] → JSON TEXT, inet → TEXT, jsonb → TEXT.
  • SQL rewrites: $N?N, now()strftime(), = ANY()IN (...), ILIKELOWER LIKE, data-modifying CTEs (WITH ... UPDATE/DELETE ... RETURNING) are split into individual statements.
  • Time handling: model.Time.Scan parses 8 timestamp layouts and strips Go monotonic-clock (m=+...) and double‑timezone (+0800 +0800) suffixes.
  • Disk space: VACUUM runs automatically after cleanup tasks and FlushHistory to reclaim freed pages.
  • Docker: Alpine‑based image with an entrypoint.sh that fixes volume permissions at startup, then drops to nobody (UID 65534) via su‑exec.

See MIGRATION_SQLITE.md for the full migration report — file changes, functional differences, bug fix history, Docker deployment guide, and known limitations.

Features

Feed Reader

  • Supported feed formats: Atom 0.3/1.0, RSS 1.0/2.0, and JSON Feed 1.0/1.1.
  • OPML file import/export and URL import.
  • Supports multiple attachments (podcasts, videos, music, and images enclosures).
  • Plays videos from YouTube directly inside Miniflux.
  • Organizes articles using categories and bookmarks.
  • Share individual articles publicly.
  • Fetches website icons (favicons).
  • Saves articles to third-party services.
  • Provides full-text search (powered by SQLite FTS5).
  • Available in 20 languages: Portuguese (Brazilian), Chinese (Simplified and Traditional), Dutch, English (US), Finnish, French, German, Greek, Hindi, Indonesian, Italian, Japanese, Polish, Romanian, Russian, Taiwanese POJ, Ukrainian, Spanish, and Turkish.

Privacy and Security

  • Removes pixel trackers.
  • Strips tracking parameters from URLs (e.g., utm_source, utm_medium, utm_campaign, fbclid, etc.).
  • Retrieves original links when feeds are sourced from FeedBurner.
  • Opens external links with attributes rel="noopener noreferrer" referrerpolicy="no-referrer" for improved security.
  • Implements the HTTP header Referrer-Policy: no-referrer to prevent referrer leakage.
  • Provides a media proxy to avoid tracking and resolve mixed content warnings when using HTTPS.
  • Plays YouTube videos via the privacy-focused domain youtube-nocookie.com.
  • Supports alternative YouTube video players such as Invidious.
  • Blocks external JavaScript to prevent tracking and enhance security.
  • Sanitizes external content before rendering it.
  • Enforces a Content Security and a Trusted Types Policy to only application JavaScript and blocks inline scripts and styles.

Bot Protection Bypass Mechanisms

  • Optionally disable HTTP/2 to mitigate fingerprinting.
  • Allows configuration of a custom user agent.
  • Supports adding custom cookies for specific use cases.
  • Enables the use of proxies for enhanced privacy or bypassing restrictions.

Content Manipulation

  • Fetches the original article and extracts only the relevant content using a local Readability parser.
  • Allows custom scraper rules based on CSS selectors.
  • Supports custom rewriting rules for content manipulation.
  • Provides a regex filter to include or exclude articles based on specific patterns.
  • Optionally permits self-signed or invalid certificates (disabled by default).
  • Scrapes YouTube's website to retrieve video duration as read time or uses the YouTube API (disabled by default).

User Interface

  • Optimized stylesheet for readability.
  • Responsive design that adapts seamlessly to desktop, tablet, and mobile devices.
  • Minimalistic and distraction-free user interface.
  • No requirement to download an app from Apple App Store or Google Play Store.
  • Can be added directly to the home screen for quick access.
  • Supports a wide range of keyboard shortcuts for efficient navigation.
  • Optional touch gesture support for navigation on mobile devices.
  • Custom stylesheets and JavaScript to personalize the user interface to your preferences.
  • Themes:
    • Light (Sans-Serif)
    • Light (Serif)
    • Dark (Sans-Serif)
    • Dark (Serif)
    • System (Sans-Serif) – Automatically switches between Dark and Light themes based on system preferences.
    • System (Serif)

Integrations

Authentication

  • Local username and password.
  • Passkeys (WebAuthn).
  • Google (OAuth2).
  • Generic OpenID Connect.
  • Reverse-Proxy authentication.

Technical Stuff

  • Written in Go (Golang).
  • Single binary compiled statically without dependency.
  • Works only with SQLite (embedded, no external server required).
  • Does not use any ORM or any complicated frameworks.
  • Uses modern vanilla JavaScript only when necessary.
  • All static files are bundled into the application binary using the Go embed package.
  • Supports the Systemd sd_notify protocol for process monitoring.
  • Configures HTTPS automatically with Let's Encrypt.
  • Allows the use of custom SSL certificates.
  • Supports HTTP/2 when TLS is enabled.
  • Updates feeds in the background using an internal scheduler or a traditional cron job.
  • Uses native lazy loading for images and iframes.
  • Compatible only with modern browsers.
  • Adheres to the Twelve-Factor App methodology.
  • Provides official Debian/RPM packages and pre-built binaries.
  • Publishes a Docker image to Docker Hub, GitHub Registry, and Quay.io Registry, with ARM and RISC-V architecture support.
  • Uses a limited amount of third-party go dependencies
  • Has a comprehensive testsuite, with both unit tests and integration tests.
  • Only uses a couple of MB of memory and a negligible amount of CPU, even with several hundreds of feeds.
  • Respects/sends Last-Modified, If-Modified-Since, If-None-Match, Cache-Control, Expires and ETags headers, and has a default polling interval of 1h.

Building

Requires Go and Docker (for images).

Compile

Command Description
make miniflux Build locally (PIE)
make linux-amd64 Cross-compile Linux amd64
make linux-arm64 Cross-compile Linux arm64
make linux-armv7 Cross-compile Linux armv7
make linux-riscv64 Cross-compile Linux riscv64
make darwin-amd64 Cross-compile macOS amd64
make darwin-arm64 Cross-compile macOS arm64
make freebsd-amd64 Cross-compile FreeBSD amd64
make openbsd-amd64 Cross-compile OpenBSD amd64
make build Build all platforms

Run locally

Command Description
make run Run with admin account (admin / test123)

Docker

Command Description
make docker-image Build Alpine image
make docker-image-distroless Build Distroless image
make docker-images Multi-platform build and push

Docker image build requires a tagged commit (git tag). To build with a custom tag directly:

docker build --pull -t miniflux/miniflux-sqlite:latest -f packaging/docker/alpine/Dockerfile .

Alpine vs Distroless

Feature Alpine Distroless
External volume permissions Auto-fixed via entrypoint.sh Must chown host dir to 65532
Shell in container
Image size ~15 MB ~30 MB
Recommendation Preferred Use for internal/k8s volumes

Distroless note: Distroless has no shell, so entrypoint.sh cannot run. Anonymous volumes work out of the box, but external mounts (-v /host/path:/var/lib/miniflux) require the host directory to be owned by UID 65532:

chown 65532 /host/path
docker run -v /host/path:/var/lib/miniflux miniflux/miniflux-sqlite:latest

Packages

Command Description
make rpm Build RPM package
make debian Build deb package
make debian-packages Build all architecture deb packages

Test & Clean

Command Description
make test Run unit tests
make lint Run linters
make integration-test Run integration tests
make clean Remove build artifacts

Documentation

The Miniflux documentation is available here: https://miniflux.app/docs/ (Man page)

Screenshots

Default theme:

Default theme

Dark theme when using keyboard navigation:

Dark theme

Credits

About

Minimalist and opinionated feed reader

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages