split-monitor-workspaces gives Hyprland per monitor workspace numbering
A small lua package for Hyprland to provide awesome-like workspace behavior
At a glance
- What is it?
- split-monitor-workspaces is a Lua package for Hyprland 0.55 and newer that splits a set of workspaces across monitors with independent numbering, keeps persistent workspaces per monitor, and binds keys to the nth workspace of the focused monitor.
- Who is it for?
- Adopt split-monitor-workspaces if you run Hyprland 0.55 or newer with the Lua config and want the dwm style behaviour of separate workspace numbering on each monitor, or want persistent workspaces created automatically as monitors come and go. Do not adopt it if you are still on the C++ config, since the plugin path documented in docs/cpp-plugin.md is marked for deprecation when Hyprland 0.57.0 releases, and do not expect packaged releases, as the repository has none.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 27 days ago.
- What is it written in?
- Mainly Lua, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Why Hyprland's global workspace numbering annoys dwm users
Hyprland numbers workspaces globally, so the tenth workspace is the tenth workspace on every monitor. That is fine for a single screen and wrong for a multi monitor desk where a dwm or awesome style layout is expected, where each monitor has its own set of numbered tags and the key you press means something different depending on which screen you are looking at. split-monitor-workspaces is a small Lua package for Hyprland that provides awesome and dwm like behaviour with workspaces: it splits them between monitors and provides independent numbering. The audience is specific: Hyprland users on a multi monitor setup who have been writing their own dispatch rules to work around the global numbering, and who also want workspaces to persist per monitor instead of evaporating when a monitor is unplugged. The plugin keeps that behaviour inside one package with a documented API rather than a pile of hyprctl calls spread across your config.
A small API for focusing and moving windows on the focused monitor
The value of the package is that it hands you bindable functions instead of rules you have to author. The features described in the README are an easy-to-use API to focus or move windows to the nth workspace on the active monitor, with for example SUPER plus N, N being a number on your keyboard, without having to set up complicated rules yourself. The functions used in the binding example are smw.workspace(n) to switch to the nth workspace on the currently focused monitor, smw.move_to_workspace_silent(n) to move the active window to that workspace without a focus change, and smw.get_amount_of_workspaces(), which reports how many workspaces exist so your keybind loop can cover all of them. The silent variant matters for muscle memory: dragging a window to another tag should not pull focus with it.
Cloning the package into the Hyprland plugins directory
Installation is a clone into the Hyprland configuration tree, with no build step for the Lua version:
mkdir -p ~/.config/hypr/plugins
cd ~/.config/hypr/plugins
git clone https://github.com/zjeffer/split-monitor-workspacesThe package is then required from the Hyprland config, and the loader path is extended so that the plugins directory can be resolved:
-- somewhere in your Hyprland config
package.path = package.path .. ";./?.lua;./?/init.lua"
local smw = require("plugins.split-monitor-workspaces")Once the module is imported as smw, you call setup() with the configuration you want. The minimal example creates five persistent workspaces on each monitor at startup:
smw.setup({
workspace_count = 5, -- This will create 5 persistent workspaces on each monitor at startup
})The repository also contains an init.lua, a lua directory and a src directory, plus a Makefile, a hyprpm.toml and a flake.nix, so the same source tree serves the Lua package, the C++ plugin variant and the Nix and hyprpm packaging routes.
A keybind loop that renumbers itself
The documented binding pattern loops over the workspace count and derives the modifier and digit from it, so adding or removing a workspace does not require editing a list of individual binds:
local mainMod = "SUPER"
for i = 1, smw.get_amount_of_workspaces() do
local n = tostring(i)
if n == "10" then n = "0" end -- Optional if you configured 10 workspaces: bind workspace 10 to SUPER + 0
-- Switch to the Nth workspace on the currently focused monitor.
hl.bind(mainMod .. " +" .. n, smw.workspace(n))
-- Move the active window to the Nth workspace on the currently focused monitor silently (no focus change).
hl.bind(mainMod .. " + SHIFT +" .. n, smw.move_to_workspace_silent(n))
endTwo details are worth copying exactly. The number ten is mapped to the zero key with a single conditional, so a ten workspace setup still fits on one row of the keyboard. And the same digit serves two different verbs depending on the modifier, focus versus move, which is the difference between a workspace switch and a window transfer. A full example showing the entire API is kept in docs/example.lua, so the README example is deliberately a starting point rather than the whole surface.
hy3 is detected automatically, the C++ plugin is on the way out
Compatibility with other people's plugins is handled for you. The project states it is explicitly compatible with the hy3 plugin: it automatically detects if hy3 is installed, and if it is, it uses hy3's dispatchers instead of Hyprland's. That is the kind of detail that breaks plugins in practice, where two packages both want to own the dispatcher path and one of them wins depending on load order. The version story matters just as much. The requirement is Hyprland 0.55.0 or newer, and if you are on an older version or have not yet switched to the new Lua config, the project points you at the cpp plugin in docs/cpp-plugin.md, which provides the same functionality. That route is explicitly marked for deprecation when Hyprland 0.57.0 releases, so it is a migration path rather than a destination.
Keeping the plugin on the right branch for your Hyprland version
Because the plugin depends on Hyprland internals that change between releases, branch discipline is part of the install. If you are on the latest Hyprland git commit, the instruction is simply to use the main branch and run git pull to get the latest changes whenever there is an update. If you are on a Hyprland release branch, you should check out the corresponding release branch of the plugin:
# if you're on a 0.55 release, simply run this inside the split-monitor-workspaces repo:
git fetch -Ppft && git checkout release/0.55.x
# if you want to use a specific release instead of a branch, see the https://github.com/zjeffer/split-monitor-workspaces/tags page for a list of all possible tags. For example:
git checkout v0.55.4The advice is to pull the latest changes when Hyprland has a new minor release and to switch to the new release/0.XX.x branch whenever a new major release is created, and if no release branch exists yet the project asks for a GitHub issue. That request tells you something about the maintenance model: this is a repository that tracks an upstream compositor in step, not a package with independent releases.
Waybar shows the split workspaces, and scroll cycles them
Status bar integration is a first class feature rather than an afterthought, and the plugin supports the hyprland/workspaces module of waybar. The upstream configuration for that module sets a format of {icon} and maps five states to five icons: urgent, active for the focused workspace on the current monitor, visible for the focused workspace on other monitors, default, and empty for the persistent workspaces the plugin creates. The scroll handlers are bound to the split-cycleworkspaces dispatcher, with -1 on scroll up and +1 on scroll down, and the recommended setting is all-outputs set to false so that waybar does not draw every monitor's workspaces in every bar. The split-cycleworkspaces dispatcher exists because the ordinary cycleworkspaces dispatcher would move through a numbering that is not per monitor. The project suggests rechecking this configuration every time Hyprland is updated.
No GitHub releases, a permissive licence, and a plugin that tracks its host
Two structural facts bound what this project is. First, the repository has no GitHub releases, so there is no versioned artefact to install: you track a branch, and the tags page lists specific versions such as v0.55.4 that you can check out if you prefer a fixed point. The last push to the repository was on 2026-09-26, and the project is licensed BSD-3-Clause, which is a permissive licence with no copyleft obligation, though the exact terms still belong in your own legal review. Second, this is a plugin for a compositor that moves fast, and the package ties itself to Hyprland internals through version-specific branches. The trade-off is explicit in the repository itself: the C++ plugin exists for older setups and is marked for deprecation at Hyprland 0.57.0, so a user on an old config will eventually have to move to the Lua config whether or not this plugin is in use. The credited lineage also helps when reading the code: the original creator of the plugin is credited, and hyprsome is acknowledged as an earlier project of similar nature, which is a reasonable starting point if you want to see the problem solved differently.
Editorial conclusion
Adopt split-monitor-workspaces if you run Hyprland 0.55 or newer with the Lua config and want the dwm style behaviour of separate workspace numbering on each monitor, or want persistent workspaces created automatically as monitors come and go. Do not adopt it if you are still on the C++ config, since the plugin path documented in docs/cpp-plugin.md is marked for deprecation when Hyprland 0.57.0 releases, and do not expect packaged releases, as the repository has none. Verify first that you are on a matching release/0.XX.x branch of the plugin for your Hyprland version, that the Waybar module is set to all-outputs false, and that the BSD-3-Clause terms fit your distribution model.
Frequently asked questions
How do I install split-monitor-workspaces for Hyprland?
Clone the repository into ~/.config/hypr/plugins with git clone, then extend package.path in your Hyprland config and require the package with local smw = require("plugins.split-monitor-workspaces"). The Lua version requires Hyprland 0.55.0 or newer.
How do I create persistent workspaces per monitor in split-monitor-workspaces?
Call setup with a workspace_count, for example smw.setup({ workspace_count = 5 }). The plugin then creates that many persistent workspaces on each monitor at startup, and it also creates them dynamically when new monitors are connected.
Which branch should I use for my Hyprland version?
Use the main branch if you are on the latest Hyprland git commit, and check out the matching release/0.XX.x branch if you are on a Hyprland release branch, for example git fetch -Ppft && git checkout release/0.55.x. Tags such as v0.55.4 are available for a fixed version.
Does split-monitor-workspaces work with the hy3 plugin?
Yes. The project states it is explicitly compatible with hy3 and automatically detects whether hy3 is installed, using hy3's dispatchers instead of Hyprland's when it is present.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/zjeffer-split-monitor-workspaces)Was this useful?