# Hacker News Modern Emacs Client
Fork of [hackernews.el](https://github.com/clarete/hackernews.el) with a modern,
widget-based interface.

Requires Emacs 28.1 or later.
It doesn't actually interact with [Hacker News](https://news.ycombinator.com/)
directly. It uses the [Hacker News API](https://hacker-news.firebaseio.com/v0)
to get the data.
## Differences from hackernews.el
| Feature | hackernews.el | hackernews-modern.el |
|---------|---------------|----------------------|
| Request handling | Synchronous, blocking (~10 seconds) | Asynchronous, non-blocking (~2-3 seconds) |
| Interface | Classic text mode | Widget-based |
## Interface
The interface fetches stories from six different feeds: top, new, best, ask,
show and job. The default feed is top stories, which corresponds to the Hacker
News homepage.
Each story is displayed as a clickable title widget, followed by metadata
(score, comment count, and author) with color coding. The header includes
navigation buttons for switching between feeds and refreshing the current feed.
Content is formatted to a configurable width (default 80 characters). If the
[`visual-fill-column`](https://github.com/joostkremers/visual-fill-column)
package is installed, it will be used to center the content automatically.
Clicking or pressing RET on a story title opens it with
[`browse-url`](https://gnu.org/software/emacs/manual/html_node/emacs/Browse_002dURL.html),
which uses the system default browser. Clicking a comment count opens the
comments page in the same way.
## Keymap
| Key | Description |
|----------------|--------------------------------------------|
| RET | Activate widget at point (open link) |
| n | Move to next story |
| p | Move to previous story |
| TAB | Move to next widget (buttons, links, etc.) |
| m | Load more stories |
| g | Reload stories |
| f | Prompt for a feed to switch to |
| q | Quit |
All feed loading commands accept an optional [numeric prefix
argument](https://gnu.org/software/emacs/manual/html_node/emacs/Arguments.html)
denoting how many stories to fetch. For example,
M-50g reloads the current feed and fetches
its top 50 stories. With no prefix argument, the value of
`hackernews-modern-items-per-page` is used.
## Installation
### use-package with :vc (Emacs 29+)
Recommended method for Emacs 29 and later:
```el
;; Optional but recommended for centering content
(use-package visual-fill-column
:ensure t)
(use-package hackernews-modern
:vc (:url "https://git.andros.dev/andros/hackernews-modern-el"
:rev :newest)
:config
;; Optional: enable emoji icons in the header and comment counts
(setq hackernews-modern-enable-emojis t)
;; Optional: customize display width (default 80)
;; (setq hackernews-modern-display-width 100)
)
```
### use-package with :load-path
For manual installation or Emacs < 29:
```el
(use-package visual-fill-column
:ensure t)
(use-package hackernews-modern
:load-path "/path/to/hackernews-modern-el"
:config
;; Optional: enable emoji icons in the header and comment counts
(setq hackernews-modern-enable-emojis t)
;; Optional: customize display width (default 80)
;; (setq hackernews-modern-display-width 100)
)
```
### Manual
Clone the repository and place the files in a directory on your `load-path`:
```bash
git clone https://git.andros.dev/andros/hackernews-modern-el.git
```
Then add to your `user-init-file`:
```el
;; Add directory to load-path
(add-to-list 'load-path "/path/to/hackernews-modern-el")
;; Load on demand
(autoload 'hackernews-modern "hackernews-modern" nil t)
```
Or, to load it immediately at startup:
```el
(add-to-list 'load-path "/path/to/hackernews-modern-el")
(require 'hackernews-modern)
```
## Usage
Run M-x `hackernews-modern` RET. The feed is determined by
`hackernews-modern-default-feed`, which defaults to top stories. Direct commands for
each feed are also available:
- `hackernews-modern-top-stories`
- `hackernews-modern-new-stories`
- `hackernews-modern-best-stories`
- `hackernews-modern-ask-stories`
- `hackernews-modern-show-stories`
- `hackernews-modern-job-stories`
## Customization
Run M-x `customize-group` RET `hackernews-modern` RET
to list all available options.
Key options:
- `hackernews-modern-items-per-page` (default `20`): Number of stories to fetch per
page.
- `hackernews-modern-default-feed` (default `"top"`): Feed to load on startup.
- `hackernews-modern-display-width` (default `80`): Maximum content width. Content is
centered automatically when `visual-fill-column` is installed.
- `hackernews-modern-enable-emojis` (default `nil`): Show emoji icons in feed buttons
and comment counts.
## Contributing
Contributions are welcome! Please see the [contribution guidelines](https://git.andros.dev/andros/contribute) for instructions on how to submit issues or pull requests.
## License
Copyright (C) 2012-2025 The Hackernews.el Authors
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.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .