Carbonyl: Forking Chromium to Render Live in a Terminal

A new project called Carbonyl takes a fresh stab at text-based browsing by forking Chromium and re-routing its rendering pipeline into a terminal emulator. Rather than outputting pixels to a window, Carbonyl maps every web page onto Unicode block chara…


This content originally appeared on DEV Community and was authored by Mr Punk da Silva

A new project called Carbonyl takes a fresh stab at text-based browsing by forking Chromium and re-routing its rendering pipeline into a terminal emulator. Rather than outputting pixels to a window, Carbonyl maps every web page onto Unicode block characters and ANSI color escapes—complete with interactive text capture and input support.

đź“° Coverage on CyNews: https://cynews.vercel.app/show/45133935

📎 Project page & write-up: https://fathy.fr/carbonyl

Background

Most terminal-based browsers rely on parsing HTML and re-implementing layout (e.g. w3m, lynx). Carbonyl instead leverages the real Chromium engine:

  • It hooks Skia’s bitmap and text-drawing devices to capture rendered output.
  • It preserves the exact layout, CSS, JavaScript engine and extensions you’d see in Chrome.
  • It translates that output into terminal control sequences on the fly.

The result is a “true” Chrome experience—minus the GUI.

Rendering Pipeline

  1. HTML → Skia bitmap

     Chromium’s renderer draws pages into an offscreen SkBitmap. Carbonyl intercepts this via a custom HostDisplayClient and shared memory mapping between GPU, renderer, and browser processes.

  2. Bitmap → Terminal blocks

     Each terminal cell uses U+2584 (lower half block) with 24-bit ANSI colors. Carbonyl sets the cell’s background to the top pixel and foreground to the bottom. It batches calls for minimal cursor movement:

   fn print_pixels_pair(top: RGB, bottom: RGB, cursor: (x, y)) {
     move_cursor(cursor);
     set_background(top);
     set_foreground(bottom);
     println!("â–„");
   }
  1. Text capture  A TextCaptureDevice, inserted into Skia’s pipeline, intercepts glyph runs. It converts glyph IDs to Unicode and issues ANSI code to render characters instead of bitmap blocks—preserving crisp text and selectable content.

Input & Interaction

Carbonyl listens for mouse and keyboard via ANSI Device Control Sequences (DCS). For example:

fn report_mouse_down((x, y): (usize, usize)) {
  write!(stdin, "\x1b[<0;{y};{x}M");
}

These sequences feed events back into Chromium’s input system on the main thread via BrowserMainThread::PostTask, enabling clicks, scrolling, and text input—just like in a GUI browser.

Performance & Tuning

Out of the box, Carbonyl renders at about 5 FPS with ~400 % CPU usage on a modern laptop. Two key optimizations were introduced:

  • LoDPI scaling: For terminal output, the display scale is forced to 1/7, reducing the pixel grid by a factor of 49.
  • Threaded compositing hacks: Disabling --disable-threaded-scrolling and --disable-threaded-animation keeps rendering on the main thread, avoiding expensive cross-thread coordination.

With these tweaks, idle CPU usage drops to near zero, and scrolling stabilizes around 15 %.

Community Feedback

On the CyNews discussion, developers highlighted:

  • Novelty: “Finally, a real Chromium-powered terminal browser.”
  • Performance concerns: CPU overhead makes it impractical for daily use today.
  • Potential use cases: Remote servers, CI log previews, low-bandwidth environments, or ultra-portable dev setups.
  • Feature requests: True-color detection, configurable block resolution, SSH-friendly input modes.

Why Carbonyl Matters

Carbonyl demonstrates how far browser engines can be repurposed when paired with terminal graphics tricks. It:

  • Preserves exact web compatibility (JS, CSS, extensions).
  • Maintains selectable text for copy/paste or accessibility readers.
  • Opens a path for GUI-less demos, remote interaction, and embedded deployments in constrained environments.

For anyone curious about browser internals, terminal graphics or building bridges between GUIs and CLIs, Carbonyl is a compelling, hands-on case study.

đź”— Project write-up & demo: https://fathy.fr/carbonyl

đź“° Read the CyNews article: https://cynews.vercel.app/show/45133935

Let me know if you try it—what pages render best, or how it fits into your remote workflows!


This content originally appeared on DEV Community and was authored by Mr Punk da Silva


Print Share Comment Cite Upload Translate Updates
APA

Mr Punk da Silva | Sciencx (2025-09-05T03:39:57+00:00) Carbonyl: Forking Chromium to Render Live in a Terminal. Retrieved from https://www.scien.cx/2025/09/05/carbonyl-forking-chromium-to-render-live-in-a-terminal/

MLA
" » Carbonyl: Forking Chromium to Render Live in a Terminal." Mr Punk da Silva | Sciencx - Friday September 5, 2025, https://www.scien.cx/2025/09/05/carbonyl-forking-chromium-to-render-live-in-a-terminal/
HARVARD
Mr Punk da Silva | Sciencx Friday September 5, 2025 » Carbonyl: Forking Chromium to Render Live in a Terminal., viewed ,<https://www.scien.cx/2025/09/05/carbonyl-forking-chromium-to-render-live-in-a-terminal/>
VANCOUVER
Mr Punk da Silva | Sciencx - » Carbonyl: Forking Chromium to Render Live in a Terminal. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/09/05/carbonyl-forking-chromium-to-render-live-in-a-terminal/
CHICAGO
" » Carbonyl: Forking Chromium to Render Live in a Terminal." Mr Punk da Silva | Sciencx - Accessed . https://www.scien.cx/2025/09/05/carbonyl-forking-chromium-to-render-live-in-a-terminal/
IEEE
" » Carbonyl: Forking Chromium to Render Live in a Terminal." Mr Punk da Silva | Sciencx [Online]. Available: https://www.scien.cx/2025/09/05/carbonyl-forking-chromium-to-render-live-in-a-terminal/. [Accessed: ]
rf:citation
» Carbonyl: Forking Chromium to Render Live in a Terminal | Mr Punk da Silva | Sciencx | https://www.scien.cx/2025/09/05/carbonyl-forking-chromium-to-render-live-in-a-terminal/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.