# nextcloud/news architecture

> Architecture diagram of the GitHub repository nextcloud/news, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-27). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/nextcloud/news
- Repository: https://github.com/nextcloud/news

## Overview

Nextcloud News is an RSS/Atom aggregator with a Vue client and a Nextcloud-hosted PHP API. The main user flow is browsing feeds and folders, requesting item lists, and changing read or starred state; controllers delegate those operations to services and database mappers. Separately, scheduled jobs fetch and parse subscriptions into items. The README also identifies a REST API; the tree documents import/export, sharing, search, recommendations, and podcast playback. Links for unsampled subsystems are limited to directory-level evidence.

Main entry points: [`appinfo/routes.php`](https://github.com/nextcloud/news/blob/master/appinfo/routes.php) (Route definitions), [`lib/Service/FeedServiceV2.php`](https://github.com/nextcloud/news/blob/master/lib/Service/FeedServiceV2.php) (Feed service), [`lib/Db`](https://github.com/nextcloud/news/tree/master/lib/Db) (Entity mappers), [`src/App.vue`](https://github.com/nextcloud/news/blob/master/src/App.vue) (Vue application)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_client["News client"]
  node_app["Vue application<br/>[App.vue]"]
  node_routes["Reader views<br/>[Feed.vue]"]
  node_clientdata["Client data services<br/>[feed.service.ts]"]
  node_state["Vuex state<br/>[index.ts]"]
end

subgraph group_api["HTTP API"]
  node_routesphp["Route definitions<br/>[routes.php]"]
  node_feedcontroller["Feed endpoints<br/>[FeedController.php]"]
  node_itemcontroller["Item endpoints<br/>[ItemController.php]"]
  node_itemapi["REST item API"]
end

subgraph group_domain["Feed domain"]
  node_feedservice["Feed service<br/>[FeedServiceV2.php]"]
  node_itemservice["Item service<br/>[ItemServiceV2.php]"]
  node_folderservice["Folder service"]
  node_mappers["Entity mappers"]
end

subgraph group_background["Background ingestion"]
  node_updater["Feed updater<br/>[UpdaterService.php]"]
  node_fetcher["Feed fetcher<br/>[FeedFetcher.php]"]
  node_feedio["Feed-IO parser"]
end

subgraph group_features["Product features"]
  node_importexport["OPML and article transfer"]
  node_share["Item sharing<br/>[ShareService.php]"]
  node_search["Search providers"]
  node_explore["Feed discovery"]
  node_podcast["Podcast playback<br/>[App.vue]"]
  node_favicon["Favicon service"]
end

node_reader(("Reader"))
node_database[("Nextcloud database")]
node_scheduler(("Nextcloud scheduler"))
node_feedservers(("Feed servers"))

node_reader -->|"uses"| node_app
node_app -->|"renders"| node_routes
node_app -->|"dispatches"| node_state
node_routes -->|"requests data"| node_clientdata
node_clientdata -->|"calls API"| node_routesphp
node_routesphp -->|"routes feed calls"| node_feedcontroller
node_routesphp -->|"routes item calls"| node_itemcontroller
node_routesphp -->|"routes REST calls"| node_itemapi
node_feedcontroller -->|"delegates"| node_feedservice
node_itemcontroller -->|"delegates"| node_itemservice
node_itemapi -->|"delegates"| node_itemservice
node_feedservice -->|"reads and writes"| node_mappers
node_itemservice -->|"reads and writes"| node_mappers
node_folderservice -->|"reads and writes"| node_mappers
node_mappers -->|"persists entities"| node_database
node_scheduler -->|"runs jobs"| node_updater
node_updater -->|"updates feeds"| node_feedservice
node_feedservice -->|"fetches feed"| node_fetcher
node_fetcher -->|"parses feed"| node_feedio
node_fetcher -->|"requests feeds"| node_feedservers
node_feedservice -->|"updates items"| node_itemservice
node_routesphp -->|"routes transfers"| node_importexport
node_routesphp -->|"routes sharing"| node_share
node_app -->|"plays enclosure"| node_podcast
node_feedcontroller -.->|"discovery support"| node_explore
node_routesphp -->|"routes favicon"| node_favicon
node_search -.->|"searches entities"| node_mappers

click node_app "https://github.com/nextcloud/news/blob/master/src/App.vue"
click node_routes "https://github.com/nextcloud/news/blob/master/src/components/routes/Feed.vue"
click node_clientdata "https://github.com/nextcloud/news/blob/master/src/dataservices/feed.service.ts"
click node_state "https://github.com/nextcloud/news/blob/master/src/store/index.ts"
click node_routesphp "https://github.com/nextcloud/news/blob/master/appinfo/routes.php"
click node_feedcontroller "https://github.com/nextcloud/news/blob/master/lib/Controller/FeedController.php"
click node_itemcontroller "https://github.com/nextcloud/news/blob/master/lib/Controller/ItemController.php"
click node_itemapi "https://github.com/nextcloud/news/blob/master/lib/Controller/ItemApiController.php"
click node_feedservice "https://github.com/nextcloud/news/blob/master/lib/Service/FeedServiceV2.php"
click node_itemservice "https://github.com/nextcloud/news/blob/master/lib/Service/ItemServiceV2.php"
click node_folderservice "https://github.com/nextcloud/news/blob/master/lib/Service/FolderServiceV2.php"
click node_mappers "https://github.com/nextcloud/news/tree/master/lib/Db"
click node_updater "https://github.com/nextcloud/news/blob/master/lib/Service/UpdaterService.php"
click node_fetcher "https://github.com/nextcloud/news/blob/master/lib/Fetcher/FeedFetcher.php"
click node_importexport "https://github.com/nextcloud/news/tree/master/lib/Service"
click node_share "https://github.com/nextcloud/news/blob/master/lib/Service/ShareService.php"
click node_search "https://github.com/nextcloud/news/tree/master/lib/Search"
click node_explore "https://github.com/nextcloud/news/blob/master/lib/Explore/RecommendedSites.php"
click node_podcast "https://github.com/nextcloud/news/blob/master/src/App.vue"
click node_favicon "https://github.com/nextcloud/news/blob/master/lib/Controller/FaviconController.php"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_app,node_routes,node_clientdata,node_state toneBlue
class node_routesphp,node_feedcontroller,node_itemcontroller,node_itemapi,node_database toneAmber
class node_feedservice,node_itemservice,node_folderservice,node_mappers,node_feedservers toneMint
class node_updater,node_fetcher,node_feedio,node_scheduler toneRose
class node_importexport,node_share,node_search,node_explore,node_podcast,node_favicon,node_reader toneIndigo
```

## Components

### News client

- [Vue application](https://github.com/nextcloud/news/blob/master/src/App.vue): `src/App.vue`
- [Reader views](https://github.com/nextcloud/news/blob/master/src/components/routes/Feed.vue): `src/components/routes/Feed.vue`
- [Client data services](https://github.com/nextcloud/news/blob/master/src/dataservices/feed.service.ts): `src/dataservices/feed.service.ts`
- [Vuex state](https://github.com/nextcloud/news/blob/master/src/store/index.ts): `src/store/index.ts`

### HTTP API

- [Route definitions](https://github.com/nextcloud/news/blob/master/appinfo/routes.php): `appinfo/routes.php`
- [Feed endpoints](https://github.com/nextcloud/news/blob/master/lib/Controller/FeedController.php): `lib/Controller/FeedController.php`
- [Item endpoints](https://github.com/nextcloud/news/blob/master/lib/Controller/ItemController.php): `lib/Controller/ItemController.php`
- [REST item API](https://github.com/nextcloud/news/blob/master/lib/Controller/ItemApiController.php): `lib/Controller/ItemApiController.php`

### Feed domain

- [Feed service](https://github.com/nextcloud/news/blob/master/lib/Service/FeedServiceV2.php): `lib/Service/FeedServiceV2.php`
- [Item service](https://github.com/nextcloud/news/blob/master/lib/Service/ItemServiceV2.php): `lib/Service/ItemServiceV2.php`
- [Folder service](https://github.com/nextcloud/news/blob/master/lib/Service/FolderServiceV2.php): `lib/Service/FolderServiceV2.php`
- [Entity mappers](https://github.com/nextcloud/news/tree/master/lib/Db): `lib/Db`

### Background ingestion

- [Feed updater](https://github.com/nextcloud/news/blob/master/lib/Service/UpdaterService.php): `lib/Service/UpdaterService.php`
- [Feed fetcher](https://github.com/nextcloud/news/blob/master/lib/Fetcher/FeedFetcher.php): `lib/Fetcher/FeedFetcher.php`
- **Feed-IO parser**

### Product features

- [OPML and article transfer](https://github.com/nextcloud/news/tree/master/lib/Service): `lib/Service`
- [Item sharing](https://github.com/nextcloud/news/blob/master/lib/Service/ShareService.php): `lib/Service/ShareService.php`
- [Search providers](https://github.com/nextcloud/news/tree/master/lib/Search): `lib/Search`
- [Feed discovery](https://github.com/nextcloud/news/blob/master/lib/Explore/RecommendedSites.php): `lib/Explore/RecommendedSites.php`
- [Podcast playback](https://github.com/nextcloud/news/blob/master/src/App.vue): `src/App.vue`
- [Favicon service](https://github.com/nextcloud/news/blob/master/lib/Controller/FaviconController.php): `lib/Controller/FaviconController.php`

### Other components

- **Reader**
- **Nextcloud database**
- **Nextcloud scheduler**
- **Feed servers**

## Connections

- Reader → Vue application: uses
- Vue application → Reader views: renders
- Vue application → Vuex state: dispatches
- Reader views → Client data services: requests data
- Client data services → Route definitions: calls API
- Route definitions → Feed endpoints: routes feed calls
- Route definitions → Item endpoints: routes item calls
- Route definitions → REST item API: routes REST calls
- Feed endpoints → Feed service: delegates
- Item endpoints → Item service: delegates
- REST item API → Item service: delegates
- Feed service → Entity mappers: reads and writes
- Item service → Entity mappers: reads and writes
- Folder service → Entity mappers: reads and writes
- Entity mappers → Nextcloud database: persists entities
- Nextcloud scheduler → Feed updater: runs jobs
- Feed updater → Feed service: updates feeds
- Feed service → Feed fetcher: fetches feed
- Feed fetcher → Feed-IO parser: parses feed
- Feed fetcher → Feed servers: requests feeds
- Feed service → Item service: updates items
- Route definitions → OPML and article transfer: routes transfers
- Route definitions → Item sharing: routes sharing
- Vue application → Podcast playback: plays enclosure
- Feed endpoints → Feed discovery: discovery support
- Route definitions → Favicon service: routes favicon
- Search providers → Entity mappers: searches entities
