[HN Gopher] Show HN: Chawan TUI web browser
       ___________________________________________________________________
        
       Show HN: Chawan TUI web browser
        
       A terminal-based web browser in Nim.[1] Has acceptable (YMMV) CSS
       rendering, some JS support, and inline images (sixel/kitty). It can
       also use various protocols other than http(s) such as (s)ftp,
       gopher, gemini, ...  Chawan started out as a w3m clone, and the UI
       still resembles it. However, the architecture has turned out quite
       different, with pages loaded in separate processes, and
       protocol/file type handling separated out into external binaries.
       An interesting result is that you can even register decoders for
       custom inline image formats, although practical use cases of this
       are rather minimal.  There is a gallery showcasing some websites
       being rendered here: https://chawan.net/gallery/index.html  [1]:
       https://nim-lang.org
        
       Author : shiomiru
       Score  : 372 points
       Date   : 2025-06-16 20:48 UTC (1 days ago)
        
 (HTM) web link (chawan.net)
 (TXT) w3m dump (chawan.net)
        
       | hecanjog wrote:
       | I love this browser, thank you for building it!
        
         | shiomiru wrote:
         | Glad you like it :)
        
       | marcodiego wrote:
       | GPM support?
        
         | shiomiru wrote:
         | No GPM yet, but it does recognize XTerm's mouse protocol.
        
       | etaioinshrdlu wrote:
       | I rabbit-holed a little and apparently Chrome and Safari no
       | longer even fully pass Acid2 and Acid3?
        
         | ataylor32 wrote:
         | Here is a relevant discussion:
         | https://news.ycombinator.com/item?id=15256890
        
       | ijustlovemath wrote:
       | My jaw dropped when HN loaded first try from Termux! Nice work!
        
         | shiomiru wrote:
         | Thanks :)
         | 
         | If you're interested, I posted a user style for HN here:
         | https://lists.sr.ht/~bptato/chawan-devel/%3CD9S40OS2QWHL.PXQ...
         | 
         | Mainly just to fix the vote arrows, because for now background-
         | image only renders placeholders.
        
       | corv wrote:
       | Awesome and in Nim!
        
       | agumonkey wrote:
       | as a tiny web fan, it's lovely to see projects like these,
       | *claps*
        
       | greenspam wrote:
       | Finally a good tool to view HN in terminal. Thank you! Where can
       | I find the keyboard shortcuts? I can move with vim key binding,
       | but can go back.
        
         | shiomiru wrote:
         | cha-config(5) or about:chawan. The former also has an online
         | version: https://chawan.net/doc/cha/config.html#pager-actions
         | 
         | For navigation in particular you'd use capital D to discard the
         | current buffer and return to the previous page. There's also ,
         | (comma, back) and . (period, forward), which non-destructively
         | cycle through the stack.
         | 
         | (Well, it's really a tree, but the UI mostly treats it as a
         | stack.)
        
           | greenspam wrote:
           | Thank you so much!
        
       | mikeponders wrote:
       | Gotta love Nim
        
       | elcritch wrote:
       | I recommend perusing the code. Since it's in Nim it's pretty
       | approachable (and performant). There's still lots of gnarly bits
       | like implementing HTML DOM and web specs, but it doesn't take you
       | days to grasp the basic setup.
        
       | isaacvando wrote:
       | This is super cool! Bravo. Awesome to see it written in Nim too.
       | 
       | When I do `cha example.com` I can't figure out how to use any of
       | the commands (hjkl, etc). The only keys I've found that have any
       | effect are typing numbers which show up in the bottom left.
       | Haven't figured out how to do anything with those. Am I missing
       | something obvious about how to use this or could this be a bug?
       | 
       | I built from source on MacOS Sequoia 15.5 Apple Silicon using Nim
       | 2.24. Pages load correctly, I just can't get the commands to
       | work. Thanks!
        
         | isaacvando wrote:
         | I tried it in Ghostty, iTerm2, and Terminal.app and they all
         | behaved the same.
        
           | shiomiru wrote:
           | It's a bug, thanks for reporting. I've created a ticket:
           | https://todo.sr.ht/~bptato/chawan/63
           | 
           | Could you please pull the macos-input branch from
           | https://git.sr.ht/~bptato/chawan and report back on what the
           | `a` file includes after opening a site and typing some
           | commands? (Should be created in the current working
           | directory.)
        
             | isaacvando wrote:
             | Here's the contents of a. Let me know if there are any
             | other commands you'd like me to type.
             | 
             | ``` handleCommandInput 1, buffer "" c 'j'
             | handleCommandInput 2, buffer "" c 'j' after
             | handleCommandInput, buffer 0x104c5b780"j" c 'j'
             | handleCommandInput 1, buffer "" c 'k' handleCommandInput 2,
             | buffer "" c 'k' after handleCommandInput, buffer
             | 0x104ca8b70"k" c 'k' handleCommandInput 1, buffer "" c 'l'
             | handleCommandInput 2, buffer "" c 'l' after
             | handleCommandInput, buffer 0x104c5bab0"l" c 'l'
             | handleCommandInput 1, buffer "" c 'k' handleCommandInput 2,
             | buffer "" c 'k' after handleCommandInput, buffer
             | 0x104ca8d20"k" c 'k' handleCommandInput 1, buffer "" c 'j'
             | handleCommandInput 2, buffer "" c 'j' after
             | handleCommandInput, buffer 0x104c5b480"j" c 'j'
             | handleCommandInput 1, buffer "" c 'h' handleCommandInput 2,
             | buffer "" c 'h' after handleCommandInput, buffer
             | 0x104ca89c0"h" c 'h' handleCommandInput 1, buffer "" c 'g'
             | handleCommandInput 2, buffer "" c 'g' after
             | handleCommandInput, buffer 0x104cae780"g" c 'g'
             | handleCommandInput 1, buffer "" c '1' after
             | handleCommandInput, buffer "" c '1' handleCommandInput 1,
             | buffer "" c '2' after handleCommandInput, buffer "" c '2'
             | handleCommandInput 1, buffer "" c '3' after
             | handleCommandInput, buffer "" c '3' handleCommandInput 1,
             | buffer "" c '1' after handleCommandInput, buffer "" c '1'
             | handleCommandInput 1, buffer "" c '2' after
             | handleCommandInput, buffer "" c '2' handleCommandInput 1,
             | buffer "" c '2' after handleCommandInput, buffer "" c '2'
             | handleCommandInput 1, buffer "" c '3' after
             | handleCommandInput, buffer "" c '3' handleCommandInput 1,
             | buffer "" c '\3' handleCommandInput 2, buffer "" c '\3'
             | after handleCommandInput, buffer 0x104cae690"\3" c '\3'
             | handleCommandInput 1, buffer "" c '\3' handleCommandInput
             | 2, buffer "" c '\3' after handleCommandInput, buffer
             | 0x104adaed0"\3" c '\3' handleCommandInput 1, buffer "" c
             | '\3' handleCommandInput 2, buffer "" c '\3' after
             | handleCommandInput, buffer 0x104ca8720"\3" c '\3'
             | handleCommandInput 1, buffer "" c '\4' handleCommandInput
             | 2, buffer "" c '\4' after handleCommandInput, buffer
             | 0x104bf8d80"\4" c '\4' handleCommandInput 1, buffer "" c
             | '\3' handleCommandInput 2, buffer "" c '\3' after
             | handleCommandInput, buffer 0x104caaa80"\3" c '\3'
             | handleCommandInput 1, buffer "" c '\4' handleCommandInput
             | 2, buffer "" c '\4' after handleCommandInput, buffer
             | 0x104ca8e40"\4" c '\4' ```
        
               | shiomiru wrote:
               | Strange, so it sees your input but still doesn't evaluate
               | the commands...
               | 
               | OK, let's try something else. On master, is anything
               | written to the status line if you press `p` when started
               | with                   cha
               | -o'page.p="pager.alert(config.page.j)"' -V
        
               | erohead wrote:
               | I'm on Mac OS, encountering the same problem. I tried
               | opening `cha -o'page.p="pager.alert(config.page.j)"' -V`
               | then press `p`...nothing happens
        
       | lucideer wrote:
       | Absolutely incredible. And it even supports gopher.
        
       | silasdb wrote:
       | Wonderful! Thanks!
       | 
       | I see you don't use termcap/ncurses anymore. Do you perform
       | terminal handling yourself directly?
       | 
       | Thanks again!
        
         | shiomiru wrote:
         | Chawan never really used ncurses, only termcap. (ncurses just
         | happens to implement termcap too.)
         | 
         | I started with termcap because I was already familiar with it
         | through w3m. But termcap is an obsolete interface, and cannot
         | describe the only useful attribute for modern terminals (true
         | color). Its only benefit was "maybe it accidentally works on a
         | hardware terminal from the 80s", which is cool but not really
         | worth the extra failure mode.
         | 
         | So instead of migrating to terminfo, I ditched it completely in
         | favor of terminal queries (which were already necessary for
         | other reasons). There is still a built-in terminal database, to
         | detect known TERM values with XTerm incompatibilities. But a
         | terminal that correctly responds to queries will work out of
         | the box, even if its TERM value is unknown.
        
           | NoGravitas wrote:
           | > I started with termcap because I was already familiar with
           | it through w3m. But termcap is an obsolete interface, and
           | cannot describe the only useful attribute for modern
           | terminals (true color). Its only benefit was "maybe it
           | accidentally works on a hardware terminal from the 80s",
           | which is cool but not really worth the extra failure mode.
           | 
           | Priorities, I guess. As long as I'm in a terminal, I'd rather
           | have support for hardware terminals from the 80s than
           | truecolor. But my only hardware terminal is a VT-420, so
           | probably works for more or less anything that supports base
           | XTerm (monochrome).
        
       | zquestz wrote:
       | This works great, been playing with it through s-search and it
       | works way better than w3m. =)
        
       | higon wrote:
       | Long time w3m user here. Tried it and I can love it. Very nice.
       | 
       | Is that your design choice not having "Open URL"(Address bar)
       | feature?
        
         | shiomiru wrote:
         | The address bar should open by pressing C-l (control + L).
        
       | FerretFred wrote:
       | Very nice! I compiled this from source on my Lenovo M8 4h gen
       | running termux: I only had to install nim. It even installed
       | nicely despite there being no "root" user.
        
       | noufalibrahim wrote:
       | This is beautifully done. I'm going to use this for some of my
       | daily work and see how far I can get with it. HN looks
       | exceptionally good. Thank you!
        
         | dotancohen wrote:
         | Good of you! Don't forget to file the bugs you find.
        
       | desireco42 wrote:
       | I think making markdown browser would totally make sense for
       | terminal and would work really well. Come to think about it, you
       | can even, Netscape style even allow editing of the pages. Now
       | that would be something.
       | 
       | Nim is wonderful language and I am glad to see it used for this.
        
         | ralgozino wrote:
         | glow is kinda that: https://github.com/charmbracelet/glow
        
           | desireco42 wrote:
           | Thanks, this is a good find
        
       | mariusor wrote:
       | I've always tried to make my websites look good in Links and now
       | it looks like I have a new candidate.
       | 
       | Having support for _some_ CSS makes it a bit more difficult, as
       | spacing between elements is now an issue, where previously links
       | would ignore margins and padding all together which were used to
       | display cleaner inline list elements (for menus and such).
        
         | shiomiru wrote:
         | The intention is that it should "just work"... I'm aware
         | sometimes it doesn't, you can consider that a bug :)
         | 
         | But if you really want custom CSS for grid displays, chawan
         | does support the standard "grid" media feature:
         | https://developer.mozilla.org/en-US/docs/Web/CSS/@media/grid
        
           | mariusor wrote:
           | I had no idea this CSS API existed. I'll add that to my CSS,
           | thank you! :)
           | 
           | I'll check if the issue tracker has anything related to
           | supporting titled alternate stylesheets (and eventually
           | allowing users to pick one of them), because on the website
           | where I made efforts for the markup to look reasonable on
           | links, I also have a "simple" style that removes most of the
           | CSS fanciness.
        
       | eMPee584 wrote:
       | Thanks, always appreciate ways of not using another blink engine
       | for a brief research side quest! looking forward to test after
       | school ; )
       | 
       | As it hasn't been brought up yet, a really great hack (esp. for
       | us without sixel) is this terminal port of chromium:
       | https://github.com/fathyb/carbonyl .. but the original creator
       | hasn't had time to get back to it. So it is very bare bones &
       | lacks a lot of features, like keyboard shortcuts, file saving..
       | but obviously it brings full web compatibility and is just very
       | cool. Wishing for someone with rust skills to pick it up again,
       | last time I looked (couple of months ago) none of the forks had
       | any momentum.
        
         | Imustaskforhelp wrote:
         | Side note but on the carbonyl github post, everyone keeps
         | asking about the author's health as if he's safe or not, given
         | he is palestinian.
         | 
         | I hope the author is safe. His work was really good,I must say.
         | Fuck wars in general.
        
       | onetom wrote:
       | @shiomiru
       | 
       | What's the best resource (paid or free) in your opinion for
       | learning about these TTY related concepts?
       | 
       | I'm aware of
       | https://www.linusakesson.net/programming/tty/index.php for
       | example, but that doesn't go into termcap/terminfo/curses.
       | 
       | one of the comments mentions http://www.amazon.com/termcap-
       | terminfo-OReilly-Nutshell-Lind... though (online
       | https://www.scribd.com/document/831486848/Termcap-and-Termin...)
        
         | shiomiru wrote:
         | chawan has a custom terminal module, so my knowledge about the
         | standard X/Open curses is not that great.
         | 
         | That said, for the actual escape sequences, XTerm's
         | ctlseqs.ms[1] is an invaluable resource. I also took many ideas
         | from nick black's notcurses[2], and I especially recommend his
         | notes on "sprixels".[3]
         | 
         | [1]: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html
         | 
         | [2]: https://nick-black.com/dankwiki/index.php/Notcurses
         | 
         | [3]: https://nick-
         | black.com/dankwiki/index.php/Theory_and_Practic...
        
       | anta40 wrote:
       | Can be easily built on macOS with just a single 'make'. Cool.
       | 
       | And nice to see there's a new elinks alternative.
        
       | poulpy123 wrote:
       | always nice to see something written in nim. In my very novice
       | eyes, it is the most interesting language that is situated
       | between C/C++ and python. It's a pity it never took off. The
       | productivity of its users compared to the userbase size always
       | made me think I'm right even if I'm far to be knowledgeable
       | enough on the topic
        
         | pancsta wrote:
         | Nim(rod) was released soon before Golang, and the overlap in
         | features probably stopped the former one.
        
       | avinassh wrote:
       | what does the name mean
        
         | meepmorp wrote:
         | I believe it's a chinese tea bowl,
        
       | adamseddie wrote:
       | Dockerfile: https://paste.rs/egbGg
       | 
       | docker build -t chawan:0.2.0 .
       | 
       | docker run -it --rm chawan:0.2.0 https://news.ycombinator.com/
        
       | ieee2 wrote:
       | How are those images rendered in text UI?
        
         | dotancohen wrote:
         | Inline using sixel. Go look at the screenshots, it's not bad.
        
           | ieee2 wrote:
           | Yes, screenshots are nice. That's why I asked.
        
         | ieee2 wrote:
         | OK. Found it:
         | 
         | Displayed using Sixels or the Kitty protocol. Supported input
         | formats are PNG, JPEG, BMP, GIF (stb_image), WebP (jebp) and
         | SVG (nanosvg). Opt-in; edit the config to enable it.
        
         | ho_schi wrote:
         | btw.
         | 
         | Rendering images or movies on the TTY is common.
         | 
         | fbida: https://www.kraxel.org/blog/linux/fbida/
         | 
         | mpv: https://mpv.io/
         | 
         | Fbida sometimes need the _-d_ option pointing to
         | /dev/drm/something, when using screen or tmux.
         | 
         | MPV required for years _-vo=drm_ on the TTY but since some
         | months it always works. Nice improvement :)
         | 
         | A display server is not needed.
        
           | ieee2 wrote:
           | It is first time I saw it today. Thanks!
        
       | gherard5555 wrote:
       | Can we talk about how refreshing this web design is
        
       | ericrenan wrote:
       | Good job,really nice work,congrats.
        
       ___________________________________________________________________
       (page generated 2025-06-17 23:01 UTC)