Portable emacs config without crazy load time

Search for a command to run...

Was curious to try a new online casino, so I gave Bizzo a go. The platform is user-friendly, with a wide selection of games to keep things fun. The bonuses were what made the experience even better – a generous welcome offer and plenty of promotions. This site is popular in Australia, which gave me peace of mind. The bonuses really made my time here more enjoyable, and I’m happy I decided to give it a try.
Remember my post about switching to VSCode? Well, plot twist: the very next day after publishing it, I switched to WebStorm. And guess what? I've been on JetBrains IDEs ever since. I know, I know. Another "why I switched editors" post. But hear me ou...

I had been doing some basic interpreter work in Go and wanted to redo it in another language to solidify my understanding. Naturally, I chose Odin, it’s another great language, with a Go-like, easy-to-approach syntax and no unnecessary complexity. I ...

Why Emacs Keybindings? I've always preferred Emacs-style editing, especially the way it handles cursor movement and text manipulation. Even though I have switched to using VSCode for most of my development work, I often found myself missing the intui...

In my previous post about building C/C++ projects with CMake, I shared a simple CMakeLists.txt setup for compiling a basic project. Today, I’ll dive into a specific need that many developers encounter: linking libraries directly from project folders ...

Some time ago, I wrote a post about using Vim to look cool and why that’s not a good idea. Now, funny enough, here I am—having switched to VSCode after years of hopping between Vim and Emacs. This isn’t one of those "Vim sucks, I'm going back to VSCo...

Imagine you can just use package-install to install any Emacs package and have a painless way to reinstall the same packages when you move to a new system.
usually what happens is when you install some package, Emacs modifies your custom-set-variables block to include the newly installed package in the package-selected-packages variable. But this does not anything special to install these packages on a new system (as far as I know). So when you are on a new system you still have to manually install all the packages present in this block to get your Emacs running without any issues.
So I wrote a script that I can just run on a new system which would read the package-selected-packages variable and install all the relevant packages for me.
Let's go over how to get this set up.
custom-fileAdd the following to your Emacs config to make sure the auto-generated custom-set-variables block is saved to a separate file.
(setq custom-file "~/.emacs.d/custom.el")
(load custom-file)
Create a file called sync.el in your Emacs configuration folder with the following contents.
(require 'package)
(load-file "~/.emacs.d/custom.el")
(print package-selected-packages)
;; Add melpa
(add-to-list 'package-archives
'("melpa-stable" . "https://melpa.org/packages/") t)
(package-initialize)
;; refresh packages
(setq my/package-refreshed-p nil)
(defun my/refresh-contants ()
(unless my/package-refreshed-p
(progn
(package-refresh-contents)
(setq my/package-refreshed-p t))))
(dolist (pkg package-selected-packages)
(condition-case err
(progn
(let ((pkg-name (symbol-name pkg)))
(eval (if (package-installed-p pkg)
(print (concat pkg-name " already installed!"))
(progn
(print (concat "Installing: " pkg-name))
(my/refresh-contants)
(package-install pkg))))))
(error
(message "Failed to install package: %s. Error: %s" pkg err))))
This script will go through all the packages listed in package-selected-packages and install any that aren’t already on the system.
The key thing here: we don’t call this script during regular Emacs startup. That means package-refresh-contents is never called when Emacs is starting up normally. So no extra load times! You only run this sync.el script when setting up a new system or installing your packages. The rest of the time, Emacs stays fast as usual.
#!/bin/bash
emacs -q --script ~/.emacs.d/sync.el
$ sudo chmod +x ~/.emacs.d/sync
That’s it! Now, running ~/.emacs.d/sync will install any packages listed in your custom-set-variables block.
This technique is actually inspired by Doom Emacs. Alternatively, you could use use-package with :ensure t to handle package installation automatically. But honestly, I find that approach makes your config pretty beefy when you have a lot of packages. Adding a use-package block for everything feels clunky. And yeah, it might avoid the need for this script, but I like the simplicity of just listing the packages and not having to write a bunch of boilerplate.
This setup works perfectly for me—it's lightweight, avoids the usual slowdowns, and gets my Emacs ready in no time!