# NetNewsWire: a feed reader that tells you exactly which server bug it just fixed

> Brent Simmons's Mac and iOS RSS reader, syncing against a dozen services, with release notes that read as an inventory of third-party API failures.

**Ranchero-Software/NetNewsWire** — RSS reader for macOS and iOS.

- Repository: https://github.com/Ranchero-Software/NetNewsWire
- Website: https://netnewswire.com/
- Stars: 10,450 · Forks: 766
- Language: Swift
- License: MIT
- Published: 2026-10-07 · Updated: 2026-10-07 · Language: en
- Canonical page: https://hysenlabs.com/projects/ranchero-software-netnewswire

## A feed reader that syncs to a dozen services and admits which ones broke

NetNewsWire is a free and open-source feed reader for macOS and iOS, supporting RSS, Atom, JSON Feed and RSS-in-JSON. Format coverage is complete rather than partial, and it matters more than it sounds: Atom in particular is the format most readers support partially, and a partial implementation shows up as duplicated or missing articles rather than an error.

The more interesting work is syncing. The app talks to a long list of third-party services, and the release notes name them: Feedbin, Feedly, NewsBlur, Reader API, FreshRSS, BazQux, Inoreader, and The Old Reader, plus iCloud for people who want sync without a third party.

What makes this repository worth studying is that the maintainer documents third-party failures in public, by service name, in the release notes. The Mac 7.1.4 changelog is the clearest example. It reports a bug where read and starred statuses could stop syncing once more than 999 of them were queued, naming Feedbin, Feedly, NewsBlur and the Reader API. It reports that some FreshRSS, BazQux, Inoreader and The Old Reader articles could never be marked read or starred on the server. It reports that a feed could disappear during syncing when its folder was missing locally, and separately that syncing could skip some folders, both attributed to Feedbin and the Reader API.

That last pair is the kind of bug that would be invisible in a demo. A missing folder is a data-model mismatch between the client and the server, and there is no way to discover it except by hitting the case in production.

## Resilience fixes that describe a queueing system under stress

Reading the 7.1.4 notes closely, a coherent picture of the sync architecture emerges, and it is a batched queue with partial-failure handling. Four separate entries are about not letting one failure stop the rest of a sync: statuses keep syncing even when sending article content fails, article fetching continues after an error sending statuses, the rest of the statuses still go out after one batch fails, and a Feedbin feed no longer disappears when its local folder is missing.

The 999 queued statuses threshold is a detail that tells you more than it appears to. A limit exactly at 999 rather than 1000 or 1024 points at a pagination or batch-size constant interacting badly with something on the server side, quite possibly a query parameter or a rate limit. When a sync silently stops after a large backlog, the observable symptom is that nothing syncs any more, with no error shown, which is about the worst failure mode a sync feature can have.

The iCloud entries tell the same story from the other direction. There is a fix for iCloud syncing stalling on a batch the server considers too large, fixes for potential hangs in iCloud syncing, and a fix making push-triggered iCloud syncing work even when notifications are not authorized. Each of those is a distinct failure of an abstraction the app would like to treat as a dumb blob store.

And there is one more, quieter fix worth highlighting: dates from servers failing to parse under some system languages. That is a locale bug in a date parser, and it is the kind of defect that only appears for users whose Mac is set to a language the developer does not use. The iOS build for the same version had a different problem entirely, a crashing bug introduced in the previous beta.

## A tone in the changelog you do not expect from a sync bugfix

One line in the Mac 7.1.4b3 changelog reads that JavaScript was disabled for Slashdot regardless of the setting, and gives the reason in two words. It is a legitimate engineering decision recorded plainly: a site was executing scripts that produced results the maintainer did not want to render, so the exception list gained a domain.

It is worth sitting with why that is in the release notes at all. Most projects would either fix it quietly or remove the site from their test fixtures. Recording it as a per-domain override, alongside ordinary bug fixes, tells you that the web rendering layer is an ongoing maintenance surface rather than a solved problem. A reader that renders arbitrary remote HTML is running every site's JavaScript against its own WebView, and the failure modes belong to sites it has never heard of.

That entry also suggests the app has a genuinely capable article renderer, since it is worth having a per-site toggle for a single domain. The same beta build fixed a crash that could happen when the app was moved after macOS had run it from a quarantined location, such as the Downloads folder. That is a macOS-specific lifecycle bug involving quarantine state and relocation, and it is the sort of thing that only surfaces on a user's machine.

Neither entry is a criticism of the site or the operating system. They are both examples of a maintainer documenting the boundary conditions of a system that renders untrusted remote content, which is the right place for that documentation to live.

## Building without a paid developer account

The README's build section is unusually practical, and the reason it needs to be is visible: NetNewsWire depends on API keys that cannot live in the repository. Those keys gate iCloud and Feedly accounts and the Reader View, so a local build has some functionality disabled by necessity.

The workaround is a local, gitignored `DeveloperSettings.xcconfig` file that overrides code signing settings, placed in a `SharedXcodeSettings` directory as a sibling of the checkout. The documented contents are the settings that matter:

