Chatting on Matrix/Riot with end to end encryption from within Emacs

Iʼm a happy user and administrator of a Matrix instance. Itʼs a pretty lonely one (iʼm the sole user of it) but i faced a lot of pros and cons of it in the last few years. In case you havenʼt heard about Matrix yet, itʼs a messaging framework which, for a few years now, supports end to end encryption (E2EE). It also serves as the base of a federated chat service you might know as Riot.

Another thing iʼm also fond of is Emacs. Itʼs a great little UI for pretty much everything i do, from note taking through managing email and calendar to software development. It even has a Matrix client, matrix-client.el, written by well-known (in Emacs circles at least) Ryan Rix (rrix) and alphapapa. I tried it several times, but at the end i always came back to the official Riot client because we use Emacs E2EE both at my company and in private with some friends, and unfortunately matrix-client.el doesnʼt support it.

As this is the case with many other clients, like Fractal, some awesome folks of the Matrix community wrote Pantalaimon to solve this problem. It’s a Matrix proxy that can do E2EE for clients that donʼt support it natively.


Setting up Pantalaimon is really easy: you pip install it, write a 4 lines long config fire, and you are ready to go. Just make sure you have a valid certificate if you use HTTPS; Pantalaimon wonʼt connect if not, and will communicate this problem poorly.

Homeserver =
ListenAddress =
ListenPort = 8765

You simply start it with pantalaimon or, if you are a systemd fan user, you can use the service file from their repository with a slight change in the path.


Coming up next, the Emacs Matrix client.

The fastest route for me was to add quelpa and quelpa-use-package to my config, and install matrix-client.el using those. The only tricky part is that iʼm lazy, so i have use-package-always-ensure enabled which doesnʼt play nice with Quelpa installed packages that are not otherwise available on MELPA (or any other repository you might have enabled), hence the :ensure nil clause.

;; Don’t use it unless you are lazy enough to do extra work later
(customize-set-variable 'use-package-always-ensure t)

(use-package quelpa)

(use-package quelpa-use-package
  :after quelpa)

(use-package matrix-client
  :after quelpa-use-package
  :ensure nil  ;; you only need this if you have `use-package-always-ensure' set to non-nil
  :quelpa (matrix-client :fetcher github :repo "alphapapa/matrix-client.el"
                         :files (:defaults "logo.png" "")))

Run it!

At this point you are ready to go. In Emacs, run M-x matrix-client-frame or use the standalone script $HOME/.emacs.d/elpa/matrix-client-VERSION/ to run it in a separate process (might be a better choice if your server is lagging a lot).

When matrix-client.el is asking for your credentials, you just enter them: your User ID (MXID, looks like and your password is as usual. Your server should be the one you specified in your Pantalaimon config as the listening IP and port, so in my example it would be http://localhost:8009. If you donʼt need E2EE, then you can simply enter your homeserverʼs address here (and thus you donʼt need Pantalaimon).

You are all set! Happy (secretive) chatting, enjoy doing everything from your favourite OS, Emacs!

contacts & more