Top Related Projects
i3-compatible Wayland compositor
Hyprland is an independent, highly customizable, dynamic tiling Wayland compositor that doesn't sacrifice on its looks.
A Wayland window-stacking compositor
A modular and extensible wayland compositor
A tiling window manager for X11
A tiling window manager based on binary space partitioning
Quick Overview
River is a dynamic tiling Wayland compositor for Linux and FreeBSD. It aims to be simple, flexible, and visually pleasing, offering a minimalist approach to window management. River is designed for users who prefer a keyboard-driven workflow and customizable layouts.
Pros
- Highly customizable through a simple configuration language
- Lightweight and efficient, with minimal resource usage
- Supports multiple monitors and flexible layout system
- Active development and community support
Cons
- Steep learning curve for users new to tiling window managers
- Limited GUI configuration options, primarily configured through text files
- May not be suitable for users who prefer traditional stacking window managers
- Some advanced features may require additional scripting or external tools
Getting Started
To get started with River, follow these steps:
-
Install River on your system:
# For Arch Linux sudo pacman -S river # For Debian/Ubuntu sudo apt install river
-
Create a basic configuration file:
mkdir -p ~/.config/river touch ~/.config/river/init chmod +x ~/.config/river/init
-
Add some basic configuration to
~/.config/river/init
:#!/bin/sh # Set background color riverctl background-color 0x002b36 # Set keyboard repeat rate riverctl set-repeat 50 300 # Set mod key to Super (Windows key) riverctl map normal Super Return spawn foot # Exit River riverctl map normal Super+Shift Q exit
-
Start River from your display manager or add
exec river
to your~/.xinitrc
file.
For more detailed configuration options and usage instructions, refer to the official River documentation.
Competitor Comparisons
i3-compatible Wayland compositor
Pros of Sway
- More mature and feature-rich project with a larger user base
- Extensive documentation and community support
- Compatible with i3 configuration files, making migration easier
Cons of Sway
- Larger codebase, potentially more complex to contribute to
- Less flexible in terms of customization compared to River
- Tied to the i3 paradigm, which may not suit all users
Code Comparison
Sway (C):
struct sway_container *container_create(struct sway_view *view) {
struct sway_container *c = calloc(1, sizeof(struct sway_container));
if (!c) {
return NULL;
}
c->view = view;
return c;
}
River (Zig):
pub fn create(self: *Self, view: *View) !*Output {
const output = try self.allocator.create(Output);
errdefer self.allocator.destroy(output);
output.* = Output{
.view = view,
};
return output;
}
Both projects implement Wayland compositors, but River is written in Zig and aims for a more minimal, customizable approach. Sway, written in C, closely follows the i3 window manager's design and functionality. River's code tends to be more concise due to Zig's modern features, while Sway's C codebase is more traditional and verbose.
Hyprland is an independent, highly customizable, dynamic tiling Wayland compositor that doesn't sacrifice on its looks.
Pros of Hyprland
- More feature-rich and customizable, with extensive configuration options
- Smoother animations and better performance on high-refresh-rate displays
- Active development with frequent updates and new features
Cons of Hyprland
- Higher system resource usage due to its feature set
- Steeper learning curve for configuration and customization
- Less stable compared to River, as it's still in active development
Code Comparison
River configuration example:
map {
normal Super+J focus-view next
normal Super+K focus-view previous
normal Super+Return spawn foot
}
Hyprland configuration example:
bind = SUPER, J, cyclenext
bind = SUPER, K, cyclenext, prev
bind = SUPER, Return, exec, foot
Both River and Hyprland are Wayland compositors, but they differ in their approach and feature set. River focuses on simplicity and stability, while Hyprland aims for a more feature-rich and customizable experience. River uses a more traditional configuration syntax, while Hyprland adopts a more modern and flexible approach. Ultimately, the choice between the two depends on the user's preferences and system requirements.
A Wayland window-stacking compositor
Pros of labwc
- Lightweight and fast Wayland compositor with Openbox-like configuration
- Supports traditional stacking window management
- Easier transition for users coming from X11 environments
Cons of labwc
- Less flexible tiling options compared to River
- Smaller community and ecosystem
Code Comparison
labwc (C):
static void
view_move(struct view *view, int x, int y)
{
view->x = x;
view->y = y;
wlr_scene_node_set_position(&view->scene_tree->node, x, y);
}
River (Zig):
pub fn move(self: *View, x: i32, y: i32) void {
self.x = x;
self.y = y;
self.scene_node.setPosition(x, y);
}
Both projects implement similar functionality for moving views, but River uses Zig while labwc uses C. River's code is more concise due to Zig's modern syntax, while labwc follows a more traditional C style.
A modular and extensible wayland compositor
Pros of Wayfire
- More feature-rich and customizable out of the box
- Offers a plugin system for extending functionality
- Provides a more traditional desktop environment experience
Cons of Wayfire
- Higher resource usage due to more features and effects
- Steeper learning curve for configuration and customization
- Less minimalist approach compared to River
Code Comparison
River configuration (example):
map {
modifiers = {"Super"},
key = "Return",
command = "foot"
}
Wayfire configuration (example):
[key-bindings]
terminal = <super> KEY_ENTER
[command]
terminal = foot
Both River and Wayfire are Wayland compositors, but they target different user preferences. River focuses on simplicity and minimalism, while Wayfire aims for a more feature-rich and customizable experience. River uses a Lua-based configuration, whereas Wayfire uses an INI-style format. Wayfire's plugin system allows for more extensive customization, but it may come at the cost of increased complexity and resource usage. River, on the other hand, provides a more streamlined and lightweight approach to window management.
A tiling window manager for X11
Pros of i3
- Mature and stable project with a large user base and extensive documentation
- Highly customizable with a powerful configuration system
- Supports both floating and tiling window management
Cons of i3
- Limited to X11, no Wayland support
- Less modern design compared to newer window managers
- Steeper learning curve for new users
Code Comparison
i3 (C):
static void
tree_render(Con *con) {
if (con->type == CT_ROOT)
return;
/* Render this container */
render_con(con);
}
River (Zig):
pub fn renderOutput(self: *Self) void {
const output = self.output;
const wlr_output = output.wlr_output;
var render = self.render_data.base.render orelse return;
render.renderOutput(output);
}
Both projects use different programming languages and approaches to rendering. i3 uses C and focuses on rendering individual containers, while River uses Zig and handles rendering at the output level. River's code appears more modern and takes advantage of Zig's features, while i3's code is more traditional C.
A tiling window manager based on binary space partitioning
Pros of bspwm
- More mature and stable project with a larger user base
- Extensive documentation and community support
- Highly customizable through external scripts and tools
Cons of bspwm
- Written in C, which may be less accessible for some contributors
- Lacks native Wayland support, limiting its future-proofing
Code Comparison
bspwm (C):
void
monitor_focus(monitor_t *m)
{
if (mon == m)
return;
mon = m;
if (m->desk != NULL)
desk = m->desk;
}
River (Zig):
pub fn focus(self: *Self) void {
if (self == focused_output) return;
focused_output = self;
if (self.active_workspace) |workspace| {
workspace.focus();
}
}
Both projects are window managers, but River is designed for Wayland while bspwm is for X11. River is written in Zig, a newer language that aims to be more memory-safe and easier to use than C. bspwm has a longer history and more established ecosystem, while River represents a more modern approach to window management. The code snippets show similar functionality for focusing monitors/outputs, with River's implementation being slightly more concise due to Zig's syntax.
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Overview
River is a dynamic tiling Wayland compositor with flexible runtime configuration.
Check packaging status â Join us at #river on irc.libera.chat â Read our man pages, wiki, and Code of Conduct
The main repository is on codeberg, which is where the issue tracker may be found and where contributions are accepted.
Read-only mirrors exist on sourcehut and github.
Note: river has not yet seen a stable 1.0 release and it will be necessary to make significant breaking changes before 1.0 to realize my longer term plans. That said, I do my best to avoid gratuitous breaking changes and bugs/crashes should be rare. If you find a bug don't hesitate to open an issue.
Features
Currently river's window management style is quite similar to dwm, xmonad, and other classic dynamic tiling X11 window managers. Windows are automatically arranged in a tiled layout and shifted around as windows are opened/closed.
Rather than having the tiled layout logic built into the compositor process,
river uses a custom Wayland
protocol
and separate "layout generator" process. A basic layout generator, rivertile
,
is provided but users are encouraged to use community-developed layout
generators
or write their own. Examples in C and Python may be found
here.
Tags are used to organize windows rather than workspaces. A window may be assigned to one or more tags. Likewise, one or more tags may be displayed on a monitor at a time.
River is configured at runtime using the riverctl
tool. It can define
keybindings, set the active layout generator, configure input devices, and more.
On startup, river runs a user-defined init script which usually runs riverctl
commands to set up the user's configuration.
Building
Note: If you are packaging river for distribution, see PACKAGING.md.
To compile river first ensure that you have the following dependencies installed. The "development" versions are required if applicable to your distribution.
- zig 0.13
- wayland
- wayland-protocols
- wlroots 0.18
- xkbcommon
- libevdev
- pixman
- pkg-config
- scdoc (optional, but required for man page generation)
Then run, for example:
zig build -Doptimize=ReleaseSafe --prefix ~/.local install
To enable Xwayland support pass the -Dxwayland
option as well.
Run zig build -h
to see a list of all options.
Usage
River can either be run nested in an X11/Wayland session or directly
from a tty using KMS/DRM. Simply run the river
command.
On startup river will run an executable file at $XDG_CONFIG_HOME/river/init
if such an executable exists. If $XDG_CONFIG_HOME
is not set,
~/.config/river/init
will be used instead.
Usually this executable is a shell script invoking riverctl(1) to create mappings, start programs such as a layout generator or status bar, and perform other configuration.
An example init script with sane defaults is provided here in the example directory.
For complete documentation see the river(1)
, riverctl(1)
, and
rivertile(1)
man pages.
Future Plans
Currently details such as how tags work across multiple monitors are not possible for users to configure. It would be possible to extend river's source code to allow more flexibility here but this comes at the cost of complexity and there will always be someone who prefers something slightly different.
My long term plan to address this is to move as much window management policy as possible out of the river compositor process and into the "layout generator" process which will need to be renamed to "window manager." This will give users much more power and control over river's behavior and also enable some really cool workflows. For example, it would be possible to write a window manager in lisp and use hot code reloading to edit its behavior it while it is running.
This is a non-trivial architectural change and will take a while to implement. I plan to focus on this change for the 0.4.0 release cycle. Unfortunately, it will almost certainly break existing river configurations as well. I think the benefits outweigh that downside though and I will do my best to offer a reasonable upgrade path.
Donate
If my work on river adds value to your life and you'd like to support me financially you can find donation information here.
Licensing
River is released under the GNU General Public License v3.0 only.
The protocols in the protocol
directory are released under various licenses by
various parties. You should refer to the copyright block of each protocol for
the licensing information. The protocols prefixed with river
and developed by
this project are released under the ISC license (as stated in their copyright
blocks).
The river logo is licensed under the CC BY-SA 4.0 license, see the license in the logo directory.
Top Related Projects
i3-compatible Wayland compositor
Hyprland is an independent, highly customizable, dynamic tiling Wayland compositor that doesn't sacrifice on its looks.
A Wayland window-stacking compositor
A modular and extensible wayland compositor
A tiling window manager for X11
A tiling window manager based on binary space partitioning
Convert designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot