← Blog
Self-hosting16 min czytania

yarr — czytnik RSS zamknięty w jednym binarium

yarr to czytnik kanałów w jednym pliku wykonywalnym, bez zależności, działający jako aplikacja desktopowa albo serwer. Opisujemy konfigurację, wybór między SQLite i PostgreSQL oraz pułapkę, która cicho wyłącza tryb WAL.

Czytnik kanałów wrócił do łask z prostego powodu: jest jedynym sposobem czytania internetu, w którym o kolejności decydujesz ty, a nie cudzy algorytm. Subskrybujesz to, co chcesz, dostajesz wszystko, co zostało opublikowane, i nikt nie wtrąca ci między wpisy treści sponsorowanej.

Problem z czytnikami polega na tym, że hostowane umierają. Google Reader zamknięto w 2013, Pocket — narzędzie z sąsiedniej kategorii — Mozilla wyłączyła w 2025. Za każdym razem ci sami ludzie eksportują te same pliki OPML i szukają nowego domu dla tych samych stu subskrypcji.

yarr jest odpowiedzią na to najprostszą, jaką da się wymyślić: jeden plik wykonywalny bez zależności, który uruchamiasz jako aplikację na własnym komputerze albo jako serwer w swojej sieci. Nie ma czego zamknąć, bo nie ma usługi — jest plik.

Stan projektu

Repozytorium: nkanaev/yarr. 4044 gwiazdki, 293 forki, licencja MIT z prawami Nazara Kanaeva. Start w czerwcu 2020, więc projekt ma sześć lat.

Utrzymanie jest znakomite i warto podać liczby, bo mówią same za siebie. Ostatnie commity na gałęzi master pochodzą z 9 września 2026 — dnia przed powstaniem tego wpisu. Wydanie v2.9 ukazało się 7 września, a wcześniejsze: v2.8 w lipcu, v2.7 w czerwcu, v2.6 w listopadzie 2025. Tempo wyraźnie przyspieszyło w ostatnim roku. A liczba, która zwraca uwagę najbardziej: osiem otwartych zgłoszeń przy czterech tysiącach gwiazdek. Tak wygląda projekt, w którym ktoś naprawdę czyta zgłoszenia.

Autor jest jeden i przy narzędziu tej klasy to normalne — ale warto to wpisać w ocenę ryzyka, jeśli yarr ma być firmowym narzędziem. Z drugiej strony jest to program napisany w Go, z zależnościami zawartymi w repozytorium (katalog vendor), więc zbudowanie go samodzielnie za pięć lat będzie realne niezależnie od tego, co się stanie z autorem czy z npm-em.

Dokument, który mówi, czym ten program nie jest

W repozytorium leży plik z uzasadnieniem projektu i jest to lektura, na którą warto poświęcić minutę, bo takich dokumentów prawie się nie pisze. Zaczyna się od celu, a zaraz potem od jawnego nie-celu: yarr nie jest zaprojektowany ani przeznaczony do użycia jako narzędzie archiwizujące.

To zdanie oszczędza rozczarowania. Jeśli szukasz narzędzia, które zachowa treść artykułów na wypadek zniknięcia oryginału, to nie jest ten program — do tego są zbieracze z pełną archiwizacją strony. yarr jest czytnikiem: pokazuje, co się pojawiło, i pozwala to przeczytać wygodnie.

Pierwotny cel autor opisuje równie szczerze: chciał aplikacji desktopowej dostępnej przez przeglądarkę, bo trzymanie dwóch działających programów — czytnika i przeglądarki — było irytujące. Stąd bierze się cała architektura tego projektu, w której tryb desktopowy i serwerowy to ta sama rzecz.

Dokument wymienia też rodowód interfejsu — układ trzykolumnowy i część elementów nawigacji wzorowano na Reeder 3, NetNewsWire i Feedbinie — oraz powody wyboru technologii. Dla Go: kompilacja do jednego pliku, dostępność bibliotek i „wymówka autora, by nauczyć się Go". Dla SQLite: brak potrzeby konfiguracji bazy, co przy aplikacji desktopowej jest ogromnym plusem, oraz — cytując — „SQL jest nudny i praktyczny".

