How to Install, Customize and Backup Suckless Tools

Table of Contents

How to Install, Customize and Backup Suckless Tools

By Ronnie Nissan at April 18, 2020


The suckless tools, especially dwm, st and dmenu, are some amazing pieces of software, that allow a great flexibility while being minimal. But they come at a cost, yes, Libra software is free as both in freedom and as in beer (most of the time), but you should make an effort to be able to use it, and that effort (cost) is much needed when it comes to the sucklees tools.

I used dwm, st and dmenu about a year ago, but I had no idea how to manage and backup them, I didn’t know a lot about customizing (patching) them, but recently I started learning C programming language, and so I decided to use all three, as I will have to edit the source code to make any changes and so this will help me in my endeavor of learning C.

The reason I am making this tutorial is to help you get started with using dwm, st and dmenu too. This tutorial is my own personal experience and knowledge and has no connection to the guys at suckless, nor it is the best how-to guide.

This tutorial will assume you have a basic knowledge in Linux and you are able to install packages through your distro’s package manager and solve dependencies, and that you use xinit to login to your xorg-session.


To install any of the above three, you’ll need to have some libraries and git installed in your system, you can install them as following;

On Void Linux:

sudo xbps-install -S git make libX11-devel libXinerama-devel

On Debian and Debian-based distros:

sudo apt-get install build-essential libx11-dev libxinerama-dev sharutils

And on Arch and Arch-based distros:

sudo pacman -S git make libx11 libxinerama


Clone dwm from

git clone
cd dwm/
sudo make install

Then all that’s left is that you put the following to your .xinitrc then start x with startx (nice!).

exec dwm

This will give you an untouched dwm experience like the guys at suckless intended it.


Clone st from

git clone
cd st/
sudo make install

And this will install st, unmodified, on your system. Just note that st doesn’t have a .desktop file by default, which means you will not find it in menus (like dmenu), however st it is the default terminal in dwm and it is bound to ALT + Shift + Return.


Clone dmenu from

git clone
cd dmenu/
sudo make install

Now dmenu is installed on your system. In dwm, alt + p is bound to launching dmenu.


By now you should have a working (in the suckless philosophy way) system, but maybe you want to edit some colors, add some features through patching those programs to make them even more usable, or just more pleasant to look at.

NOTE: It is recommended that you make a copy of the config.def.h file and name it config.h and make your edits to this new file, so that when you update dwm for example and you get the new config.def.h it will not overwrite your modifications. However I don’t do that, I edit the config.def.h and the config.h is generated automatically when I compile and install. This way when a patch edits the config.def.h, I can just delete config.h and recompile.


To edit dwm, you’ll have to cd into the dwm directory and edit the config.def.h, remember to remove the config.h file before recompiling (see note above). And here I’ll explain some parts of the config file.

Font and Color-scheme

In the lines 8 and 9 you can set the font, and the font size of the dwm, and also dmenu if you don’t want to edit your dmenu installation and launch it through the dwm defined flags on line 59.

From line 10 to line 19 in your config.h file, you’ll see the following

