NAME

noss - RSS/Atom feed reader and aggregator

SYNOPSIS

noss command syntax:

noss <command> [options] [arguments]

Commands:

update    Fetch and reload feeds
reload    Reload cached feeds
read      Read post in pager
open      Open feed or post URL in browser
cat       Print post to stdout
list      List and filter posts
unread    List unread posts
mark      Mark posts as read or unread
post      View post information
feeds     List feeds
groups    List feed groups
clean     Clean up obsolete files and data
export    Export feed list as OPML
import    Import feed list from OPML
help      View documentation for a noss command

Global options:

-c|--config=<file>       Specify path to configuration file
-D|--data=<dir>          Specify path to data directory
-f|--feeds=<file>        Specify path to feeds file
-z|--time-format=<fmt>   Specify default strftime format for time strings

-h|--help      Print usage message
-v|--version   Print version and copyright information

DESCRIPTION

noss is a command-line program for aggregating and reading RSS/Atom feeds. noss can fetch feed updates, list posts, read posts from the command-line, open posts in a browser, and much more.

noss works by storing feed and post information in a local database, and the user interacts with the database by supplying commands to noss.

noss requires a feed list in order for it to function. A feed list is supplied to noss via a feeds file, a file that contains a list of feeds and any special configuration to use for those feeds. The format of this file is documented in the subequent "Feeds File" section of this manual. Once a list of feeds is supplied to noss through the feeds file, the feeds can then be fetched and loaded into its database via the update command.

In order for noss to read posts, it must be able to uniquely identify and distinguish posts from each other. Posts in noss are identified via two pieces of information: the name of the feed they're in and their unique ID within that feed. When reading a post, like with either the read or open command, you would typically supply the command with the feed name and post ID to refer to that specific post.

# Read post #1 in the PlanetDebian feed
noss read PlanetDebian 1

To determine the feed and ID of a post, the list command can be used to query the post database for a list of posts that conform to whatever search parameters are provided (like title containing a string, content matching a regex, being tagged with a specific tag, etc.). The post command can also be used to query more detailed post information than the list command provides for a specific post. Consult the documentation for the list and post commands in the "COMMANDS" section of this manual.

So basically, the typical usage of noss would involve managing your feed list from the feeds file, using the update command to fetch feed updates, using the list command to see what posts are available, and then using read or open commands for actually reading posts.

# Add your feeds
vim ~/.config/noss/noss.feeds

# Fetch and update feed updates
noss update

# Look to see what posts you have
noss list
# ...or only check for unread ones
noss unread

# And then actually reading a post
noss read whatever 12

The "COMMANDS" section of this manual documents the complete list of commands and any options that are available to them.

noss can also have its behavior modified through a configuration file, whose format is documented in the "CONFIGURATION" section of this manual.

Feeds File

