A buddy and I are wanting to start writing emacs packages specific for use in our company. (Trust me, nothing we write will be of much interest to anyone outside -- it's integration with internal tools.)

We'd like to make package installation and maintenance as easy as possible and we think this means integration with package.el. What do we need to do to set up a repository for such use?

  • I'd fork MELPA and write recipes for your packages! Alternatively, provide just the recipes and point your coworkers to QUELPA.
    – user227
    Commented Oct 17, 2015 at 14:46

2 Answers 2


I set up a local package archive (Emacs 24.5) using package.el by first creating two directories, pkgs and local. (The names don't matter.) The files comprising your packages go in pkgs, and local will end up holding your archive. If you want to make an archive available to others, you can expose local using a web server, but the process is the same as building a local archive.

I put the following in my init.el file:

(require 'package)
(setq package-enable-at-startup nil)

(require 'package-x)
(defvar local-archive
  (expand-file-name "local/" user-emacs-directory)
  "Location of the package archive.")
(setq package-archive-upload-base local-archive)
(add-to-list 'package-archives `("local" . ,local-archive) t)


I put my archive in my .emacs.d directory (hence the user-emacs-directory in the expand-file-name form) but you can put it anywhere you like.

Once this is evaluated, execute M-x package-upload-file and enter the file name of your package to be installed. This will generate a new package in local. You will see three new files in there, archive-contents, yourpackagename-version.el, and yourpackagename-readme.txt. Now you should be able to do M-x package-list-packages and see your package listed. With luck, they'll be at the top marked "new". You can install the package as usual, and you will see it show up in your .emacs.d/elpa directory just like any other package.

This should work out of the box for Emacs 24. I'm not sure about earlier versions. Your users can access your package in the usual way by including

(require 'package)
(setq package-enable-at-startup nil)
(add-to-list 'package-archives 
  '("archive" . "http://yourdomain.com/path-to-local-dir/"))

in their init.el file.

For information on how to write a package, see Preparing Lisp code for distribution in the GNU Emacs Lisp manual.

  • Thanks! This is a very well-written answer and it worked well for me. I have just one question.. when I do M-x package-update-file, it puts the .el file directly under local/ dir. Is there a way to create a subdirectory for each package so that we end up with local/pkg1/pkg1.el, local/pkg2/pkg2.el, ... ? Commented Oct 15, 2015 at 19:34
  • Not to my knowledge. The elpa directory is set up the way you describe. I really don't know why local is not. Bear in mind that these files are generated automatically, so no one ever really has to look at them. I keep my files under version control with git, and put my local directory into .gitignore for that reason. I keep my pkgs directory nicely organized, and under version control, but local is what it is. Commented Oct 15, 2015 at 22:51
  • Thanks. So to confirm, all files gets dumped in a flat hierarchy in your local/ too? I wanted the hierarchical arrangement so that I can specify the package's URL meta data as ;; URL: http://yourdomain.com/path-to-local-dir/pkg1, and so on for different packages. But it's not a big deal. I am more thrilled to publish my packages in a local elpa. :) Commented Oct 15, 2015 at 23:02
  • 1
    Mine is flat, too. I wouldn't point your users to that local directory anyway. Point them to the original source instead. Commented Oct 16, 2015 at 21:55
  • This is great! But when I use it with tar files on windows, a broken tar is uploaded and I have to manually copy over it again. Bug in Emacs? 24.5
    – fommil
    Commented Dec 22, 2015 at 18:45

If you'd like to host something like MELPA, you can find instructions on MELPA's wiki on how to host your own MELPA instance:


Essentially, it boils down to:

  1. Fork/clone the MELPA GitHub repository
  2. Delete all existing recipes from the recipes/ directory
  3. Add your own recipes
  4. Run make.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.