Jedno zastrzeżenie do tego dokumentu, bo weryfikacja wykazała rozbieżność. Jest tam deklaracja, że projekt nie wprowadzi ekosystemu node i npm, a kod JavaScriptu osób trzecich jest włączany do projektu wprost, przy czym ES5 jest preferowany nad ES6. To już nie odpowiada stanowi kodu: w korzeniu repozytorium są package.json, package-lock.json, tsconfig.json i skrypt budujący, a lista zmian wersji 2.9 wymienia przebudowę frontendu z Vue 2 na Vue 3 i z Bootstrapa 4 na 5. Dokument uzasadnienia opisuje więc intencje z 2020 roku, nie dzisiejszy stan — co samo w sobie jest normalne, ale warto o tym wiedzieć, czytając go jako opis projektu.

Jeden plik i koniec

To główna teza tego projektu, więc wypada sprawdzić, co za nią stoi. Zależności produkcyjne z pliku go.mod to: sterownik SQLite, sterownik PostgreSQL, biblioteka do ikony w zasobniku systemowym, biblioteka wyrażeń oraz dwa pakiety z rozszerzonej biblioteki standardowej Go. Całość jest kompilowana do jednego pliku wykonywalnego, a interfejs — napisany w TypeScripcie i budowany osobno — jest do tego pliku wbudowany.

Wersje dla wiersza poleceń wydawane są na siedem kombinacji systemu i architektury: macOS na Apple Silicon i Intelu, Windows na ARM64 i x86-64 oraz Linux na x86-64, ARM64 i ARMv7. Ta ostatnia pozycja znaczy, że yarr zadziała na starszym Raspberry Pi — i to jest właśnie ten rodzaj sprzętu, na którym czytnik kanałów ma sens, bo może chodzić bez przerwy przy zużyciu prądu rzędu kilku watów.

Dwa tryby pracy

yarr może być aplikacją desktopową albo serwerem, i to ta sama rzecz w dwóch opakowaniach.

W trybie desktopowym dostajesz ikonę w zasobniku systemowym (na macOS w pasku menu), z której otwierasz czytnik w przeglądarce. Dane trafiają automatycznie do katalogu konfiguracyjnego użytkownika i nie trzeba niczego ustawiać. Tu jednak uwaga, którą trzeba powiedzieć wprost: wydania z interfejsem graficznym są dostępne wyłącznie dla macOS i Windowsa. Na Linuksie zostaje wariant serwerowy — co przy Linuksie na biurku znaczy po prostu uruchomienie procesu i otwarcie zakładki, więc strata jest niewielka, ale warto o niej wiedzieć przed pobraniem.

W trybie serwerowym uruchamiasz plik i otwierasz przeglądarkę. Domyślnie serwer nasłuchuje na 127.0.0.1:7070, czyli tylko z maszyny, na której działa — i to jest właściwe ustawienie domyślne, którego wiele projektów nie ma. Wystawienie na zewnątrz wymaga świadomej decyzji.

Konfiguracja

Wszystkie opcje mają postać flag wiersza poleceń oraz odpowiadających im zmiennych środowiskowych, przy czym flaga ma pierwszeństwo nad zmienną. Najważniejsze:

  • -addr / YARR_ADDR — adres nasłuchu. 0.0.0.0 otwiera na wszystkie interfejsy.
  • -auth / YARR_AUTH — nazwa użytkownika i hasło w formacie użytkownik:hasło.
  • -auth-file / YARR_AUTHFILE — ścieżka do pliku z tymi danymi. Ma pierwszeństwo nad -auth.
  • -cert-file i -key-file — certyfikat i klucz TLS. Oba są wymagane, by włączyć HTTPS.
  • -base — ścieżka bazowa, gdy serwis stoi pod podkatalogiem.
  • -db, -log-file, -open — magazyn danych, plik dziennika i otwarcie przeglądarki po starcie.

Rada praktyczna: używaj -auth-file, nie -auth. Hasło podane jako argument wiersza poleceń widać w liście procesów i zostaje w historii powłoki. Plik z odpowiednimi uprawnieniami rozwiązuje oba problemy, a autor przewidział tę ścieżkę i dał jej pierwszeństwo.

Jest też opcja, którą doceni każdy, kto stawia usługi za odwrotnym proxy: zamiast portu TCP serwer może nasłuchiwać na gniazdku uniksowym. Wystarczy poprzedzić ścieżkę przedrostkiem unix:. Przy nginksie albo Caddym to najczystszy układ — usługa nie zajmuje żadnego portu i nie da się do niej trafić z sieci przypadkiem.

SQLite czy PostgreSQL — i jedna pułapka