As previously mentioned, noss reads its feed list from a feeds file. The feeds file is a JSON file that contains a list of feeds, feed groups, and feed configurations for noss to use. noss uses a special JSON format that supports comments and trailing commas, so that it can be better suited as a configuration file format. Comments start with a hash (#) sign, are terminated by the end of a line, and can be placed anywhere where JSON allows whitespace.

noss will look for a feeds file in the following locations:

Path specified by the -f|--feeds option
$NOSS_FEEDS
$XDG_CONFIG_HOME/noss/noss.feeds
$XDG_CONFIG_HOME/noss.feeds
~/.config/noss/noss.feeds
~/.config/noss.feeds
~/.noss.feeds

The feeds file can have three different fields: feeds, groups, and default. The only required field is the feeds field.

feeds

The feeds field is a key-value map of feed names and their configuration. Feed names can only contain alphanumeric/underscore characters, and must not be the name of another feed or group. The feed can either be mapped to a URL string of the feed it represents or a key-value map of configuration parameters for the feed. The former has the benefit of better readability but lacks the ability to have its configuration fine-tuned. The latter can have fine-tuned configuration but may look more cluttered than the former.

{
  "feeds": {
    # Just the URL, no specific configuration
    "feed1": "https://phonysite.com/feed1.rss",
    # Key-value map allows for fine-tuned configuration
    "feed2": {
      "feed": "https://phonysite.com/feed2.rss",
      "limit": 100,
      "autoread": false,
    },
  }, # yes, you can have trailing commas :-)
# yes, you can have comments, too!
}

When using the latter-style key-value map syntax for a feed, the only required field is the feed field, which must store the feed's URL. Additional fields, which are listed below, can be set to provide the previously mentioned fine-tuned configuration.

"limit": integar

Specify a limit to the number of posts a feed can contain. If a feed exceeds the limit, noss will discard older posts to fit into that limit. By default, there is no limit to the number of posts a feed can contain.

"respect_skip": bool

Specify whether to respect the skipDays and skipHours fields in RSS feeds, which tells feed aggregators to skip updating feeds on certain hours or days. This is enabled by default, and is recommended to not be disabled.

"include_title": "target" | [ "target", ... ]
"exclude_title": "target" | [ "target", ... ]

Specify a target string or list of target strings a post title must include or not include in order to not be filtered out by noss during aggregation. A target string can either be a literal string that a post title must include/exclude, or a Perl regex (signified by a leading and trailing forward slash character) that a title must match/not match.

"include_content": "target" | [ "target", ... ]
"exclude_content": "target" | [ "target", ... ]

Similar to the include_title and exclude_title parameters, except for a post's content instead of its title.

"include_tags": "tag" | [ "tag", ... ]
"exclude_tags": "tag" | [ "tag", ... ]

Specify a tag or list of tags that a post must be tagged with or without in order to not be filtered out by noss during aggregation.

"autoread": bool

Specify whether new posts from this feed should automatically be marked as read or not. Defaults to false.

"default_update": bool

Specify whether this feed should be included in a default update or not (update when ran with no arguments). Defaults to true.

"hidden": bool

Specify whether this feed should be omitted from the list command's default listing (the list shown when ran with no arguments). Defaults to false.

A feed's specific configuration takes priority over the configuration it may inherit from the default field or any groups it may be a part of.

noss uses curl(1) for fetching feeds, so generally any URL that is acceptable for curl(1) will be acceptable for noss. There are two unique types of URLs that noss will process in a special way.

file:///path/to/file

A URL that starts with the file:// protocol will be interpreted as a local file which noss will copy over to its feed cache and load instead of fetching remotely via curl(1).

# Use the contents of "/home/sam/feeds/feed.rss" as a feed
"file_feed": "file:///home/sam/feeds/feed.rss"
shell://command

A URL that starts with the shell:// protocol will be interpreted as a shell command which noss will execute and capture the output of, then use that output as the contents of the feed.

# Use the output of the "cat feed.rss" command as a feed
"shell_feed": "shell://cat feed.rss"

groups

groups is a key-value map of group names and their configuration. Feed groups in noss serve two purposes: 1) to provide a way to logically group multiple feeds together, and 2) provide a way to "share" a common configuration between multiple different feeds.

Just like with feeds, group names can only contain alphanumeric/underscore characters and cannot be the same name as any other group or feed. A group can either be defined by a list of feed names with no special configuration, purely acting as a logical collection of feeds, or a key-value map of feed configuration parameters with a feed list stored in the feeds field of the map. The same options listed above for a feed's configuration in the feeds field can be used for a group's configuration.

{
  "groups": {
    # purely logical feed grouping, no special configuration
    "group1": [ "f1", "f2", "f3" ],
    # each feed will inherit group2's configuration
    "group2": {
      "feeds": [ "f2", "f4", "f6" ],
      "limit": 100,
      "autoread": false,
    },
  },
  "feeds": {
    ...
  },
}

Feeds are also allowed to be a part of multiple different groups. If a feed is a part of multiple different groups that try to configure the same parameter, noss will try to resolve the conflict by picking the most "non-default" option available. Group configurations take priority over the default field but are overridden by a feed's own configuration.

default

