Jotain is a "use-package + Nix" configuration: Nix provides most packages on load-path, so use-package finds them without touching the network; anything Nix does not ship falls through to MELPA at install time.
:ensure nil.
nix/mk-overlay.nix) scans the use-package declarations and maps them to the emacs-overlay package set; archive-absent packages (e.g. claude-code-ide, combobulate) are built in nix/extra-packages.nix. These also use :ensure nil because Nix already put them on the load path.
use-package block. use-package-always-ensure is t (set in early-init.el), so these default to "install if missing" without any extra boilerplate. Archives are registered in init.el:
(add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
(add-to-list 'package-archives '("nongnu" . "https://elpa.nongnu.org/nongnu/") t)
When built with default.nix (the full distribution — just build and friends), Jotain ships every tree-sitter grammar in nixpkgs via emacsPackagesFor emacs |> withPackages (epkgs: [ epkgs.treesit-grammars.with-all-grammars ]). The grammar bundle is exposed through TREE_SITTER_DIR; early-init.el picks that up and adds it to treesit-extra-load-path so every built-in *-ts-mode finds its grammar out of the box.
nix/extra-packages.nix defines the Elisp packages that are not on any archive (MELPA, GNU ELPA, NonGNU ELPA), so Nix builds them directly via trivialBuild from pinned revisions and puts them on load-path:
ghostel — Ghostty terminal integration.
jylhis-emacs-themes — the design-system themes; their revision comes from nix/design-pin.nix, the single pin shared with the website’s vendored CSS.
claude-code-ide — fetched from manzaltu/claude-code-ide.el, built with websocket and web-server as runtime dependencies (transient is built in to Emacs 30+).
combobulate — fetched from mickeynp/combobulate; all its dependencies (seq, map, treesit) are built in to Emacs 30+.
majutsu — Magit-style porcelain for Jujutsu (jj), wired in init-vc.el.
tagref — Emacs integration for the tagref cross-reference checker.
All are consumed by use-package ... :ensure nil blocks in the relevant init-*.el module and wired into the distribution by nix/mk-overlay.nix.
The devenv shell provides tooling only — linters, language servers, the docs chain, fonts. Emacs itself is not in the shell (see the top-of-file note in devenv.nix); build and launch the editor with just run-built.
Most of the time you just need a use-package block in the appropriate init-*.el module — :ensure t is implicit thanks to use-package-always-ensure:
(use-package some-package :mode "\\.ext\\'" :custom (some-package-option t) :config ;; configuration here )
If the package is not on any archive, add it to nix/extra-packages.nix with trivialBuild so it is built from a pinned GitHub revision and available on load-path, then declare it with :ensure nil in the module.
One invariant to know: the Nix side (nix/use-package.nix) parses the Elisp — it does not evaluate it. use-package forms must stay top-level (not wrapped in when/let/macros) and not :disabled, or the package silently drops out of the Nix-provided set even though the Elisp still works interactively.