Magazyn wybiera się wartością flagi -db i mechanizm jest sprytny: zwykła ścieżka pliku znaczy SQLite, a łańcuch zaczynający się od postgres:// albo postgresql:// — PostgreSQL. Nie ma osobnego przełącznika trybu.

Bez podanej ścieżki dane trafiają do pliku storage.db w katalogu konfiguracyjnym użytkownika: na Linuksie pod $XDG_CONFIG_HOME/yarr/ (domyślnie ~/.config/yarr/), na macOS w ~/Library/Application Support/yarr/, na Windowsie w %AppData%\yarr\. Zgodność z konwencjami każdego systemu, bez wynalazków.

A teraz pułapka, którą znalazłem w dokumentacji magazynu i którą uważam za najważniejszą techniczną informację w tym wpisie. Ścieżka pliku SQLite przyjmuje parametry połączenia sterownika, a gdy ich nie podasz, yarr stosuje własne wartości domyślne: _journal=WAL&_sync=NORMAL&_busy_timeout=5000&cache=shared. Są to ustawienia dobrze przemyślane — dziennik z wyprzedzeniem zapisu, rozsądna synchronizacja i pięciosekundowy limit oczekiwania na zajętą bazę.

Ale dokumentacja mówi wyraźnie: jeśli podasz własne parametry, zastępują one wartości domyślne w całości. Nie są z nimi łączone. Czyli dopisanie jednego parametru — na przykład zmiany trybu blokowania — cicho wyłącza tryb WAL i limit oczekiwania. Efektem będą sporadyczne błędy „database is locked" przy jednoczesnym odświeżaniu kanałów i przeglądaniu, których nikt nie powiąże z parametrem dopisanym trzy miesiące wcześniej. Jeśli musisz coś zmienić, przepisz cały zestaw, nie tylko swój dodatek.

Przy PostgreSQL obowiązuje jedna zasada warta zapamiętania: baza musi już istnieć, natomiast tabele yarr tworzy i aktualizuje sam przy starcie. Warto też odnotować, że obsługa obu silników nie jest doklejona — w kodzie źródłowym magazyn ma osobne podpakiety dla SQLite i PostgreSQL obok wspólnego modelu, więc to porządny rozdział, a nie warunek w kilkunastu miejscach.

Czytnik

Zakres funkcji jest przemyślany i skończony — to nie projekt, który chce być wszystkim.

Obsługiwane formaty kanałów to Atom, RSS, RDF i JSON Feed. Import i eksport OPML pozwala wejść i wyjść z całą kolekcją subskrypcji, co przy narzędziu tej kategorii jest warunkiem koniecznym. Kanały odświeża harmonogram działający w tle. Jest pełnotekstowe wyszukiwanie po wszystkich artykułach, skróty klawiszowe do szybkiej nawigacji oraz cztery motywy: jasny, beżowy, nocny i automatyczny za systemem.

Interfejs jest responsywny i instalowalny jako aplikacja webowa (PWA), więc na telefonie dostajesz ikonę na ekranie startowym bez pośrednictwa sklepu z aplikacjami.

Dwie funkcje warto wyróżnić. Pierwsza to silnik czytelności — dla kanałów podających tylko skrót artykułu yarr potrafi pobrać i wyświetlić pełną treść lokalnie, zamiast odsyłać do strony wydawcy. Czytelnikom tej serii przypomni to wpis o bibliotece Readability z ekosystemu Mozilli: to dokładnie ta klasa problemu, tylko rozwiązana wewnątrz czytnika.

Druga to obsługa załączników: podcasty, wideo oraz odtwarzanie materiałów z YouTube'a wprost w czytniku. Kanał podcastowy to technicznie RSS z załącznikiem audio, więc czytnik kanałów jest naturalnym odtwarzaczem podcastów — tylko rzadko któryś to robi.

Fever API, czyli twój czytnik w cudzej aplikacji

To funkcja, która najbardziej zmienia sposób korzystania z tego programu, a łatwo ją przeoczyć w liście cech. yarr udostępnia pod ścieżką /fever API zgodne z Fever — protokołem, który obsługuje spora część komercyjnych czytników mobilnych. Praktycznie znaczy to, że serwer trzymasz u siebie, a czytasz w dopracowanej aplikacji na telefonie.

Włączenie wymaga ustawienia uwierzytelniania flagą -auth, po czym w aplikacji podaje się adres serwera z dopiskiem /fever oraz te same dane logowania.

