Skip to main content

Launching Emacs

Current state: the devenv shell provides tooling only — there is no emacs binary in it (see the top-of-file note in devenv.nix). The direct-launch recipes (just run, just debug, just tty, just daemon, just client, just client-tty, just quick) are [DISABLED] stubs that print a notice and exit 0. The supported launch path is just run-built: build Emacs via Nix, then launch it with this configuration. Other docs pages that mention launching point back at this note.
Jotain supports three launch patterns. Pick the one that matches the task — they’re complementary, not alternatives.

One-shot

A fresh emacs process every time. Loads the full Jotain config; pays package-init cost on every launch.
just run-built auto-detects the platform, builds the full distribution (just build; on aarch64-linux the full terminal-only distribution via just build-nox-full), and launches ./result/bin/emacs --init-directory=<repo>, so it never touches ~/.emacs.d. The first invocation pays a nix build (usually a binary-cache pull); reruns launch straight from ./result. Best for sanity checks and trying out config changes. Avoid for day-to-day editing — the startup cost adds up.

Daemon + client

Start Emacs once as a server; reuse it via lightweight clients. The first frame is slow; every frame after is instant.

In the repo (development)

The just daemon / just client / just client-tty recipes are disabled (no Emacs in the dev shell — see the note above). The manual equivalent uses the Nix-built binary:
The daemon blocks; run it in another terminal (or under tmux) and connect with emacsclient from elsewhere. Launching with --init-directory=<repo> keeps it isolated from ~/.emacs.d. Stop the daemon with C-c in its terminal, or from any client:

As an installed user (home-manager)

The services.jotain module ships:
  • A systemd user service (Linux) or launchd agent (macOS) that runs emacs --fg-daemon. Enabled via services.jotain.startWithUserSession.
  • jotain-editoremacsclient --tty with a -nw fallback. Set as $EDITOR when services.jotain.defaultEditor = true.
  • jotain-visualemacsclient --create-frame. Set as $VISUAL.
  • jotctl {start|stop|status|restart|logs} — manage the daemon itself (wraps launchctl on macOS, the jotain systemd user service on Linux). Always on PATH when the module is enabled.
  • A .desktop entry (jotain-client.desktop) for launching a GUI client from your application menu, enabled by services.jotain.client.enable.
See Module Options in the appendix for the full option reference.

Shell aliases

Inspired by Rahul Juliato’s launching-emacs-terminal post, the module can install short aliases for the daemon and clients:
The aliases are written to programs.bash.shellAliases, programs.zsh.shellAliases, and programs.fish.shellAliases — pick up whichever shell home-manager already manages.

Managing the daemon (jotctl)

emd starts a foreground daemon; to manage the supervised daemon (the launchd agent on macOS, the jotain systemd user service on Linux) use jotctl, which is always on PATH when the module is enabled — independent of shellAliases.enable: ¹ The launchd agent sets no StandardOutPath, so macOS doesn’t capture the daemon’s stdout; jotctl logs prints the launchd state instead.

Quick edit (-Q -nw)

When you need a stripped-down Emacs — editing /etc/hosts over SSH, fixing a typo in a 200 MB log file, demonstrating something with no muscle-memory key bindings — bypass Jotain entirely (the just quick recipe is disabled; use any emacs on the host, or the Nix-built one):
This is the pattern Rahul Juliato describes in basic-emacs-alias. -Q skips early-init.el, init.el, site-lisp, and ~/.emacs.d/; -nw keeps it in the current terminal; the wombat theme line is the one concession to readability on dark terminals. To get the same effect anywhere, add an alias to your shell:

Which one to use

Last modified on August 23, 2026