{"id":42890181,"url":"https://github.com/irq0/llar","last_synced_at":"2026-01-30T14:56:58.193Z","repository":{"id":223377094,"uuid":"381845183","full_name":"irq0/llar","owner":"irq0","description":"🖖 Live Long and Read!  A self-hosted news aggregator focused on customizability.","archived":false,"fork":false,"pushed_at":"2025-07-17T22:05:49.000Z","size":30905,"stargazers_count":7,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-18T02:58:36.184Z","etag":null,"topics":["clojure","crawler","feed-reader","hackernews-api","news-aggregator","news-reader","reddit-api","rss","rss-reader"],"latest_commit_sha":null,"homepage":"","language":"Clojure","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/irq0.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-06-30T22:13:52.000Z","updated_at":"2025-07-17T22:05:53.000Z","dependencies_parsed_at":"2024-12-29T09:21:02.356Z","dependency_job_id":"a30c0602-bd11-4622-8740-32e3bf6686d2","html_url":"https://github.com/irq0/llar","commit_stats":null,"previous_names":["irq0/llar"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/irq0/llar","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irq0%2Fllar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irq0%2Fllar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irq0%2Fllar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irq0%2Fllar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/irq0","download_url":"https://codeload.github.com/irq0/llar/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/irq0%2Fllar/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28914895,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-30T12:13:43.263Z","status":"ssl_error","status_checked_at":"2026-01-30T12:13:22.389Z","response_time":66,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clojure","crawler","feed-reader","hackernews-api","news-aggregator","news-reader","reddit-api","rss","rss-reader"],"created_at":"2026-01-30T14:56:58.117Z","updated_at":"2026-01-30T14:56:58.185Z","avatar_url":"https://github.com/irq0.png","language":"Clojure","readme":"# 🖖\n\nLive Long and Read!\n\nA self-hosted news aggregator focused on customizability.\n\n## Getting Started\n\nLLAR needs a PostgreSQL database, a JVM and a [couple of command line tools](resources/config.edn) to run.\nEasiest way to get started is to use docker compose with the [llar container image](https://github.com/irq0/llar/pkgs/container/llar).\n\n```sh\ngit clone https://github.com/irq0/llar.git\ncd llar/docker\ndocker-compose pull\ndocker-compose up\n```\n\n### Add your first feed\n\nIf you use the docker compose way above, the configuration  lives in `llar/config`.\nLLAR watches that directory for change.\n\nLet's add an RSS feed and the Hacker News front page as an example.\n\nthis projects GitHub release feed as an example. Put the following in `llar/config/myfirstconfig.llar`.\n\n```clojure\n(fetch github-llar-releases (src/feed \"https://github.com/irq0/llar/releases.atom\") :tags #{:my-first-feed :github})\n(fetch hn-frontpage (src/hn :front_page) :tags #{:my-first-feed :hackernews})\n(sched-fetch my-first-feeds :now-and-hourly (some #{:my-first-feed} $TAGS))\n```\n\nWhat does this do?\n\n`fetch` instructs LLAR how to fetch a *source*, it's name and various options.\nIn this example we have a `feed` source with URL `https://github.com/irq0/llar/releases.atom` and a `hn`\nsource which takes a Hacker News search tag instead of an address.\nFeed sources are the most common and support RSS, Atom and the like.\n\n`github-llar-releases` and `hn-frontpage` are *source key*. A user-defined identifier for all data fetched from this source.\n\n`:tags #{:my-first-feed :github}` instructs LLAR to tag this source with `:my-first-feed` and `:github`.\nThis is Clojure syntax to say \"set the fetch function's tags keyword argument to a set of two keywords\".\nKeywords in this case behave much like strings, except that you really shouldn't use whitespace in them.\n\nThe last line creates a *fetch schedule*. LLAR is quite flexible in when to update what.\nIn this case we define a schedule `my-first-feeds` that updates all sources tagged `:my-first-feed`\nnow (0-120 seconds after LLAR loads the schedule) and then every hour.\n\n### Have an OPML file?\n\nAwesome! Copy it to the config directory and let LLAR convert if for you.\nIf you use docker please ensure that LLAR can write to the config directory.\n\nThe generated file will have the extension `.llar.example`.\nI suggest that you have a look and adjust the generated source keys.\nIf you want LLAR to load the config, just rename it to `.llar` and it will load the file.\n\n## Features\n\n- Sources: RSS, Atom, Wordpress REST, Reddit, Hacker News, IMAP mailboxes\n- Custom Feeds from HTML selectors ([example](https://github.com/irq0/llar-config/blob/main/fefe.llar),\n  [example](https://github.com/irq0/llar-config/blob/main/usenixlogin.llar))\n- Article extraction (via [Postlight Parser](https://github.com/postlight/parser))\n- HTML sanitation (fix URLs, remove annoying elements and ads)\n- Bookmark / read it later from single URLs\n- Blobstore: Keep copy of feed images to make content self-contained\n- Clojure-scriptable processing: Run code to filter or change fetched items\n- Reader UI\n- Dashboard UI\n\n## UI\n\n### Reader\n\n![Screenshot of the LLAR UI](doc/img/screenshot_2024-02-20.png)\n\nPer default running on port 8023.\n\n### Dashboard\n\nPer default running on port 9999.\n\nMakes internal application state accessible.\nThis includes memory usage,\ndatabase stats,\nschedules,\napplication state,\nthreads and\nconfiguration.\n\nGives a *technical* view on the fetch status of configured sources.\nShows timing and error information and allows manual triggers.\n\n## Concept\n\nThe [updater](src/llar/update.clj) [fetches](src/llar/fetch.clj) [sources](src/llar/src.clj),\nnormalizes the data into *items*, runs them through the [processor](src/llar/postproc.clj)\nand finally [persists](src/llar/persistency.clj) them.\n\n`.llar` [files](config/) specify sources to fetch, schedules to run, and much more.\nA fetch definition not only contains the [source](src/llar/src.clj), but also pre, post and filter rules, as well as,\nUI options and *source tags*.\n\nOn update a [fetcher](src/llar/fetch) creates *items*. Each has a title, timestamps, content, descriptions, *tags*, source.\nProcessors and filters act on individual items. Both are Clojure functions. As long as the result adheres to\nthe item spec they are free to do any kind of manipulation.\n\nLLAR knows two kinds of tags.\nSource tags, that are defined as part of a fetch definition.\nThey basically group sources and are useful to specify schedules on.\nItem tags, that are attached to an item.\nPredefined tags are *unread*, *saved*, *in-progress*, *archive*, *highlight*.\nEach has its own semantics in the UI. Arbitrary additional tags are supported.\n\n## Configuration\n\n### Appconfig\n\nLoaded on startup. Contains paths to command line tools, blob store,\nstate directory, credentials file.\n\nExamples:\n\n- [config.edn](resources/config.edn)\n- [docker-config.edn](docker/docker-config.edn)\n\n### Config\n\nRuntime configuration. Automatically loaded when files in the `:runtime-config-dir` change.\nSpecify sources to fetch, schedules, highlight rules here.\n\nFiles are (almost) Clojure code with extra constructs for convenience. They use the extension `.llar`.\nSee [readme.llar](config/readme.llar) for documentation\nor check out [my config](https://github.com/irq0/llar-config).\n\n### Credentials\n\nThe credentials file contains secrets made available with the `$credentials` function in `.llar` config files.\nSee [credentials.edn.example](resources/credentials.edn.example).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Firq0%2Fllar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Firq0%2Fllar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Firq0%2Fllar/lists"}