w3m
A text-focused browser that renders web pages in a terminal.
w3m runs in a text-only environment, so it supports neither CSS nor JavaScript. It does support a good deal else: bookmarks, cookies, forms, and HTTPS.
It’s open source, originally written by Akinori Ito, with new features and maintenance since handled by Tatsuya Kinoshita for the Debian project and a modest list of contributors. Debian seems to be the main thing keeping it maintained.
Using w3m
w3m is good for focused, distraction-free reading. Small-web and independent sites tend to have far better support for it, and for JavaScript-free browsing generally. It’s also good on lower-powered machines, including ones that render a desktop environment perfectly well but cannot cope with what a modern mainstream browser demands.
It’s useful over SSH while doing maintenance on a remote server, when you want to look up a command or a configuration option without leaving the session.
It’s also often used to display HTML email in Mutt. A lot of mail now arrives with no plain-text alternative. Most of that comes from marketers and can simply be ignored, but mail from Apple’s client frequently has no text version either, and w3m renders it well.
Daily-Driving w3m
With bookmarks, HTTPS, and cookies, w3m is perfectly capable of being a primary browser. The catch is that most pages have never been tested in it, so layouts can be hard to read.
DuckDuckGo works well for search. Google mostly works too, if you don’t mind it rewriting every result as a tracking link.
Image Support
Although it’s a console browser, w3m can display images using sixels in terminals that support them.
If there are images you’d rather w3m showed as alt text, configure the web server to return a 403 for them when w3m is the one asking. Here’s how I do it in Nginx for the logos in my site’s header and footer:
location ~* ^/(aicned|argat|attrab|feth|gael|slaine|scribble).png$ {
if ($http_user_agent ~* "w3m") {
return 403;
}
}
Developing with w3m in Mind
w3m has good support for HTML tables, so channeling your 90s-era web design skills and relaxing any dogma about semantic HTML just a bit goes a long way. When using a structural tag for presentational purposes, add role="none" or role="presentation" so browsers know not to assign it meaning.
For some interfaces I wrap the whole page in a <center> tag and then a <table>. I like to keep long lines to a reasonable length, and a width of 624 on the wrapping <table> holds lines to roughly 72 characters, which is comfortable. Use a <tbody>, because modern graphical browsers inject one into the DOM whether or not you wrote it. To make those presentational tags disappear for browsers that don’t need them, give them display: contents.