PaperWM.spoon for macOS: Installation and First Tiling Setup
Tiled scrollable window manager for MacOS
At a glance
- What is it?
- PaperWM.spoon adds scrollable, grid-based window tiling to HammerSpoon on macOS. It fits keyboard-driven users who want precise window placement, but installation changes Mission Control settings and the project has no published releases.
- Who is it for?
- Adopt PaperWM.spoon if you already use HammerSpoon and want keyboard-driven, scrollable tiling on macOS. Do not choose it if changing Mission Control behavior is unacceptable or if you need a packaged release with documented upgrade procedures.
- Can I use it commercially?
- Yes. MIT 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 10 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 PaperWM.spoon Adds a Tiling Layer to macOS
PaperWM.spoon addresses a specific gap in the normal macOS window workflow: applications remain free-floating unless the user repeatedly resizes and positions them. This project is aimed at macOS users who already use HammerSpoon and want a tiled, horizontally scrollable arrangement without leaving their applications. It is not a standalone desktop. The README describes it as a Spoon plugin, so HammerSpoon must be installed and configured before PaperWM.spoon can manage windows.
The project takes its tiling concept from PaperWM, but its delivery model is different. PaperWM.spoon is implemented in Lua and exposes actions through the HammerSpoon API. Once started, it automatically tiles new and existing windows. The user can move focus through the grid, resize a selected window, move windows between columns, separate floating windows from the tiled layer, switch Mission Control spaces, and send focused windows to another space.
This scope makes PaperWM.spoon most relevant to keyboard-oriented developers and other users who spend substantial time arranging terminals, editors, browsers, and documentation windows. It also introduces a large hotkey surface. The documented setup binds arrow keys, letters, number keys, Space shortcuts, and floating-window commands. Users who prefer direct window dragging may gain little from the plugin and will have to learn those bindings.
How PaperWM.spoon Organizes Windows and Actions
Based on the repository layout, the implementation is divided into Lua modules with focused responsibilities. `tiling.lua` contains the tiling logic, while `windows.lua` deals with window operations. `state.lua` appears to hold internal window state. Floating windows, Space tracking, Mission Control, swipe handling, events, and actions each have separate files. `init.lua` and `config.lua` form the public entry and configuration layer.
The README demonstrates a tiled grid in which directional actions select adjacent windows. Separate swap actions move the focused window through that grid. Width and height commands resize the current window, while column-oriented actions such as `slurp_in`, `barf_out`, and `toggle_stack` change how it participates in the layout. This is a layout model with explicit columns and layers, not a simple grid snapper.
State also crosses macOS Space boundaries. The documented hotkeys can focus windows within the current Space, switch to recent or numbered Spaces, move a focused window to another Space, and retile windows. `space_tracker.lua` and `mission_control.lua` indicate that Space identity and transitions are central concerns rather than incidental integration. `floating.lua` separates unmanaged windows from the tiled set, and `swipe.lua` provides a navigation input path.
Actions are available programmatically through `PaperWM.actions.actions()`, which returns action names and functions. That matters for users who do not want the README's default shortcut scheme. A custom modal layer can bind selected actions to `h`, `j`, `k`, and `l`, leaving the rest of the mapping under the user's control.
Installing PaperWM.spoon and Preparing Mission Control
The direct installation method clones the repository into HammerSpoon's `Spoons` directory. Run this in a shell while HammerSpoon's configuration directory already exists:
git clone https://github.com/mogenson/PaperWM.spoon ~/.hammerspoon/Spoons/PaperWM.spoonAfter the command completes, `PaperWM.spoon` should be present under `~/.hammerspoon/Spoons/`. This step copies the plugin source but does not yet load it.
The README requires two macOS settings. Open `System Preferences`, then `Desktop and Dock`, scroll to `Mission Control`, uncheck `Automatically rearrange Spaces based on most recent use`, and enable `Displays have separate Spaces`. These are operating-system settings rather than Lua options. They alter how Spaces behave before PaperWM.spoon starts.
HammerSpoon users can instead configure installation through `SpoonInstall`. The following is the repository's documented example:
hs.loadSpoon("SpoonInstall")
spoon.SpoonInstall.repos.PaperWM = {
url = "https://github.com/mogenson/PaperWM.spoon",
desc = "PaperWM.spoon repository",
branch = "release",
}
spoon.SpoonInstall:andUse("PaperWM", {
repo = "PaperWM",
config = { screen_margin = 16, window_gap = 2 },
start = true,
hotkeys = {
< see below >
}
})There is a repository detail worth checking before using this route. The default branch is `main`, but the README's `SpoonInstall` example explicitly selects `release`. The README does not explain the branch difference, so this example should not be treated as proof that both branches have identical content or update behavior.
Starting PaperWM.spoon with a Focused Keyboard Setup
For a first real use, load the Spoon and bind a small set of actions from `~/.hammerspoon/init.lua`. This shortened configuration keeps the initial workflow centered on focus and window movement:
PaperWM = hs.loadSpoon("PaperWM")
PaperWM:bindHotkeys({
focus_left = {{"alt", "cmd"}, "left"},
focus_right = {{"alt", "cmd"}, "right"},
focus_up = {{"alt", "cmd"}, "up"},
focus_down = {{"alt", "cmd"}, "down"},
swap_left = {{"alt", "cmd", "shift"}, "left"},
swap_right = {{"alt", "cmd", "shift"}, "right"},
full_width = {{"alt", "cmd"}, "f"}
})
PaperWM:start()Calling `PaperWM:start()` begins automatic tiling for both new and existing windows. The directional keys should move focus through the tiled arrangement. The modified arrow bindings move the focused window, while `full_width` applies the documented full-width action. These mappings are part of the README's larger table, reduced here to make the first startup easier to inspect.
To use the complete documented defaults instead, replace the explicit table with:
PaperWM = hs.loadSpoon("PaperWM")
PaperWM:bindHotkeys(PaperWM.default_hotkeys)
PaperWM:start()Calling `PaperWM:stop()` releases control over windows. That explicit stop operation is important for troubleshooting or temporarily abandoning the tiled layout, although the README does not document what visual state macOS restores to each affected window after `stop()`.
PaperWM.spoon Spacing, Floating Windows, and External Bars
PaperWM.spoon exposes layout spacing through `PaperWM.window_gap`. A single number applies the same gap between windows and screen edges. A table can set each edge independently:
PaperWM.window_gap = 10For asymmetric spacing, use named side values instead:
PaperWM.window_gap = {
top = 10,
bottom = 8,
left = 12,
right = 12
}The tiling system also recognizes a floating layer. The documented `toggle_floating` action moves the focused window into or out of that layer, while `focus_floating` raises floating windows above tiled windows. This is necessary because a strict window manager would otherwise prevent dialogs or other windows that should remain independent from participating in the grid.
For screen real estate occupied by custom status bars, the README says to set `PaperWM.external_bar` to a table specifying `top` and `bottom`. It specifically names Sketchybar as a possible integration. The README does not supply a complete `external_bar` example, so the setting is documented as an extension point rather than a fully specified configuration.
Users who do not need per-side gaps, a floating layer, Space management, or custom bars may be paying for unnecessary complexity. The plugin exposes more layout concepts than a basic drag-to-edge or grid-snapping utility, and the complete binding table adds another configuration surface to maintain.
PaperWM.spoon Constraints Compared with Native Window Management
The first constraint is platform dependence. PaperWM.spoon is a HammerSpoon Spoon for MacOS, written primarily in Lua. The installation and usage documentation do not describe Linux, Windows, or a standalone distribution. A user who does not already operate HammerSpoon would need a separate macOS automation layer before this project becomes usable.
The second constraint is the required Mission Control configuration. Disabling automatic Space rearrangement can conflict with an existing desktop workflow, particularly for someone who depends on macOS selecting Spaces by recency. Separate Spaces are also a global desktop setting. Although `toggle_floating` exists for individual windows, it is not evidence that PaperWM.spoon can avoid every global operating-system preference.
Compared with macOS's built-in window placement, PaperWM.spoon adds automatic tiling, a scrollable grid, column operations, keyboard movement, width and height cycles, floating windows, and per-Space management. Compared with arranging windows manually, it shifts layout work into Lua actions and HammerSpoon hotkeys. The trade-off is control versus complexity: users gain repeatable commands but must configure applications and accept a changed Space model.
The README does not document recovery for a partially failed retile, behavior for every application window type, or rollback for a broken configuration. It does expose `refresh_windows` and `refresh_windows_forcedly`, but their exact failure conditions are not described.
PaperWM.spoon Maintenance, Releases, and MIT Use
The repository is not archived. Its last push was on 2026-10-13, but recent activity is not the same as a stable release process. The repository has no GitHub releases, so there is no published release number, release note, or documented upgrade command to rely on. Direct installation from a branch also leaves the branch-selection decision with the user, especially because the README's `SpoonInstall` example names `release` while the repository's default branch is `main`.
Upgrading a `git clone` may therefore require pulling repository changes manually, but the README does not provide an upgrade tutorial. Before replacing an existing local checkout, a user would need to inspect the repository's own revision state and preserve any local edits. This is an operational consequence of the documented installation model, not a project-specific upgrade guarantee.
The repository uses the MIT License. In practical terms, the license permits use, modification, distribution, and sublicensing subject to its conditions, while copyright and license notices must be retained. Distribution may also require the applicable notice text. This is a license summary rather than legal advice, and it does not establish compatibility with every organization policy.
The absence of releases raises the verification burden for adopters. Check the selected branch, local modifications, and HammerSpoon behavior after any source update. The repository's current push date supports continuing evaluation, but it does not replace release notes or a documented migration path.
Editorial conclusion
Adopt PaperWM.spoon if you already use HammerSpoon and want keyboard-driven, scrollable tiling on macOS. Do not choose it if changing Mission Control behavior is unacceptable or if you need a packaged release with documented upgrade procedures. Verify first that your preferred hotkeys are available, that separate Spaces support fits your workflow, and whether the `release` branch named by the SpoonInstall example is suitable for your installation.
Frequently asked questions
What prerequisites does PaperWM.spoon require?
PaperWM.spoon requires HammerSpoon on MacOS and a directory at `~/.hammerspoon/Spoons/` for the manual installation path. Its documented macOS setup also changes two Mission Control settings related to Space behavior.
How do I start and stop PaperWM.spoon?
Add `PaperWM:start()` to `~/.hammerspoon/init.lua` to begin automatically tiling new and existing windows. Calling `PaperWM:stop()` releases control over the windows.
Which branch does the PaperWM.spoon SpoonInstall example use?
The README's `SpoonInstall` example sets `branch = "release"`, even though the repository's default branch is `main`. The README does not explain the difference between those branches.
Can PaperWM.spoon keep some windows outside the tiled layout?
Yes. The documented `toggle_floating` action moves a focused window into or out of the tiling layer, while `focus_floating` raises floating windows above tiled windows.
Does PaperWM.spoon publish versioned releases?
The repository has no GitHub releases. The README documents installation through `git clone` or `SpoonInstall`, but it does not provide versioned upgrade instructions.
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/mogenson-paperwm-spoon)Was this useful?