top | item 31833101

Straight.el: next-gen, purely functional package manager for the Emacs hacker

117 points| bjourne | 3 years ago |github.com | reply

40 comments

order
[+] matthberg|3 years ago|reply
I use this in combination with `use-package`.

Here's the relevant section copied from my config, copied from right at the top:

  ;; Straight bootstrap
  (defvar bootstrap-version)
  (let ((bootstrap-file
         (expand-file-name "straight/repos/straight.el/bootstrap.el" user-emacs-directory))
        (bootstrap-version 5))
    (unless (file-exists-p bootstrap-file)
      (with-current-buffer
          (url-retrieve-synchronously
           "https://raw.githubusercontent.com/raxod502/straight.el/develop/install.el"
           'silent 'inhibit-cookies)
        (goto-char (point-max))
        (eval-print-last-sexp)))
    (load bootstrap-file nil 'nomessage))

  ;; Set up use-package for tidier package configuration/installation
  (straight-use-package 'use-package)
  (setq straight-use-package-by-default t)

  ;; Add diminish, which makes it easier to customize lighters (minor mode display)
  (use-package diminish)
I use it since it allows for transparent installations, meaning you can find the straight folder (in my case "~/.config/emacs/straight/repos/") and see git repos for all of your installed packages. From there you can edit them, commit to upstream, pull, all of the usual stuff.

Another main reason to use it is that it allows for repeatable installations, something I had struggled with previously with `package.el`. Run `M-x straight-freeze-versions`, and you have a lock file made with the exact commits of all of the dependencies you're running. That way, you don't need to push your entire emacs config folder up to your dotfiles repo, and can get a new install of emacs set up feature-(and bug)-exact on new machines easily.

One gripe I have about it though is that flycheck no longer recognizes `use-package` syntax in my init file and throws a bunch of warnings as a result. If anyone knows a quick fix, please let me know!

[+] b3n|3 years ago|reply
> If anyone knows a quick fix, please let me know!

I don't use `use-package` (or `flycheck`, what advantage does it have over the built in `flymake`?), but I suspect adding `(require 'use-package)` after `(straight-use-package 'use-package)` would fix it.

[+] motform|3 years ago|reply
I have been using straight for a while now and I think it is great! The ability to lazy load everything by default does a lot to make Emacs snappier (or at the very least, faster to boot). Being able to pull packages directly from git (be it local or a forge) makes package development a lot easier. raxod has a lot of really sleek, modern emacs packages that I would encourage everyone to check out, selectrum[0] and ctrf[1] in particular are really great as well.

[0] https://github.com/radian-software/selectrum

[1] https://github.com/radian-software/ctrlf

[+] ashton314|3 years ago|reply
I moved to straight.el several years ago when I was working on making my Emacs config more repeatable. It’s been simply the best tool for Emacs dependency management. Several packages that I now drive daily I found before they were on MELPA/ELPA; with straight, it was trivial to configure it to clone and install them just with a URL to clone. I’ve also had many bleeding edge updates break stuff for me; I just cd’d into the corresponding elisp directory, git checkout’d the version I wanted, then let straight rebuild the byte compiled files for me automatically on next launch. So. Nice.
[+] b3n|3 years ago|reply
Another approach to the problem would be to install Emacs packages with GNU Guix[1].

[1] https://guix.gnu.org/manual/en/html_node/Application-Setup.h...

[+] civodul|3 years ago|reply
On top of that, one can use Guix from the comfort of Emacs:

  guix install emacs-guix
The Emacs interface includes Magit-style popup menus, lets you install/remove/upgrade/browse packages, roll back, edit package definitions, navigate system services, and more.
[+] agumonkey|3 years ago|reply
Would be worth doing a tutorial for r/emacs or #emacs as I'm not sure a lot of people are aware of this.
[+] pmoriarty|3 years ago|reply
Yet another option is to use a configuration management system like Ansible.
[+] rcthompson|3 years ago|reply
Thanks to straight, setting up emacs on a new machine is as easy as git cloning my config into .emacs.d and launching emacs.
[+] madmax96|3 years ago|reply
what about LSP servers?
[+] onetom|3 years ago|reply
After stumbling upon straight via Doom Emacs, I finally felt confident enough to built my own, from-scratch configuration, without worrying about the kind of constant issues my colleagues were experiencing on their Doom or Spacemacs setups every few months or sometimes every few weeks.

I knew very little about Emacs (27.1) at that time, yet it was an effortless endeavor to grow my own config: https://github.com/onetom/onetomacs

I had literally zero hiccups with packages, though I haven't even froze them, while kept upgrading every few weeks with straight-pull-all.

I think the other big contributor to my pleasant experience was that I've vetted and studied every package, before I've added it to my config and tried to figure out what would it offer compared to built-in functionality.

I'm programming for 40 years by now and primarily in Clojure for the past ~7 years (using IntelliJ/Cursive), so I guess that helped a lot too...

[+] hcarvalhoalves|3 years ago|reply
I wonder what this adds over the default Emacs package manager?

I have this in my init.el:

    (custom-set-variables
    ...
    '(package-selected-packages
       '(package1 package2 ...))
    ...)

    ;;; Bootstrap pkgs
    
    (require 'package)
    (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/") t)
    (add-to-list 'package-archives '("melpa-stable" . "https://stable.melpa.org/packages/") t)
    (package-initialize)
    (unless package-archive-contents
      (package-refresh-contents))
    (package-install-selected-packages)
Then for all mode-specific configuration, I have something like:

    (eval-after-load 'XXX-mode
      '(progn
         (setq XXX 'something)
         (define-key XXX-mode (kbd "C-c .") 'do-something)))
Has been working well enough for me as a config I can share between installations.
[+] eduction|3 years ago|reply
Can someone smarter than me explain what it means to be a “purely functional” package manager?

Because it’s confusing to use the term this way. In programming “purely functional” means no side effects; writing files to disk and mutating the state of the host system is a strong set of side effects.

[+] hypersoar|3 years ago|reply
Think of side-effects on the system user level instead of the hardware level. A functional package manager doesn't rely on, for example, globally installed libraries. It also installs packages in such a way as to not affect the operation of your system. Nix, for example, keeps everything in a private directory. If you have packages A depending on packages X, Y, and B depending on Y, Z, then A, B, X, Y, and Z will all be placed in separate directories in /nix/store. This can all be done without touching any system or user (or emacs) profiles. Hence, "no side-effects".

Of course, you probably want some side-effects, so you'll put symlinks to the stuff you want in your user profile, or into a .envrc file in the root of a project.

[+] zcam|3 years ago|reply
It's a bit like nix but only for emacs. Modes are downloaded/built locally and versions pinned. From there you can put in version control your pin file and update/revert updates safely. It also guarantees you get the exact same setup across machines.

Paired with use-package it makes emacs configs very compact, typically you can have a single conf file + the versions file for everything related to ones setup. That makes it very easy to transport.

Even if you use nix/guix it's more convenient imho to use straight.el for emacs, as it's standalone as long as emacs is available.

[+] esrh|3 years ago|reply
My interpretation is that the same initialization config will lead to the same setup every time, in the sense that each installation is pure in a way. Of course, while it probably just works, it's only actually pure if you pin every package to a version.
[+] tome|3 years ago|reply
This is the only way I have managed to have sane package dependencies in my Emacs configuration.
[+] zelphirkalt|3 years ago|reply
Just from looking at the heading: There is GNU Guix, which also already packages many Emacs packages and many of the contributors / authors of GNU Guix use Emacs to work on it themselves. I have a mostly Guix installed Emacs setup, only including my own init.el and some packages installed through `M-x list-pack RET`, which are not on Guix already. It works quite well and is easy to update.
[+] pasc1878|3 years ago|reply
The problem is that Guix only works on GNU/Linux not even other Unixes as Nix does. Let alone MS Windows.

straight.el works on all of these.

[+] thom|3 years ago|reply
I'm not _aware_ of having any problem that this solves, so I'm probably a horribly inadequate Emacs user. But this repo and some of the author's other work makes it clear he's extremely smart and tasteful so this is probably worth checking out.
[+] AJRF|3 years ago|reply
The reason I use it is because it checks the git repo of the package out so I can jump in and edit it and be inside a git repo if I wanted to open a PR with my change. When you use package.el it will download .tar's and not have git history inside it.

Edit: Also because of above, straight makes it easy to check out specific branches - this isn't easy using package.el - your packages are pinned to a version - whereas this makes it super easy to just checkout a branch someone made without waiting for a new release.

[+] KSPAtlas|3 years ago|reply
I personally use this, I love how it lets you "try out" a package
[+] afroisalreadyin|3 years ago|reply
Looking at the documentation, straight.el took a lot of dedicated work, thanks a lot! Will definitely give it a spin later, which should be rather easy thanks to use-package integration.
[+] mark_l_watson|3 years ago|reply
+1 After reading through the documentation, I wanted to make the same comment.

10 or 20 years ago (I have been using Emacs for about 40 years) I was really happy with my Emacs setup but now I have support for so many languages that my current setup seems like a mess. I will try Straight.el.

[+] yewenjie|3 years ago|reply
I wish there was something like Nix for configuring Emacs.
[+] Kototama|3 years ago|reply
You can manage your Emacs packages with home-manager, it looks like this:

  programs.emacs = {
    enable = true;

    extraPackages = epkgs: with epkgs; [
      ace-jump-mode
      ag
      auto-indent-mode
      browse-kill-ring
    ];
  };
and here a function that builds a package that is missing in MELPA:

  build_movelines = epkgs: epkgs.trivialBuild {
    pname = "move-lines";
    version = "2.0";

    src = pkgs.fetchFromGitHub {
      owner = "targzeta";
      repo = "move-lines";
      rev = "master";
      sha256 = "0pbvn11n9sw3mg3hpcpc8p80zh53sxyjbhqqxdwbwg8dwpc7r5ij";
    };

  };
[+] kdtsh|3 years ago|reply
Guix works as a package manager for Emacs, though you’ll always need to maintain your init.el

straight.el works too of course but ultimately Emacs configuration is not declarative.

[+] reuben364|3 years ago|reply
There is also nix-straight, which is used in nix-doom-emacs, although it is fairly limited and takes ages to build when you make any changes.
[+] widdershins|3 years ago|reply
As I understand it, that's basically what this is.