Furst/README.md
nak0x b1d052fc79 Make the reader the default route and document the toolset
The catch-all rule now sends anything that did not match a more specific
rule to furst-serve, while `default` stays a plain browser. Because rules
fall through when their command is missing, that arrangement needs no new
mechanism: if furst-serve is not installed the reader rule is skipped and
the browser still gets the URL.

Firefox drops to a short list of sites that genuinely need it. Every reader
page carries a browser link, so the list can stay short.

Adds a README for furst-serve and rewrites the top-level one around the
whole pipeline: what it is for, what each piece does, measured output
sizes, and the limits — client-rendered pages, rate-limited search
endpoints, DRM.
2026-09-06 20:10:11 +02:00

104 lines
4.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# furst
A toolset for browsing the modern web on hardware that cannot run a modern
browser. Built for a Core2 Duo with 4GB of RAM and a minimal Arch install,
where Firefox is the bottleneck.
## The idea
A news page is 25MB across 80+ requests with 13MB of JavaScript to parse and
JIT. The same article, extracted, is ~20KB. Choosing a lighter browser engine
buys 23×. **Not loading the payload at all buys considerably more.**
So the goal is not a faster browser. It is to keep a browser engine out of the
loop wherever possible, and to make the cases where you still need one rare and
deliberate.
```
link click
┌────▼─────┐ video ──────────────► mpv (H.264 forced)
│ furst │ pdf / image ────────► zathura / nsxiv
│ router │ mailto / magnet ────► xdg-email / transmission
└────┬─────┘ a short "heavy" list ► firefox
▼ everything else
┌──────────────┐ ┌──────────────┐
│ furst-serve │───────►│ furst-read │ fetch → extract → render
│ local reader │ │ library │
└──────┬───────┘ └──────────────┘
│ minimal HTML, no JS/CSS/fonts, links rewritten to stay inside
a light browser (surf, luakit, …)
```
## The pieces
| | |
|---|---|
| [`furst`](src/) | the router. Sits where the default browser used to and dispatches each URL to the cheapest tool that can handle it. Two dependencies, 541K binary. |
| [`furst-read`](furst-read/README.md) | fetch, extract the article, render it as a self-contained document. Library and CLI. |
| [`furst-serve`](furst-serve/README.md) | the local reader. Rewrites in-page links so browsing stays in reader mode, caches pages, and handles what extraction cannot: search, feeds, listings, comment threads. |
## Install
```sh
cargo build --release --workspace
install -Dm755 target/release/furst target/release/furst-read \
target/release/furst-serve -t ~/.local/bin/
furst --init # rules tuned for low-end hardware
furst --install # become the system default browser
furst-serve --init # home page links and feeds
sudo pacman -S mpv yt-dlp zathura zathura-pdf-mupdf nsxiv surf
```
Then every link click in every application goes through the router, and most
of them never reach a browser engine.
## Measured
| page | raw HTML | scripts | stylesheets | through furst |
|---|---|---|---|---|
| wiki.archlinux.org/title/Zram | 64K | 4 | 2 | 16K |
| en.wikipedia.org/wiki/Core_2 | 207K | 5 | 2 | 47K |
| theverge.com | 770K | 55 | 71 | 2.4K |
| lwn.net headlines (feed) | — | — | — | 11K, 15 entries |
The HTML column understates it. The script and stylesheet columns are the real
story: those become zero, along with every webfont and tracker, which is where
an old CPU actually spends its time. A cached revisit is ~0.4ms.
## Two details that matter on this hardware
**Video is forced to H.264.** A Core2 handles 720p `avc1` in software but
stalls on VP9 and AV1, which is what YouTube serves by default. The format
string in the `video` rule is doing more work than the resolution cap, and
playing it in mpv skips the browser entirely.
**The reader is the catch-all, not a special case.** Rules fall through when
their command is missing, so the last rule can be "send it to the reader" while
`default` stays a plain browser. Firefox is left for a short list of sites that
genuinely need it — and every reader page has a **browser** link for the rest.
## Limits
- Anything that renders client-side arrives empty. There is no JavaScript here;
that is the point, not an oversight.
- Free search endpoints rate-limit repeat visitors. The reader detects a
challenge page and tells you which engine refused, rather than showing an
empty list. See [furst-serve](furst-serve/README.md#on-search).
- Paywalls and DRM are not defeated, only rendered plainly or handed off.
## Development
```sh
cargo test --workspace # note: --workspace, the root package is just furst
cargo clippy --workspace --all-targets
```
## License
MIT