I’ve been spending my time getting used to Spacemacs for my main editor. The slowness of its startup time could rival Atom, but it shouldn’t be! In this post I’ll go through how I make my Spacemacs start in milliseconds.
If you haven’t heard of Spacemacs before, it’s an Emacs distribution built to end the holy war of Vim vs. Emacs by integrating the best of both worlds. If you’re a hardcore Vim user, using Spacemacs will make you feel right at home. Among others, it provides the ergonomic and productive Vim keybindings on top of the powerful Emacs platform, while also providing discoverability of the keybindings through the
SPC leader key. Neat.
(I’m not a good marketer, so there’s a pretty good chance that you don’t buy my pitch, but please visit the official site and have a look around!)
This post assumes the following:
- You have Emacs ≥ 24.x installed
- You have Spacemacs installed
Okay, let’s get on with it!
Oh, the slowness!
After Spacemacs is successfully installed, each time you start Emacs you would be greeted by a long startup time. Indeed, the main Spacemacs buffer tells me the following:
251 packages loaded in 10.237s (e:193 r:2 l:10 b:46)
Believe it or not, on my machine sometimes it takes ~10 seconds to start a new Emacs instance. Preposterous! It’s even on par with Atom, but Atom has the excuse of it being an Electron app. It doesn’t make any sense.
So I dug around the internet looking for a way to speed up things. My goal was to see if I could make it open faster than Sublime Text, and we know how blazingly fast Sublime is. Note that I’m basically an Emacs noob so I don’t have any idea where to look.
And finally, it turns out that, just as with most of the things in my life, I’ve been doing it all wrong.
Hello, Emacs server!
When you install Emacs, there’s also this little binary that got distributed alongside it called
emacsclient, and that is the most powerful hint. It appears that Emacs is meant to be used as a persistent server daemon, where you can connect to it to edit files.
I’ve come across this post that says it is best practice to leave an editor instance running, and use the
emacsclient program to connect to it. Sadly, I’m a bit of a clean freak and I don’t like idle windows cluttering my desktop. What’s even more annoying, if you accidentally close the window (or frame as we call it in Emacs world), you have to go through the painful startup process again.
Luckily, I can accommodate my clean-freak trait. There are two steps involved: writing a shell script and overriding a default keybinding.
The `em` shell script
Emacs has a flag that lets it run as a server in the background, by using
emacs --daemon. It is also nice that if you run
emacsclient -a '', if there isn’t an Emacs daemon running, it will start one (basically calling
emacs --daemon) and connect to it.
So I’ve written the following shell script (inspired by this superuser question) called
em that takes care of things for me:
#!/usr/bin/env zsh# Checks if there's a frame open
emacsclient -n -e “(if (> (length (frame-list)) 1) ‘t)” 2> /dev/null | grep t &> /dev/nullif [ “$?” -eq “1” ]; then
emacsclient -a ‘’ -nqc “$@” &> /dev/null
emacsclient -nq “$@” &> /dev/null
The script will check if there’s an Emacs frame (window) open. If there isn’t one, it will run
emacsclient -a '' -nqc "$@", which will start the Emacs daemon if necessary and create a new frame (via the
-c option), passing the arguments given to the script. Else, it will just call
emacsclient sans the
-c flag to open the given file in an already open frame. I just need one open frame at a time.
With this script, I can edit any file using the command
em anyfile.anyext from my terminal. Great, but not enough!
Making sure that closing a frame doesn’t kill Emacs
The previous shell script will make sure that it will start a daemon if it doesn’t exist. However, closing a frame created by
emacsclient will still kill the daemon. Urgh! It’s no different than the original solution from the above post.
There’s a command, called
spacemacs/frame-killer, that will just kill the frame without killing the daemon. Unfortunately, it is bound to
SPC q z, which is arguably not the most ergonomic key combo ever. It’s hard to hit the
q z stroke with your left hand, so I wanted to rebind it to something else.
Spacemacs has the commands
spacemacs/kill-emacs, which is bound to
SPC q Q, and
spacemacs/prompt-kill-emacs, bound to
SPC q q. I don’t get the difference between the two, and it seems redundant, so I think
SPC q q will serve well as the alternative that I can bind
I rebind it by adding the following snippet into the body of
dotspacemacs/user-config function in my
“q q” ‘spacemacs/frame-killer)
Don’t forget to reload the configuration with
SPC f e R after modifying it. Now
SPC q q will behave as
frame-killer, and I can still use
SPC q Q if for whatever reason I need to kill the Emacs daemon. What’s also great is that Vim’s
:q behaves just like
Putting it into practice
So let’s compare it. With no Emacs daemon running, Let’s start Emacs and see how long it takes:
$ time em
em 0.01s user 0.02s system 0% cpu 8.835 total
Yikes, nearly 9 seconds to an open frame. Let’s close the frame with
SPC q q and try that again:
$ time em
em 0.01s user 0.01s system 17% cpu 0.100 total
It now takes just 0.1 seconds to an open frame. Talk about major improvement!
Trying out editors has been a bimonthly habit of mine this past year. This is actually my second time having a look at Spacemacs, and this discovery of making it just as fast as Sublime might actually be the thing that take me away from my current favorite editor for years, Atom.
In this post I’ve managed to cut down startup time by starting Emacs as a persistent server daemon and using the
emacsclient binary to connect to it. I also rebind
SPC q q to close a frame without killing the Emacs daemon, so that subsequent Emacs invocation would take less than a second to open.
With this setup, I can keep my desktop clean and be sure that whenever I want to edit anything, the Emacs daemon will have my back.