created_at2023-11-04 11:27:25.345217
updated_at2024-04-18 03:40:58.334396
descriptionA lightweight and batteries-included status_command for i3 and sway



i3stat: an i3 (or sway) status_command

Please Note this used to be called istat and was renamed.

I used to use i3blocks for i3's status_command, but I found that having all my configuration in separate scripts was getting a little cumbersome.

That, and also I could never find a good block for volume control that wasn't janky or slow.

So, I decided to write my own status_command generator, and what better language to write it in than Rust!


  • ⚡ completely single threaded (less resource usage)
    • 🔎 it's a status command, it shouldn't be heavy
  • ⏩ powerline theming and customisability
  • 🎮 ipc control
    • 🖱️ send click events via a command
    • ♻️ refresh items with a command
    • 📜 custom events for some integrations (e.g., controlling PulseAudio/PipeWire, etc)
    • 🤯 runtime updates - no restart required
  • 🖇️ many different bar items (continue reading for screenshots)

Each bar item is configurable, see the sample config for options.


Here's an image of a bar in i3:

screenshot of i3bar

And another one with powerline mode enabled:

screenshot of i3bar with powerline

This table contains screenshots of some bar items:

item description screenshots
battery Percentage, charging, etc. Supports multiple batteries.
cpu Usage expressed as a percentage
disk Usage, shows free disk space. Supports multiple mount points.
dunst Displays "do not disturb" status (if it's paused or not) off (invisible)
kbd Displays CapsLock/Numlock/etc states
krb Checks if a valid kerberos token exists (like klist -s)
mem Display free memory as bytes or as a percentage
net_usage Upload and download statistics
nic Network interface status - connection state and ip addresses
pulse Input/output volume status, full control and current speaker type (jack, bt, etc)
script Run arbitrary scripts and show their output
sensors Temperature sensors
time Displays the current date and/or time


Download the latest release from GitHub

Link to the latest release

With Rust (via cargo):

cargo install i3stat
# Make sure to look at the `sample_config.toml` file for configuration options!

Via the AUR (Arch Linux):

# just download the latest release and install it
paru -S i3stat-bin
# build the latest release with cargo
paru -S i3stat
# build the latest commit on `next`
paru -S i3stat-git


Setting it up

First, create a config file for i3stat. View the sample config for what's available. This file should be placed in:

  • $XDG_CONFIG_HOME/i3stat/<here>, or
  • $HOME/.config/i3stat/<here>

Even though the sample configuration file is a TOML file, YAML and JSON are also supported.

Then, update your i3/sway config to use i3stat as the status_command:

bar {
        status_command i3stat
        # ... other config

Interacting with i3stat

i3stat offers multiple ways of interacting with it:

  • standard click events from i3/sway
  • real-time signals
  • it's own ipc


Consider the following bar item which outputs the state of the CapsLock and NumLock keys:

type = "kbd"
show = ["caps_lock", "num_lock"]
interval = "30s"

It refreshes every 30 seconds, or every time the bar item receives a click event. That's alright, but we can do better with signals. Adding signal = 8 to the config, and removing interval we get:

type = "kbd"
show = ["caps_lock", "num_lock"]
signal = 8

Now, whenever i3stat receives the SIGRTMIN+8 signal, the bar item will be refreshed. Pair this with the following config in i3/sway, and you'll have a bar item that reflects your keys all the time:

bindsym --release Caps_Lock exec --no-startup-id pkill -RTMIN+8 i3stat
bindsym --release Num_Lock  exec --no-startup-id pkill -RTMIN+8 i3stat

Linux offers many realtime signals, to see which your machine supports the i3stat-signals command is provided:

$ i3stat-signals

The same signal can be configured for multiple bar items, so many can be refreshed with the same signal!

Custom IPC events

The command i3stat-ipc is provided to interface with i3stat. It supports:

  • fetching the name and index of all the currently running bar items
  • refreshing all bar items at once
  • sending click events to each bar item
  • sending custom events to bar items
    • some bar items (like pulse) expose an advanced API which can be accessed with these events

Refresh all bar items at once:

i3stat-ipc refresh-all

Send a click event to a bar item - without actually clicking it!:

# emulate a left click on the disk item:
i3stat-ipc click disk left

Control PulseAudio/Pipewire via custom IPC events:

# see all the custom events that pulse has to offer:
i3stat-ipc custom pulse

# Some examples:

# turn the output (speakers) volume up
i3stat-ipc custom pulse volume-down sink
# turn the input (microphone) volume down
i3stat-ipc custom pulse volume-up   source
# mute or unmute the output
i3stat-ipc custom pulse mute-toggle sink


See the justfile!

Also give IDEAS.md a read too.

Commit count: 404

cargo fmt