Crates.io | riverql |
lib.rs | riverql |
version | 0.1.2 |
created_at | 2025-09-25 19:59:50.787866+00 |
updated_at | 2025-09-26 00:07:08.129513+00 |
description | GraphQL bridge and CLI client for the River Wayland compositor |
homepage | |
repository | https://github.com/typester/riverql |
max_upload_size | |
id | 1855053 |
size | 147,408 |
RiverQL exposes River window manager state over GraphQL.
It ships a server that bridges River's Wayland status protocol into GraphQL queries and
subscriptions, plus a CLI client for driving graphql-transport-ws
streams.
graphql-transport-ws
cargo install riverql
This installs a riverql
binary in your Cargo bin directory.
Most setups launch the server inside River's init script:
riverql --server &
By default this creates a Unix socket under $XDG_RUNTIME_DIR/riverql.sock
. To
override, use --listen
, e.g. riverql --server --listen tcp://127.0.0.1:8080
.
The server logs via tracing
; tune with RUST_LOG
(for instance
RUST_LOG=riverql=debug
).
/graphql
/graphiql
/schema
Example query:
{
outputs {
outputId
name
focusedTags
viewTags
urgentTags
layoutName
}
seatFocusedOutput { outputId name }
}
Subscription example:
subscription {
riverEvents {
__typename
... on OutputFocusedTags { outputId name tags }
... on SeatFocusedOutput { outputId name }
}
}
When a widget or script (for example an eww widget) needs data, invoke riverql
without --server
:
riverql 'subscription { riverEvents { __typename } }'
Key points:
@file.graphql
--listen
; override with
--endpoint
if needed (supports both unix://path#/graphql
and
ws://host:port/path
formats)Add the server to your River init script (riverql --server &
). Then, inside
eww.yuck
, you can consume RiverQL in two ways:
Polling a query:
(defpoll river_outputs :interval "5s"
"riverql 'query { outputs { outputId name focusedTags } }' | jq -c '.data.outputs'")
(defwidget river-tags []
(box :orientation "vertical"
(for output in river_outputs
(box :class "tag-row"
(label :text (format "%s" (. output 'name)))
(label :text (format "%s" (. output 'focusedTags)))))))
Listening for live events:
(deflisten river_events :initial "{}"
"riverql 'subscription { riverEvents { __typename ... on OutputFocusedTags { outputId name tags } } }' | jq -c '.data.riverEvents'")
(defwidget river-event-feed []
(box :orientation "vertical"
(label :text (format "Latest event: %s" river_events))))
defpoll
is ideal for periodic snapshots (e.g. populating a list of outputs),
while deflisten
reacts instantly to subscription pushes. Both examples assume
riverql
is on PATH
and that jq
is available to compact JSON.
Code in this repository is licensed under MIT; see LICENSE.
The XML files under protocol/
are copied from upstream River (GPL-3.0-or-later)
and wlroots (MIT). They retain their original licensing. Consult the upstream
projects for full details.