Node.js window manager for X11 (written at NodeKO 2011)
C++ C JavaScript
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.

NOTE: This is the code as it was at Node Knockout

Go to , that repo will have the latest code in the future.

This repo will not receive any updates and will go out of date, as I will keep it around for historical reasons only.

nwm - node window manager

nwm is a dynamic window manager for X written at NodeKO 2011.

It uses libev to interface with X11, and allows you to lay out windows in Node.

I wrote the code in this repo during Node Knockout 2011. Unfortunately I'm not in the competition since I forgot to confirm my initial team registration (click accept). Not a big deal, my reward is shipping.

The underlying X11 bindings are written as a Node native extension in c. I apologize for the ugliness of the code - if you look at the first commit, I started on Friday with this tutorial, a vague knowledge of X11 and a lot of enthusiasm.

My plan is to dogfood this in the near future to bring it to a more useful state. Right now, I recommend you run it in a secondary X server using Xephyr.


nwm supports all kinds of layouts - you can write your own, or use the default (tiling) layout. It's like dwm, but layouts are enforced in JS rather than in C.

The default nwm.js starts a REPL, so you can issue commands to it interactively.


node-waf configure build
# start Xephyr
Xephyr -screen 1024x768 -br :1 &
# export gedit to the X server on display 1
DISPLAY=:1 gedit
DISPLAY=:1 gnome-terminal
# now start nwm.js on display 1
DISPLAY=:1 node nwm.js


The default nwm.js starts a REPL, so you can issue commands to it interactively:

To list windows:

To manage windows:

nwm.move(window_id, x, y)
nwm.resize(window_id, width, height)

To apply a layout:


nwm also supports workspaces:

nwm.windowTo(window_id, workspace_number);

There are also a couple of easter egg type functions:

nwm.stop(); // stop tweens
nwm.globalSmall(); // set all to 200x200

Writing your own layout engine

You should bind to the following events from the native extension:

  • onAdd(callback). Callback is called with a window object when nwm detects a new window is added. You should store the window object somewhere in JS so you can calculate whatever layout you want.

  • onRemove(callback). Callback is called with a window id when a window is unmapped or destroyed. When received, you should get rid of the window in your layout engine since the window is gone.

  • onRearrange(callback). Called without arguments when windows need to be rearranged - e.g. after all the startup scan of windows is done.

  • onButtonPress(callback). Called with an event. Event.button is the mouse button and x,y are the coordinates.

  • onKeyPress(callback). Placeholder for key events, which are not supported yet.

See nwm.js for a full example.