4 stable releases

✓ Uses Rust 2018 edition

2.0.0 May 22, 2020
1.0.2 Dec 30, 2019

#7 in #ipc

Download history 3/week @ 2020-02-07 24/week @ 2020-02-14 10/week @ 2020-02-21 7/week @ 2020-02-28 6/week @ 2020-03-06 3/week @ 2020-03-13 24/week @ 2020-03-20 54/week @ 2020-03-27 48/week @ 2020-04-03 45/week @ 2020-04-10 3/week @ 2020-04-17 6/week @ 2020-04-24 8/week @ 2020-05-01 6/week @ 2020-05-08 39/week @ 2020-05-15 82/week @ 2020-05-22

87 downloads per month

MIT license


pipeline status


A Rust API for D-Bus communication. The aim is to provide a safe and simple high- and low-level API akin to GDBus, that doesn't depend on C libraries.

The project is divided into three crates:


This crate provides API for encoding/decoding of data to/from D-Bus wire format. This crate is already in good shape and can and should be used by other projects. This binary wire format is simple and very efficient and hence useful outside of D-Bus context as well.

Status: Stable.


  • byteorder
  • serde
  • arrayvec (optional)
  • enumflags2 (optional)

Example code

use std::collections::HashMap;
use byteorder::LE;
use zvariant::{from_slice, to_bytes};
use zvariant::EncodingContext as Context;

// All serialization and deserialization API, needs a context.
let ctxt = Context::<LE>::new_dbus(0);

// i16
let encoded = to_bytes(ctxt, &42i16).unwrap();
let decoded: i16 = from_slice(&encoded, ctxt).unwrap();
assert_eq!(decoded, 42);

// strings
let encoded = to_bytes(ctxt, &"hello").unwrap();
let decoded: &str = from_slice(&encoded, ctxt).unwrap();
assert_eq!(decoded, "hello");

// tuples
let t = ("hello", 42i32, true);
let encoded = to_bytes(ctxt, &t).unwrap();
let decoded: (&str, i32, bool) = from_slice(&encoded, ctxt).unwrap();
assert_eq!(decoded, t);

// Vec
let v = vec!["hello", "world!"];
let encoded = to_bytes(ctxt, &v).unwrap();
let decoded: Vec<&str> = from_slice(&encoded, ctxt).unwrap();
assert_eq!(decoded, v);

// Dictionary
let mut map: HashMap<i64, &str> = HashMap::new();
map.insert(1, "123");
map.insert(2, "456");
let encoded = to_bytes(ctxt, &map).unwrap();
let decoded: HashMap<i64, &str> = from_slice(&encoded, ctxt).unwrap();
assert_eq!(decoded[&1], "123");
assert_eq!(decoded[&2], "456");


This crate provides a derive macro to easily implement Type trait on structs and enums.

Status: Stable.


  • proc-macro2
  • syn
  • quote

Example code

use zvariant::{EncodingContext, from_slice, to_bytes};
use zvariant::Type;
use zvariant_derive::Type;
use serde::{Deserialize, Serialize};
use byteorder::LE;

#[derive(Deserialize, Serialize, Type, PartialEq, Debug)]
struct Struct<'s> {
    field1: u16,
    field2: i64,
    field3: &'s str,

assert_eq!(Struct::signature(), "(qxs)");
let s = Struct {
    field1: 42,
    field2: i64::max_value(),
    field3: "hello",
let ctxt = EncodingContext::<LE>::new_dbus(0);
let encoded = to_bytes(ctxt, &s).unwrap();
let decoded: Struct = from_slice(&encoded, ctxt).unwrap();
assert_eq!(decoded, s);


That's the main crate that you'll use to actually communicate with services and apps over D-Bus. At the moment you can only connect to the session bus and call methods synchronously.

Status: Unstable. You've been warned!


  • nix
  • byteorder
  • serde
  • serde_repr
  • enumflags2
  • serde-xml-rs (optional)

Getting Help

If you need help in using these crates, are looking for ways to contribute or just want to hang out with the cool kids, please come chat with us on our IRC channel, #zbus on irc.freenode.net. If something doesn't seem right, please file an issue.


All crates are currently Unix-only and will fail to build on non-unix. This is hopefully a temporary limitation. Moreover, integration tests of zbus crate currently require a session bus running on the build host.




~25K SLoC