static const char col_gray1[]       = "#222222";
static const char col_gray2[]       = "#444444";
static const char col_gray3[]       = "#bbbbbb";
static const char col_gray4[]       = "#eeeeee";
static const char col_cyan[]        = "#005577";
static const char *colors[][3]      = {
	/*               fg         bg         border   */
	[SchemeNorm] = { col_gray3, col_gray1, col_gray2 },
	[SchemeSel]  = { col_gray4, col_cyan,  col_cyan  },

In the lines from 10 to 15 you’ll see some constants of type character defined. These are six colors, which you can change to whatever you like, you can also change the names of the constants for example:

static const char normalbg[]       = "#0ff000";

Then on the lines 17 and 18 we are setting the defined constants to the element we want which are SchemeNorm and SchemeSel from the *colors constant, the first color is the foreground (fg) second is the background (bg) and the third is border color. Edit those to your liking, recompile, install and exit and log back into dwm to see your changes.

The rules

From line 30 to 31 you’ll see some rules set for gimp and Firefox

/* class      instance    title       tags mask     isfloating   monitor */
{ "Gimp",     NULL,       NULL,       0,            1,           -1 },
{ "Firefox",  NULL,       NULL,       1 << 8,       0,           -1 },

You can write rules for other programs and remove the ones set as you like. What you need to know is the class of the program which can be found using xprop. Then you can use it under “class”, keeping both “instance” and “title” as NULL (most of the time). If you set “isfloating” to 1, the program will spawn in floating mode. Under “monitor” you set which monitor the program will spawn on.

The “tags mask” is a bit tricky, but it is easy once you know how it works. Those are bit-wise operators (which I myself don’t fully understand to be honest) but if all you want to do is to spawn Firefox on the ninth tag (default behavior) you’ll have to set tag mask to “1 << 8” which means 1 shifted to the left by 8, corresponding to the ninth tag. So the tags by default are “000000001”, when the 1 is in the rightmost position (ninth from left to right) you are on tag 1. “1 << 8” means to put the “1” in the leftmost position 100000000 (first position from left), which is tag nine.

If you want Emacs for example to open on tag 3 and in floating mode you’ll add this line to the above code:

{ "Emacs",     NULL,       NULL,       1 << 2,            1,           -1 },

Which translates to “000000100”. If you want to learn more about tag masks, check the “How does a tag-mask work?” at (in the links section below).


I will not cover key bindings because I use sxhkd for custom keybindings, but if you want to use dwm key daemon or you just want to edit a few of the defaults, a look at the config from line 46 to line 96 will help you as it is self explanatory. If you want to change the mod key from alt to super key, you can edit line 47 and change it from Mod1Mask to Mod4Mask. This is more than enough to get you a customized dwm and you can start living in it from this point, but if you want to learn how to patch it, go to the “Patching” section of this page.


The Simple Terminal is amazing, fast and has the best font rendering (second only to Alacritty) in my opinion. But it lacks some basic functionality by default which I’ll address under the “Patching” section. But for just changing some of the default bindings and color schemes, you’ll do the same as you did with dwm: go to the st directory, and edit the config.def.h file, remove the config.h file and recompile.

Font and Padding

To edit the font and the padding you’ll have to edit lines 8 and 9, to set the font to Hack, size to 14, and padding to 8, you’ll do the following:

static char *font = "Hack:pixelsize=14:antialias=true:autohint=true";
static int borderpx = 8;


To change st’s default color-scheme you’ll have to edit lines 86 to 112:

/* Terminal colors (16 first used in escape sequence) */
static const char *colorname[] = {
	/* 8 normal colors */

	/* 8 bright colors */

	[255] = 0,

	/* more colors can be added after 255 to use with DefaultXX */

Cursor Shape

St have four cursor shapes defined by default:

 * Default shape of cursor
 * 2: Block ("█")
 * 4: Underline ("_")
 * 6: Bar ("|")
 * 7: Snowman ("☃")

To change the cursor to any of the above you have to edit the line 131 and set it to the number corresponding to the shape you want.

static unsigned int cursorshape = 2;

This is the basic customization that you can do to st to make it more pleasant to look at.


You customize dmenu the same way you did with st and dwm, by editing the config.def.h, removing config.h and recompiling. Dmenu is a flexible and simple program that you can do a lot with, I use it to set my wallpaper, change my monitor layout, as a power-menu etc. You can pipe things into dmenu and paste the output to stdout. Which makes it extensible through scripting.

Note! Please remember that if you want to use your own build of dmenu, you’ll have to remove some things from dwm, the things to be removed from config.def.h of dwm are the following: in line 59, everything between <> should be removed

static const char *dmenucmd[] = { "dmenu_run", "-m", dmenumon, <"-fn", dmenufont, "-nb", col_gray1,
                                  "-nf", col_gray3, "-sb", col_cyan, "-sf", col_gray4,> NULL };

Font and color-scheme

To change the font of dmenu you should edit the line 7 and set it to the font you want.


Changing the color-scheme is the same as in dwm, but here we set the colors inside the *colors constant directly.

[SchemeNorm] = { "#bbbbbb", "#222222" },
[SchemeSel] = { "#eeeeee", "#005577" },
[SchemeOut] = { "#000000", "#00ffff" },

First one is the foreground and the second one is the background. The first line is for the Normal entries and the second line is for selected entries. If you want to watch a good video about dmenu, I recommend you watching Luke Smith’s video on it.


Patching is how you extend the suckless tools with features they lack out of the box that either make them more usable or enhance the look and feel of them, like adding the ability to scroll back in st and gaps in dwm. To apply a patch you must go to first. Download the patch you want to apply to the source-code directory of the software you want to apply it to. Then you’ll do the following.

sudo make clean
git remove config.h
git branch <name of the patch>.def
git checkout <name of the new branch>
patch -p1 < <name of the patch>

At this point, if all the hunks were successful, you will do:

git status #and check which files were modified, then do
git add <names of the modified files>
git commit -m <enter a of what you are committing here>
git checkout master
git merge <name of the new branch>
sudo make install

If one or more hunks fails, you’ll have to look into the terminal to see which file (or files) was it that the hunks failed to apply to, and you’ll see inside the source code you’ll have a file called …rej so now all you have to do is, open the .rej file in your favorite text editor, look for the lines that have “-” (remove) and “+” (add) right to them, those are the lines you have to remove and add. Then you’ll need to repeat the above steps.

In case you want to remove a patch you’ve applied you have to run the command:

patch -R < <name of the patch>.def

If you want to learn more about patches check out the Hacking page from and you can also watch DistroTube’s video on patching dmenu.

### Backup When you customize any of the suckless tools to your liking, you’ll know it is not as easy as editing a config file, especially after you patch them. So keeping a backup of them is not as easy as saving a dotfile to a git repository and linking it to .config/name-of-program. In this section I’ll show you the steps to make a backup of your suckless tools while still having the ability to update them when a new version comes out (which doesn’t happen that often).

First of all you have to be in the directory of the program you want to make a backup of. Then you’ll rename the remote of the git repository from origin to upstream.

git remote rename origin upstream

Then you’ll go to (or gitlab) and make a new repository, call it the same as the program you are backing up for convenience. Then copy the repository’s URL and type:

git add remote origin <the repository's url>

Now if you type:

git remote -v

You’ll see that you have two remotes: one called “upstream” (pointing to and the other one called “origin” (pointing to your repository). Now all that’s left is that you push your build to the master branch of your repository, to do that you type:

git push origin master

If the guys at suckless update the program, all you’ll have to do is go to that program’s directory, and run the following:

git pull upstream master

I think by now you can get around using the suckless tools with ease, customize them and back them up. Which is really amazing because the suckless tools are amazing. Later I’ll be posting more articles explaining how to customize dwm’s bar and how to use sxhkd as your key daemon.

I really hope you enjoyed this article and that it was useful to you.


Author: dt

Created: 2022-02-20 Sun 10:04