Skip to main content

Overview

You can communicate with the running niri instance over an IPC socket using the niri msg command. This allows you to:
  • Query compositor state (outputs, workspaces, windows)
  • Perform actions (focus windows, move workspaces, etc.)
  • Subscribe to real-time events
  • Control output configuration

Basic Usage

Check available commands:
The --json flag prints responses in JSON format rather than human-readable:
If you’re getting parsing errors from niri msg after upgrading niri, make sure you’ve restarted niri itself. You might be running a newer niri msg against an older niri compositor.

Available Commands

Here are all the niri msg subcommands:

Query Commands

outputs

List connected outputs

workspaces

List all workspaces

windows

List open windows

layers

List open layer-shell surfaces

keyboard-layouts

Get configured keyboard layouts

focused-output

Print information about the focused output

focused-window

Print information about the focused window

overview-state

Print the overview state (open/closed)

casts

List active screencasts

version

Print the version of the running niri instance

Interactive Commands

pick-window

Pick a window with the mouse and print its information

pick-color

Pick a color from the screen with the mouse

Action Commands

Perform any niri action via IPC:

Output Configuration

Change output configuration temporarily (not saved to config):

Event Stream

Available since version 0.1.9
The event stream request makes niri continuously stream events into the IPC connection until it is closed. This is useful for implementing bars and indicators that update in real-time without polling.

Key Features

  • Complete state up-front: The event stream gives you the complete current state first, then follows up with updates
  • No polling needed: Events are pushed to you as they happen
  • Atomic updates: Most state updates are atomic (though not always)

Usage

Example: Monitor Workspaces

Available Events

WorkspacesChanged

Complete workspace configuration update

WorkspaceActivated

A workspace was activated on an output

WindowsChanged

Complete window configuration update

WindowOpenedOrChanged

A window was opened or changed

WindowClosed

A window was closed

WindowFocusChanged

Window focus changed

KeyboardLayoutsChanged

Keyboard layouts configuration changed

KeyboardLayoutSwitched

Active keyboard layout switched

OverviewOpenedOrClosed

Overview was opened or closed

ConfigLoaded

Configuration was (re)loaded

ScreenshotCaptured

A screenshot was captured

CastsChanged

Screencasts configuration changed

Full Event Documentation

View the complete list of events with detailed documentation

Programmatic Access

For more complex scripts and modules, you can access the socket directly instead of using niri msg --json.

Socket Protocol

1

Connect to Socket

Connect to the UNIX domain socket at $NIRI_SOCKET:
2

Write Request

Write your request encoded in JSON on a single line, followed by a newline or by flushing/shutting down the write end.
3

Read Reply

Read the reply as JSON, also on a single line.

Testing with socat

Finding Request Format

You can use socat to see how niri msg formats requests:

Python Example

Response Format

The reply is an Ok or an Err wrapping the same JSON object as you get from niri msg --json:

API Documentation

View the complete niri-ipc sub-crate documentation for all request and response types

Backwards Compatibility

JSON Output Stability

The JSON output should remain stable:
Existing fields and enum variants will not be renamed
Non-optional existing fields will not be removed
New fields and enum variants will be added. Handle unknown fields gracefully.

Human-Readable Output

The formatted output (without --json flag) is not considered stable. Always use --json for scripts.

Rust API

The niri-ipc sub-crate follows niri’s version and is not API-stable in terms of Rust semver. New struct fields and enum variants will be added in patch releases.