the irc crate: a thread-safe async IRC client library for Rust
the irc crate – usable, async IRC for Rust
At a glance
- What is it?
- The irc crate is a Rust library for talking IRC, compliant with RFC 2812, IRCv3.1 and IRCv3.2, and rewritten around async/await in v0.14. It ships a full TOML configuration model, optional JSON and YAML config, proxy and TLS backends, and a set of example clients you can read as documentation.
- Who is it for?
- the irc crate fits a Rust developer writing a bot, a bouncer, or a terminal client who wants protocol handling done properly and configuration in a real file rather than in code. It is the wrong choice for a JavaScript or Python team, since there is no port of this API, and the wrong choice if you need a server side IRC implementation rather than a client.
- Can I use it commercially?
- Yes, with conditions. MPL-2.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 10 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Protocol coverage is stated as RFC 2812 plus the IRCv3 series
The irc crate is described as a thread-safe and async-friendly IRC client library written in Rust, compliant with RFC 2812, IRCv3.1 and IRCv3.2, and including some additional common features from popular IRCds. The repository topics match, with async, client, irc, ircv3, protocol, and thread-safe among them. The default branch is develop rather than master, which is worth knowing before you clone it. The library is on crates.io as `irc` and the documentation lives on docs.rs, with the README describing it as up-to-date and ready to use. What the compliance claim buys you is the unglamorous part of an IRC client. Hand-parsing the message grammar, the numerics, and the CTCP replies is where most of the bugs in a homegrown client live, and a library that has been through the RFC text saves that work.
v0.14 replaced every API with an async one, and that is the shape now
The Using Futures section is blunt about the history. The release of v0.14 replaced all existing APIs with one based on async/await. The current example shows what a client looks like after that change:
use futures::prelude::*;
use irc::client::prelude::*;
#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
// We can also load the Config at runtime via Config::load("path/to/config.toml")
let config = Config {
nickname: Some("the-irc-crate".to_owned()),
server: Some("chat.freenode.net".to_owned()),
channels: vec!["#test".to_owned()],
..Config::default()
};
let mut client = Client::from_config(config).await?;
client.identify()?;
let mut stream = client.stream()?;
while let Some(message) = stream.next().await.transpose()? {
print!("{}", message);
}
Ok(())
}The shape is the standard Rust networking shape. Configuration is built, a client is created from it asynchronously, the client is told to identify, and then a stream of messages is consumed. The `transpose()` on the stream is the part that trips people up at first, since it converts a stream of `Result` items into a stream of `Option` items so the loop can exit cleanly on an error, and the `?` operator then propagates it out of `main`. The crate version is 1.1.0 with a minimum supported Rust version of 1.80 and edition 2018, and the async runtime is tokio, with the workspace holding the `irc-proto/` crate as a second member.
Configuration is a TOML file with an optional table for your own keys
There are two ways to configure a client, and the README explains when each is right. Runtime loading through the function `Config::load` is likely sufficient for most IRC bots. Programmatic configuration is convenient for writing tests, and is also useful when you define your own custom configuration format that can be converted into `Config`. The primary format is TOML, with optional `json_config` and `yaml_config` features for JSON and YAML. A configuration requires at least `nickname` and `server`, and everything else is optional. A full example shows how much the library will carry for you:
owners = []
nickname = "user"
nick_password = "password"
alt_nicks = ["user_", "user__"]
username = "user"
realname = "Test User"
server = "chat.freenode.net"
port = 6697
password = ""
proxy_type = "None"
proxy_server = "127.0.0.1"
proxy_port = 1080The same file also covers TLS material, `use_tls`, `cert_path`, `client_cert_path` and `client_cert_pass`, the character `encoding`, the channel list, `umodes`, and the source and version strings sent in registration. There is a per-channel key table and an `[options]` table that the README says can hold anything you want, which is how you extend the configuration without changing the library.
The feature flags decide your TLS stack and your config format
The Cargo.toml is where the design decisions become visible. The default feature set is `ctcp`, `tls-native`, `channel-lists`, `toml_config`, and `encoding`. The TLS choice is the one to think about, because there are two mutually exclusive backends and you pick one. `tls-native` pulls in `native-tls` and `tokio-native-tls`, which means the system certificate store, and `tls-rust` pulls in the rustls stack with `rustls-native-certs`, `rustls-pemfile`, `tokio-rustls`, and `webpki-roots`. The proxy support is a separate `proxy` feature gated on `tokio-socks`. The config formats are additive, with `json_config` and `yaml_config` each enabling serde and their parser, and the older `json` and `yaml` names kept as temporary transitionary features. The `encoding` feature turns on character set conversion, which matters for networks that are not UTF-8, and it also enables the same feature in the `irc-proto` crate. Choosing a rustls backend on a system where you do not control the trust store is a deliberate change of behaviour, not a default you inherit.
Migrating an old JSON config is a shipped example, not a script you write
Because the crate supports several configuration formats, it also ships the migration tool. The `convertconf` example converts between them:
cargo run --example convertconf -- -i client_config.json -o client_config.tomlThe README notes that the formats are automatically determined based on the selected file extensions, and that the tool should make it easier for users to migrate their old configurations to TOML. That is a small design decision with real consequences, because a library that only accepts one configuration format forces every user to write a translation layer before they can adopt it. The `examples/` directory in the repository holds the other ready-made programs, including `simple.rs`, `simple_plaintext.rs`, `simple_proxy.rs`, `multiserver.rs`, `repeater.rs`, `build-bot.rs`, `tweeter.rs`, and `tooter.rs`, so the documented way to learn the API is to read a program that does one thing.
The list of projects built on it is the strongest argument
The Built with section lists the projects the maintainers consider favourites, and they show the range of things the library supports. Alectro is a terminal IRC client, Spilo is a minimalistic IRC bouncer, irc-bot.rs is a library for writing IRC bots, playbot_ng is a bot that evaluates Rust, bunnybutt-rs is an IRC bot for the Feed The Beast Wiki, and url-bot-rs fetches URLs. That is a spread of client, bouncer, and bot use cases, and the bouncer in particular is a demanding one, because it has to keep state for many users and hold several connections at once. The library being used for that is a better signal than any feature list. The README also asks readers making their own project to submit a pull request to add it to the list, which is how you would expect a maintained ecosystem to grow.
MPL-2.0 and two named maintainers
The licence is the Mozilla Public License 2.0, with the text in `LICENSE.md`, which is a reasonable fit for a library that is meant to be embedded in larger applications. The README names the maintainers as Ariel Weiss and Peter Atashian, and describes the project as a free, open source library that relies on contributions from its maintainers as well as the broader Rust community. There is a Code of Conduct in `CODE_OF_CONDUCT.md` and details in `CONTRIBUTING.md`. The repository also carries a `.travis.yml` and a `CODE_OF_CONDUCT.md`, and it publishes no GitHub releases, so the crates.io version is the one to track. The last push was on 2026-10-13, and the default branch is develop, which means the published crate and the branch tip can differ.
Editorial conclusion
the irc crate fits a Rust developer writing a bot, a bouncer, or a terminal client who wants protocol handling done properly and configuration in a real file rather than in code. It is the wrong choice for a JavaScript or Python team, since there is no port of this API, and the wrong choice if you need a server side IRC implementation rather than a client. Before you depend on it, read the feature flags in the Cargo.toml, because the defaults are only ctcp, tls-native, channel-lists, toml_config and encoding, and the TLS backend is a choice between native-tls and rustls that you have to make explicitly.
Frequently asked questions
How do I add the irc crate to a Rust project?
Add `irc = "1.1.0"` to the dependencies in your Cargo.toml file, or use the `cargo add irc` command. The high-level API is in `irc::client::prelude`, and examples live in the `examples/` directory and in the documentation.
What are the minimum requirements for an irc configuration?
At the minimum, a configuration requires `nickname` and `server` to be defined, and all other fields are optional. The primary format is TOML, with optional `json_config` and `yaml_config` features for the other formats.
Can the irc crate load its configuration from a file at runtime?
Yes, through the function `Config::load`, and the example shows it as `Config::load("path/to/config.toml")`. The README says runtime loading is likely sufficient for most IRC bots, while programmatic configuration is convenient for writing tests or for a custom configuration format you convert into `Config`.
Which TLS backends does the irc crate support?
Two, chosen through features. The default `tls-native` uses `native-tls` and `tokio-native-tls`, while the `tls-rust` feature uses rustls with `rustls-native-certs`, `rustls-pemfile`, `tokio-rustls`, and `webpki-roots`. Proxy support is a separate `proxy` feature enabled by `tokio-socks`.
How do I convert an old JSON configuration to TOML?
Use the `convertconf` example that ships with the crate, running `cargo run --example convertconf -- -i client_config.json -o client_config.toml`. The formats are determined automatically from the file extensions, and the README says the tool exists to make migrating old configurations to TOML easier.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/aatxe-irc)Was this useful?