Sorry, no more vibe-I/O...

Published on: Author: Dorian Niemiec

I’m reminding myself way too much about announcement of what was vibeio:

But is it vibe-coded!?

Ah, we get it… 😅

We have named this asynchronous runtime “vibeio”, from “vibe” (from “vibe coding”, because this runtime was coded with help of AI) and a common suffix for Rust asynchronous runtimes, “-io”.

However, we have debugged some parts ourselves, like io_uring use-after-frees that led to memory corruption, some zombie process reaper-related test hangups on macOS or fixing UDP test failures on Windows (since ConnectEx function works on connection-bound sockets only; also, handles couldn’t be registered multiple times in I/O completion ports).

Well, today, I have renamed this asynchronous runtime (and related crates) to something that would sound more sensible. The asynchronous runtime is used in Ferron 3 (which is in beta) as a fast thread-per-core runtime with io_uring support.

Here’s why:

Vibe-coded async runtime?

When I was first building the asynchronous runtime, I named it vibeio, because it was created with help of AI coding agents (hence “vibe-coding”), and I wanted to get attention on it by its name (pointing at “vibe-coded” as something unusual).

However, as of now, there is too much vibe-coded software! And I felt “vibe-coded” became just an overused hook and buzzword. And engineers complain about the downfall of software quality…

Also, when looking at project structure, it’s more like monoio (the thread-per-core asynchronous runtime I wanted to replace, because it was barely-maintained), but with better cross-platform compatibility (including Windows), simpler logic (not inherited complexity from Tokio, since monoio used some code from Tokio), and support for async processes (earlier, I had to use crate from smol project for Ferron 2).

And I found something a lot more vibe-coded, lot more rough and messier than what was vibeio, namely asupersync (its landing page says about AI agent loop at the bottom, and the author of the crate talks more about AI agents in the future, possible ultra-vibe-coder, gaah!). I checked its project structure, and it seems like lots of files and folders scattered together. And the crate had HTTP/1-2-3 (mine is what was vibeio-http), gRPC (I would just use tonic for that, or just not care much, since gRPC is built on HTTP/2), RaptorQ, observability (!), and way too much (scope creep?). And it took too long to compile for me…

However, my async runtime is not like that. So I ended up going for more sensible name

The new name

OK, I’m going to reveal a new name, it’s zincio.

I chose the name based on a metal from a periodic table (zinc), which is similarly to Ferron (iron) and the codename for Ferron 3 during its early development, “Titanium” (titanium). And I added -io suffix common in async Rust runtimes.

Similar to Ferron 3, zincio would focus on stability, calm operations (it would just work, not YOLO-vibe-coding risk!). It would be core infrastructure, same behind Ferron 3 (which would be also core infrastructure in the future), and it has to be stable to run the world.

Try it out

From zincio README:

Add zincio to your Cargo.toml:

[dependencies]
zincio = "0.2"

Example: TCP echo server

use zincio::RuntimeBuilder;
use zincio::net::TcpListener;

fn main() -> std::io::Result<()> {
    // 1. Build the runtime
    let runtime = RuntimeBuilder::new()
        .enable_timer(true)
        .build()?;

    // 2. Run the main future
    runtime.block_on(async {
        let listener = TcpListener::bind("127.0.0.1:8080")?;
        println!("Listening on 127.0.0.1:8080");

        loop {
            let (mut stream, _) = listener.accept().await?;

            zincio::spawn(async move {
                let (mut reader, mut writer) = zincio::io::split(stream);
                if let Err(e) = zincio::io::copy(&mut reader, &mut writer).await {
                    eprintln!("Echo failed: {}", e);
                }
            });
        }
    })
}