The default field is a special feed group that every feed is a part of. Any configuration in the default feed will used by every feed and group (unless their configuration overrides the default's). The same configuration options available to a feed and group are available to default.

{
  # All feeds have a limit of 100 posts and must contain 'foo' in their
  # titles.
  "default": {
    "limit": 100,
    "include_title": [ "/foo/" ],
  },
  ..
}

COMMANDS

update

noss update [feed|group] ...

Fetch and reload feeds. Whenever a new feed is added to noss's feed list, this command can be used to load it into noss's database.

If no specific feeds or groups are specified, all feeds are updated.

update has the following options:

--new-only

Only update feeds that are not present in the database.

--non-defaults

When running update with no arguments, update all feeds, even those that are configured to not be updated by default.

--downloads=num

Specify number of parallel downloads to perform. Default amount is 10.

Can also be configured via the downloads configuration field.

--unconditional

Unconditionally download feeds, even if they have not been modified since the last update. This option should be used with caution, as performing unconditional downloads is wasteful on feed servers and considered bad practice.

--limit-rate=speed

Specify the maximum transfer rate for downloads. Speeds are measured in bytes/second, unless a suffix is appended. k/K, m/M, and g/G correspond to kilobytes, megabytes, and gigabytes respectively.

Can also be configured via the limit_rate configuration field.

--user-agent=agent

Specify the string to use as the user-agent string.

Can also be configured via the user_agent configuration field.

--timeout=fractional second

Specify the maximum number of seconds a transfer is allowed to take.

Can also be configured via the timeout configuration field.

--proxy=[protocol://]host[:port]

Specify the proxy server to use. If a protocol is not specified, defaults as a http:// proxy. If no port number is specified, defaults to 1000.

Can also be configured via the proxy configuration field.

--proxy-user=user:password

Specify the username and password to use for proxy authentication.

Can also be configured via the proxy_user configuration field.

reload

noss reload [feed|group] ...

Reload cached feeds. Useful for when you make changes to a feed's configuration and want noss to recognize the changes. If no feeds are specified, reloads all cached feeds.

reload has no unique options.

read

noss read <feed> [post]

Read the specified post's contents from the specified feed via a pager. If no specific post is provided, the latest unread post in the feed is selected.

read has the following options:

--pager=command

Use the specified command as the pager for reading the post's contents. Defaults to less(1) on Unix systems and more(1) on Windows systems.

Can also be configured via the PAGER environment variable and pager configuration field.

--no-mark

Do not mark post as read.

--stdout

Instead of reading post via a pager, write the post's formatted contents to stdout.

--read-format=fmt

Specify the format for the post's HTML contents that noss will format when reading. fmt is a string that consists of formatting codes which will be substituted by noss for whatever information the code represents. A formatting code starts with a percentage sign, followed by an optional integar specifying the pad width, and a character signifying what the code is actually formatting. If the pad width is negative, the text will be left-justified. See also the read_format configuration option.

The format string can use the following formatting codes:

%%

A percentage sign.

%f

The name of the feed the post is in.

%i

The ID of the post.

%t

The title of the post.

%u

The URL of the post.

%a

The name of the author of the post.

%c

The list of categories the post is tagged under.

%s

A single character signifying the post's read status (r for read, U for unread).

%S

The post's read status, read or unread.

%P

The HTML contents of the post.

%C

The date of the post in the preferred date/time representation of the current locale.

%d

The post's day of the month as a decimal number (range 01 to 31).

%w

The post's abbreviated day of the week according to the current locale.

%W

The post's full day of the week according to the current locale.

%m

The post's abbreviated month name according to the current locale.

%M

The post's full month name according to the current locale.

%n

THe post's month as a decimal number (range 01 to 12).

%y

The post's year in two-digit form (range 00 to 99).

%Y

The post's full year.

%z

The post's time formatted according to the --time-format option or time_format configuration field.

--width=width

Specify the line width to use for the formatted text output. Defaults to 80. See also the line_width configuration field.

--html

Instead of reading the formatted contents of a post, read its unformatted HTML contents.

cat

noss cat <feed> [post]

Prints the specified post to stdout. This command is basically just an alias to read --stdout. If no post is specified, prints the latest unread post.

This command has the same options as the read command.

open

noss open <feed> <post>
noss open <feed>

Open the URL of the specified feed or post in a web browser.

open has the following options:

--browser=command

Use the specified command as the browser to use for opening the URL. Defaults to lynx(1).

Can also be configured via the BROWSER environment variable and browser configuration field.

--no-mark

Do not mark post as read.

list

noss list [feed|group] ...

List posts from specified feeds. When listing posts, noss displays the post's read status, the name of the feed the post is a part of, the post's ID, and the title of the post. Each post is listed on a single line, which should make it easy to process in a pipeline.

If no feeds or groups are specified, all feeds are searched.

list has the following options:

--title=target

Only list posts containing the specified target string in their title. If the string starts and ends with a forward slash (/), list will interpret it as a Perl regex and search for posts whose titles match the given regex.

--tag=tag

Only list posts tagged with the specified tag. This option can be used multiple times to specify multiple different tags.

--status=status

Only list posts marked with the specified status. Valid values are read and unread.

--content=target

Only list posts containing the specified target string in their HTML content. If the string starts and ends with a forward slash (/), list will interpret it as a Perl regex and search for posts that match the given regex. This option can be used multiple times to specify multiple different targets.

--sort=method

Sort post list by the given method. The following are valid methods:

date

Sort posts by date (default).

feed

Sort posts by feed.

title

Sort posts by title.

This option can also be configured via the sort configuration field.

--reverse

Print the post list in reverse order.

--list-limit=limit

Only list the first limit posts. When used with the --reverse option, shows the last limit posts. If limit is less than or equal to 0, there is no limit. By default, there is no limit. This option can also be configured via the list_limit configuration field.

--hidden

Show hidden feeds when using list with no arguments.

--list-format=fmt

Print post information using the specified format. This option works just like the --read-format option in the read command. Consult its documentation for how formatting works and list of valid formatting codes.

unread

noss unread [feed|group] ...

Similar to the list command, except only shows unread posts.

This command has the same options as the list command.

mark

noss mark <status> <feed|group> [posts] ...
noss mark --all <status>

Mark the given posts in the specified feeds as read or unread.

posts is a list of post IDs to mark as read. If a post argument is a range (from-to), then each post in that range is marked. posts can only be specified when marking posts in individual feeds, not when marking groups of feeds.

This command has the following options:

--all

Mark all posts in every feed as read or unread.

post

noss post <feed> <post>

View the post information for the specified post.

This command has the following options:

--post-format=fmt

Specify the format to use for printing post information. Consult the documentation for the read command's --read-format option for information on how formatting works and a list of valid formatting codes.

feeds

noss feeds [feed|group] ...

View feed information for specified feeds and/or groups. If no feeds are specified, prints information for all feeds.

This command has the following options:

--brief

Only print feed names, not additional feed info.

--feeds-format=fmt

Specify the format to use for printing feed information. Consult the documentation for the read command's --read-format option for information on how format strings are processed.

The following format codes are available:

%%

A percentage sign.

%f

The feed's name.

%l

The feed's link.

%t

The feed's title

%u

The feed's homepage.

%e

The feed's description.

%a

The feed's author.

%c

The feed's tags.

%p

The number of posts in the feed.

%r

The number of read posts in the feed.

%U

The number of unread posts in the feed.

%C
%d
%w
%W
%m
%M
%n
%y
%Y
%z

The same as their post formatting counterparts.

groups

noss groups [groups] ...

View group information. If no groups are specified, prints information for all groups.

This command has the following options:

--brief

Only print group names, not additional group info.

clean

noss clean

Cleans up obsolete cache files and database data.

This command has no unique options.

export

noss export [opml]

Export feed list as an OPML file for transferring feed data to another feed reader. If no output file is specified, the OPML will be written directly to stdout.

This command has the following options:

--no-groups

Do not try to generate feed group structures in the exported OPML.

--export-special

By default, export does not export feeds that use special noss-specific URLs like shell:// or file:// feeds. This option disables that behavior.

import

noss import <opml> [json]

Import feed list from an OPML file. Will write the feed list as a JSON file which can be used by noss. Writes the feed file to json if specified, otherwise writes it directly to stdout.

This command has the following options:

--no-groups

Do no try to import feed groups from the OPML.

help

noss help [command]

Print documentation for the specified command. If no command is specified, the noss manual will be printed instead.

This command has no unique options.

GLOBAL OPTIONS

These options can be used with any command.

-c|--config=file

Specify path to the noss configuration file.

-D|--data=dir

Specify path to the noss data directory. The data directory is the directory where noss stores data like its feed database and feed cache.

-f|--feeds=file

Specify path to the noss feeds file.

-A|--autoclean[=0|1]

Toggle whether noss should automatically run the clean command after any operation. 0 disables autoclean, 1 enables it. Giving no argument is the equivalent to enabling autoclean. This command helps with automatically freeing up unused space at the cost of a slight performance penalty. By default, autoclean is disabled. This option can also be configured via the autoclean configuration field.

-z|--time-format=fmt

Specify the time format to use for the %z formatting code. strftime(3) is used to perform the time formatting, so consult its manual for writing a format string. See also the time_format configuration field.

%z is the default formatting code used by the feed and post commands, so this option will also affect their output.

If this option is not set, %z will default to the %c strftime(3) formatting code.

-h|--help

Print noss's usage message and exit.

-v|--version

Print noss's version and copyright info, then exit.

CONFIGURATION

noss can have its behavior configured by writing it a configuration file. A noss configuration file is a JSON file that supports the same extensions as the feeds file (comments and trailing commas).

noss will look for a configuration file in the following locations:

Path specified by the -c|--config option
$NOSS_CONFIG
$XDG_CONFIG_HOME/noss/noss.conf
$XDG_CONFIG_HOME/noss.conf
~/.config/noss/noss.conf
~/.config/noss.conf
~/.noss.conf

A noss configuration file can contain the following fields:

"feeds": "path"

Path to feeds file. See also the -f|--feeds option.

"data": "dir"

Path to use for the data directory. See also the -D|--data option.

"downloads": integar

Number of parallel downloads to perform when fetching feeds for the update command. See also the update command's --downloads option.

"limit_rate": "speed"

The maximum transfer rate for downloads. speed follows the same format as the speed given to the --limit-rate option.

"user_agent": "agent"

The string to use as user-agent string for downloads. See also the update command's --user-agent option.

"timeout": fractional second

The maximum number of seconds a transfer is allowed to take. See also the update command's --timeout option.

"proxy": "[protocol://]host[:port]"

The proxy server to use for performing downloads. The proxy host string follows the same format as one used in the update command's --proxy option.

"proxy_user": "user:password"

The username and password to use for proxy authentication. Follows the same format as the one used in the update command's --proxy-user option.

"pager": "command"

The command to use for reading posts via the read command. See also the read command's --pager option.

"browser": "command"

The command to use for opening URLs.

"sort": "method"

How you would like the list command to sort posts. Valid methods are date, feed, and title. See also the list command's --sort option.

"list_limit": limit

Limit the number of posts that are listed with the list command. If limit is less than or equal to 0, there is no limit. See also the list command's --list-limit option.

"line_width": width

The line width to use for the formatted text output of the read command. See also the read command's --width option.

"read_format": "fmt"

The format to use for the HTML contents of a post that noss will format for the read command. See the documentation for the read command's --read-format option for more information on the details of how text formatting works.

"list_format": "fmt"

The format to use for posts in the list command. See also the list command's --list-format option.

"post_format": "fmt"

The format to use for the post information printed in the post command. See also the post command's --post-format option.

"feeds_format": "fmt"

The format to use for feed information printed in the feeds command. See also the feeds command's --feeds-format option.

"autoclean": bool

Boolean determining whether noss should automatically run the clean command after performing any operation. See also the --autoclean option.

"time_format": "fmt"

The strftime(3) format string to use for formatting %z times. See also the --time-format option.

NOSSUI

For Unix-like systems, noss also comes with a script called nossui(1), which is a dialog(1)-based frontend that provides a terminal user interface for noss. Not all of the functionality of noss is available through nossui(1), so it shouldn't be used as a complete replacement for noss, but it should be suitable for most of noss's routine usage.

ENVIRONMENT

NOSS_DATA

Directory for noss to store program data in.

NOSS_CONFIG

Path to noss's configuration file.

NOSS_FEEDS

Path to noss's feeds file.

XDG_DATA_HOME

Directory for noss to store its data directory in, if no data directory path is configured otherwise.

XDG_CONFIG_HOME

Directory where noss looks for configuration in by default.

PAGER

Default pager to use for the read command.

BROWSER

Default browser to use for opening URLs.

CAVEATS

Updating a feed too frequently can be wasteful on a server's resources, and in extreme cases could result in them banning you from accessing their feed. The acceptable frequency of feed updates varies from server to server, but a good rule of thumb is once per hour at most. You should also refrain from using the --unconditional option without a good reason.

AUTHOR

Written by Samuel Young, <samyoung12788@gmail.com>.

This project's source can be found on its Codeberg page. Comments and pull requests are welcome!

COPYRIGHT

Copyright (C) 2025 Samuel Young

This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

SEE ALSO

nossui(1), curl(1), less(1), lynx(1), more(1), sqlite3(1), strftime(3)