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.
104 lines
4.2 KiB
Markdown
104 lines
4.2 KiB
Markdown
# 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 2–5MB across 80+ requests with 1–3MB of JavaScript to parse and
|
||
JIT. The same article, extracted, is ~20KB. Choosing a lighter browser engine
|
||
buys 2–3×. **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
|