```bash
CODE_SIGN_IDENTITY = Mac Developer
DEVELOPMENT_TEAM = <Your Team ID>
CODE_SIGN_STYLE = Automatic
ORGANIZATION_IDENTIFIER = <Your Domain Name Reversed>
DEVELOPER_ENTITLEMENTS = -dev
PROVISIONING_PROFILE_SPECIFIER =
```

The README explains the reasoning carefully. This setup keeps the committed Xcode project pristine, with code signing configured for the real developer ID and certificates, while letting each developer hold local settings that never need to be checked in. That separation is the correct pattern for a repository where the released builds need real entitlements and the source builds do not, and it is much better than the common alternative of a shared build settings file that every contributor has to edit locally.

There are two ways to set it up, a bundled `setup.sh` script or manual creation of the directory structure, and the README documents both. The script needs an execution permission change first, which the README covers. The manual route is the one to understand, because it explains what each of those five settings does, including a pointer on where to find your development team ID in Keychain Access and a note that `PROVISIONING_PROFILE_SPECIFIER` should be left empty.

The tree shows the rest of the structure. Platform code splits into `Mac/` and `iOS/` with `Shared/` between them, `Modules/` holds extracted components, `Widget/` is the notification widget, `AppleScript/` exposes app actions to the wider system, and `Themes/` holds presentation. Three test plans exist: a default one plus separate CI and iOS plans. There is a `.swiftlint.yml`, and `buildscripts/`, `scripts/` and `xcconfig/` hold the build plumbing.

## Support policy and contribution process stated up front

Two README sections say more about the project's health than any metric. The first is a link titled How to Support NetNewsWire, with a spoiler immediately after: don't send money. This project is not funded by donations, and it says so on the README rather than burying it.

The second is the pull request policy, and it is the opposite of what most open source repositories ask for. The contributing page asks you to ask before doing a PR, before even starting work, and the README goes further by explaining why the process is that way in the Contributing page. Many maintainers want this and do not say it; the result is contributors spending a weekend on a change that was never going to be accepted. Here it is stated in a sentence a reader cannot miss.

Both of those are markers of a project with an unusual amount of care taken over who interacts with it. The 637 open issues against 10,400 stars is a large number by any measure, and it is worth reading in that light. A project that discourages unsolicited pull requests and does not take donations is not looking to scale its contributor base; it is protecting a codebase it intends to maintain itself.

The community is a Discourse forum at discourse.netnewswire.com, with a code of conduct, and the README is direct that everyone is welcome and encouraged to join, and that members can help by testing, coding, writing or providing feedback. Help with testing is listed first among the ways to contribute, which for an app whose hardest bugs are service-specific sync failures is the most valuable contribution available.

## Conclusion

NetNewsWire is worth reading as an engineering artefact as much as using as an app, because its changelogs document a category of problem that most software hides: third-party APIs that break their own contracts, one service at a time, in ways no test suite catches. The 7.1.4 notes for Mac are a catalogue of exactly that, covering Feedly token handling, FreshRSS and BazQux read-state bugs, folder disappearance during Feedbin syncs, date parsing failures under some system languages, and iCloud sync stalls. If you want an RSS reader, this one supports every feed format and syncs to the services people actually use. If you are building anything against a syncing service, read those notes as a warning about which parts of that API surface you should distrust.

## FAQ

### What is NetNewsWire used for?

Reading RSS, Atom, JSON Feed and RSS-in-JSON feeds on macOS and iOS. It syncs read and starred state, and article content, to third-party services including Feedbin, Feedly, NewsBlur, FreshRSS, BazQux, Inoreader and The Old Reader, as well as to iCloud.

### Is NetNewsWire a good RSS reader?

It is free, open source, and supports every major feed format plus a dozen sync services, which few readers do. The trade-offs are that it is Apple-only, and its release notes show a long tail of service-specific sync bugs that other readers hide. If you are on a Mac or iPhone and want your own sync service rather than a subscription, it is a solid choice.

### Who created NetNewsWire?

Brent Simmons, who is also behind the podcast client Overcast and the MarsEdit editor. The repository is now maintained under the Ranchero-Software organisation, and the README asks contributors to raise issues and pull requests there on GitHub rather than with the author directly.

### Can I build NetNewsWire without a paid Apple developer account?

Yes. The README documents creating a local DeveloperSettings.xcconfig in a SharedXcodeSettings directory as a sibling of the checkout, containing code signing overrides, either through the bundled setup.sh script or by hand. The resulting build has iCloud, Feedly and Reader View disabled, because the API keys for those cannot be shared.

## Sources

- [License: MIT](https://github.com/Ranchero-Software/NetNewsWire/blob/main/LICENSE)
- [Project website](https://netnewswire.com/)
- [Ranchero-Software/NetNewsWire on GitHub](https://github.com/Ranchero-Software/NetNewsWire)
- [README](https://github.com/Ranchero-Software/NetNewsWire/blob/main/README.md)
- [Releases](https://github.com/Ranchero-Software/NetNewsWire/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/ranchero-software-netnewswire