Dokumentacja jest tu wzorowo uczciwa. Autor pisze wprost, że specyfikacja Fever nie jest precyzyjna, więc implementacje serwerów i klientów mogą mieć problemy ze zgodnością — i zamiast na tym poprzestać, podaje tabelę przetestowanych aplikacji: Reeder, ReadKit, Fluent Reader, Unread i Fiery Feeds, wraz z platformami. Co więcej, dla każdej podaje dokładny format adresu, bo różne aplikacje różnie go przyjmują — jedna chce schemat http://, druga działa bez niego, trzecia wymaga ukośnika na końcu. To dokładnie ten rodzaj informacji, którego szuka się potem godzinę na forach.

Jest też zwykłe API REST do skryptowania i automatyzacji, jeśli chcesz zrobić z tego coś więcej niż czytnik.

Bezpieczeństwo i prywatność

Zestaw jest adekwatny do skali narzędzia, a nie udający korporacyjny. Uwierzytelnianie podstawowe do dostępu zdalnego, HTTPS z własnymi certyfikatami, rygorystyczna polityka nagłówka Referrer, żeby wydawcy nie dowiadywali się, z jakiej instancji przyszło żądanie, oraz sanityzacja treści przed wyświetleniem — bo treść kanału to obcy HTML, a czytnik go renderuje.

Ta ostatnia rzecz jest niedoceniana. Czytnik kanałów pobiera i wyświetla znaczniki napisane przez kogoś obcego, więc bez oczyszczania byłby wektorem wstrzyknięcia skryptu — i to na stronie, która ma twoją sesję. Warto zauważyć, że yarr traktuje to jako część zakresu, w odróżnieniu od bibliotek ekstrakcji treści, które (jak opisywana wcześniej Readability) jawnie odsyłają ten problem do użytkownika.

Do tego dochodzi domyślne nasłuchiwanie tylko na pętli lokalnej, o którym już było — najprostsze i najskuteczniejsze zabezpieczenie, jakie da się zastosować.

Co doszło ostatnio i co to mówi o projekcie

Lista zmian jest prowadzona porządnie i najlepiej pokazuje, że opisane wyżej funkcje to w dużej części świeży dorobek, a nie stan z lat temu.

Obsługa PostgreSQL jest nowa — pojawiła się w wersji 2.7 z czerwca 2026, opisana jako początkowa. Jeśli planujesz wdrożenie na tym silniku, warto o tym wiedzieć: to najmłodsza część systemu, a SQLite ma za sobą sześć lat użycia. Fever API również nie jest odwieczne — doszło w wersji 2.5 z marca 2025. Ta sama wersja 2.7 przyniosła tłumaczenia interfejsu na osiem języków: angielski, chiński, francuski, niemiecki, japoński, portugalski, rosyjski i hiszpański. Polskiego wśród nich nie ma — a przy projekcie tej wielkości, z ośmioma otwartymi zgłoszeniami i czynnym autorem, dołożenie tłumaczenia jest realnym, drobnym wkładem.

Dwie pozycje z listy zmian potwierdzają przy tym, że bezpieczeństwo nie jest tu deklaracją. W wersji 2.6 z listopada 2025 pojawiły się zabezpieczenia ciasteczek oraz — co ważniejsze — ograniczenie dostępu do wewnętrznych adresów IP dla mechanizmu pobierającego strony. Oba wpisy mają podane z nazwiska osoby, które je zgłosiły.

Ta druga poprawka zasługuje na komentarz, bo dotyczy dokładnie tej klasy problemu, którą opisywaliśmy przy innych narzędziach pobierających treść na żądanie użytkownika. Silnik czytelności pobiera adres, który wskazał użytkownik — a to znaczy, że bez ograniczeń mógłby odpytywać usługi w twojej sieci wewnętrznej, niedostępne z internetu. Zostało to naprawione i zaraportowane jawnie. Praktyczny wniosek dla ciebie: używaj wersji 2.6 lub nowszej, jeśli instancja jest dostępna dla kogokolwiek poza tobą.

Z wersji 2.8 warto jeszcze wyłowić jedną zmianę zachowania, bo bywa myląca: kanały nie są już automatycznie odświeżane przy starcie. Jeśli uruchamiasz yarr i dziwisz się, że nic nowego nie widać, to nie awaria — trzeba odświeżyć ręcznie albo poczekać na harmonogram. Doszła też obsługa HTTP/2.

Zastosowanie firmowe

Poza czytaniem prywatnym ten program ma w firmie dwa sensowne zastosowania.

