Skip to content
hn

Output formats

The output contract every command shares: formats, fields, and templates.

Every command renders through one formatter, so the same flags work everywhere. Pick a format with -o, or let hn choose: a table when writing to a terminal, JSONL when piped.

Formats

hn top -o table   # aligned columns for reading
hn top -o jsonl   # one JSON object per line, for piping
hn top -o json    # a single JSON array
hn top -o csv     # spreadsheet friendly
hn top -o tsv     # tab-separated
hn top -o url     # just the link for each record
hn top -o raw     # the bare field values, space-separated, no header
Format Best for
table Reading on a terminal
jsonl Piping into another tool, one object at a time
json Loading a whole result as an array
csv / tsv Spreadsheets and quick column math
url Feeding links into other commands
raw Bare values for cut, awk, and friends

A note on the two JSON formats: json prints an array, except when there is a single record, where it prints that one object. jsonl always prints one object per line, which is what you want in a stream.

The url format prints each record's url, falling back to hn_url when a record has no external link (Ask HN posts, most jobs, and comments).

Narrowing columns

Keep only the fields you want, in the order you list them:

hn top --fields rank,score,title
hn item 48517377 --depth -1 --fields depth,by,text

The field names are the JSON keys you see in jsonl output. --no-header drops the header row in table, csv, and tsv, which helps when a downstream tool expects bare rows.

Templating rows

For full control over each line, apply a Go text/template. The fields are the lowercase JSON keys:

hn top --template '{{.score}}  {{.title}}'
hn top --template '{{.by}} -> {{.hn_url}}'

A join function is available for any list-valued field:

hn top --template '{{join "," .fields}}'

Why auto-detection helps

Because the default adapts to the destination, the same command reads well by hand and parses cleanly in a pipe:

hn top            # a table, because this is a terminal
hn top | wc -l    # JSONL, because this is a pipe

You only reach for -o when you want something other than that default.