Pierwsze to monitorowanie źródeł: blogi konkurencji, ogłoszenia o podatnościach, zmiany w dokumentacji dostawców, komunikaty regulatorów. Wszystko to zwykle ma kanał RSS, a jedna instancja z API REST pozwala te informacje przekazać dalej — na przykład do firmowego czatu.

Drugie to prywatność samego czytania. To, co subskrybujesz i co otwierasz, jest informacją o twoich zainteresowaniach zawodowych — a przy czytniku hostowanym jest też informacją, którą ma dostawca. Lista kanałów zespołu badawczego albo działu prawnego bywa danymi, których nie chce się nikomu zostawiać. Własna instancja usuwa ten problem całkowicie, bo nie ma żadnego zewnętrznego podmiotu w tej operacji.

Pułapki w jednym miejscu

  • Własne parametry SQLite zastępują domyślne w całości — dopisanie jednego cicho wyłącza tryb WAL i limit oczekiwania. Przepisz cały zestaw.
  • Baza PostgreSQL musi istnieć przed startem. Tabele yarr tworzy sam, bazy nie.
  • Wydania z interfejsem graficznym są tylko dla macOS i Windowsa. Na Linuksie zostaje wariant serwerowy.
  • Używaj -auth-file, nie -auth — hasło w argumencie widać w liście procesów i zostaje w historii powłoki.
  • HTTPS wymaga obu plików — certyfikatu i klucza. Jeden nie wystarczy.
  • Fever API wymaga ustawionego uwierzytelniania i bywa kapryśne co do formatu adresu — sprawdź tabelę przetestowanych aplikacji.
  • Domyślnie serwer nasłuchuje tylko lokalnie. To zaleta, ale trzeba o tym wiedzieć, szukając usługi z innej maszyny.
  • To nie narzędzie archiwizujące — autor deklaruje to jako jawny nie-cel. Do zachowywania treści potrzebujesz czegoś innego.
  • Obsługa PostgreSQL jest najmłodszą częścią systemu (wersja 2.7, czerwiec 2026), opisaną jako początkowa.
  • Od wersji 2.8 kanały nie odświeżają się przy starcie. Brak nowych wpisów po uruchomieniu to nie awaria.
  • Poprawka blokująca dostęp crawlera do wewnętrznych adresów IP weszła w wersji 2.6. Starszych wersji nie wystawiaj nikomu poza sobą.
  • Brak polskiego tłumaczenia interfejsu — jest osiem innych języków.
  • Jeden autor. Projekt jest wzorowo utrzymywany, ale zależy od jednej osoby.

Podsumowanie

yarr jest przykładem oprogramowania, które robi dokładnie tyle, ile trzeba, i ani trochę więcej. Nie ma kont, nie ma chmury, nie ma warstwy synchronizacji — jest plik, baza i przeglądarka. Przy narzędziu, które ma działać przez dekadę na komputerze w szafie, ta oszczędność jest najważniejszą cechą.

  • Jeden plik wykonywalny bez zależności, na siedem kombinacji systemu i architektury, wraz z ARMv7 dla starszych Raspberry Pi.
  • Dwa tryby w jednym programie — aplikacja desktopowa z ikoną w zasobniku albo serwer dla całej sieci.
  • SQLite albo PostgreSQL, wybierane samym formatem ścieżki, z porządnym rozdziałem w kodzie.
  • Fever API, dzięki któremu czytasz własne kanały w dopracowanych aplikacjach mobilnych.
  • Silnik czytelności i obsługa załączników — pełne treści ze skróconych kanałów oraz podcasty i wideo w czytniku.
  • Rozsądne domyślne ustawienia bezpieczeństwa — nasłuch lokalny, sanityzacja treści i rygorystyczna polityka nagłówka Referrer.

Projekt jest wydany na licencji MIT z prawami Nazara Kanaeva — najbardziej permisywnej z popularnych. Możesz go używać komercyjnie, modyfikować i wdrażać u klientów bez obowiązku otwierania własnego kodu. Przy programie w Go z zależnościami zawartymi w repozytorium ta licencja ma jeszcze jedną, praktyczną wartość: jeśli projekt kiedykolwiek stanie, nic nie stoi na przeszkodzie, żeby zbudować go sobie samemu z tego, co już macie na dysku — a to przy narzędziu, w którym trzymacie sto subskrypcji i historię czytania, jest różnica między niezależnością a kolejnym eksportem OPML.