Emacs provides a standard way to distribute Emacs Lisp code to users. A package is a collection of one or more files, formatted and bundled in such a way that users can easily download, install, uninstall, and upgrade it.
The following sections describe how to create a package, and how to put it in a package archive for others to download. See Packages in The GNU Emacs Manual, for a description of user-level features of the packaging system.
These sections are mostly directed towards package archive maintainers—much of this information is not relevant for package authors (i.e., people who write code that will be distributed via these archives).
A package is either a simple package or a multi-file package. A simple package is stored in a package archive as a single Emacs Lisp file, while a multi-file package is stored as a tar file (containing multiple Lisp files, and possibly non-Lisp files such as a manual).
In ordinary usage, the difference between simple packages and multi-file packages is relatively unimportant; the Package Menu interface makes no distinction between them. However, the procedure for creating them differs, as explained in the following sections.
Each package (whether simple or multi-file) has certain attributes:
A short word (e.g., ‘auctex’). This is usually also the symbol prefix used in the program (see Emacs Lisp Coding Conventions).
A version number, in a form that the function version-to-list
understands (e.g., ‘11.86’). Each release of a package should be
accompanied by an increase in the version number so that it will be
recognized as an upgrade by users querying the package archive.
This is shown when the package is listed in the Package Menu. It should occupy a single line, ideally in 36 characters or less.
This is shown in the buffer created by C-h P
(describe-package), following the package’s brief description
and installation status. It normally spans multiple lines, and should
fully describe the package’s capabilities and how to begin using it
once it is installed.
A list of other packages (possibly including minimal acceptable version numbers) on which this package depends. The list may be empty, meaning this package has no dependencies. Otherwise, installing this package also automatically installs its dependencies, recursively; if any dependency cannot be found, the package cannot be installed.
Installing a package, either via the command package-install-file,
or via the Package Menu, creates a subdirectory of
package-user-dir named name-version, where
name is the package’s name and version its version
(e.g., ~/.emacs.d/elpa/auctex-11.86/). We call this the
package’s content directory. It is where Emacs puts the
package’s contents (the single Lisp file for a simple package, or the
files extracted from a multi-file package).
Emacs then searches every Lisp file in the content directory for
autoload magic comments (see Autoload). These autoload
definitions are saved to a file named name-autoloads.el
in the content directory. They are typically used to autoload the
principal user commands defined in the package, but they can also
perform other tasks, such as adding an element to
auto-mode-alist (see How Emacs Chooses a Major Mode). Note that a package
typically does not autoload every function and variable defined
within it—only the handful of commands typically called to begin
using the package. Emacs then byte-compiles every Lisp file in the
package.
After installation, the installed package is loaded: Emacs
adds the package’s content directory to load-path, and
evaluates the autoload definitions in name-autoloads.el.
Whenever Emacs starts up, it automatically calls the function
package-activate-all to make installed packages available to the
current session. This is done after loading the early init file, but
before loading the regular init file (see Summary: Sequence of Actions at Startup).
Packages are not automatically made available if the user option
package-enable-at-startup is set to nil in the early
init file.
This function makes the packages available to the current session.
The user option package-load-list specifies which packages to
make available; by default, all installed packages are made available.
See Package Installation in The GNU Emacs Manual.
In most cases, you should not need to call package-activate-all,
as this is done automatically during startup. Simply make sure to put
any code that should run before package-activate-all in the early
init file, and any code that should run after it in the primary init
file (see Init File in The GNU Emacs Manual).
A simple package consists of a single Emacs Lisp source file. The file must conform to the Emacs Lisp library header conventions (see Conventional Headers for Emacs Libraries). The package’s attributes are taken from the various headers, as illustrated by the following example:
;;; superfrobnicator.el --- Frobnicate and bifurcate flanges -*- lexical-binding:t -*- ;; Copyright (C) 2022, 2025--2026 Free Software Foundation, Inc.
;; Author: J. R. Hacker <jrh@example.com> ;; Version: 1.3 ;; Package-Requires: ((flange "1.0")) ;; Keywords: multimedia, hypermedia ;; URL: https://example.com/jrhacker/superfrobnicate ... ;;; Commentary: ;; This package provides a minor mode to frobnicate and/or ;; bifurcate any flanges you desire. To activate it, just type ... ;;;###autoload (define-minor-mode superfrobnicator-mode ...
The name of the package is the same as the base name of the file, as written on the first line. Here, it is ‘superfrobnicator’.
The brief description is also taken from the first line. Here, it is ‘Frobnicate and bifurcate flanges’.
The version number comes from the ‘Package-Version’ header, if it exists, or from the ‘Version’ header otherwise. One or the other must be present. Here, the version number is 1.3.
If the file has a ‘;;; Commentary:’ section, this section is used as the long description. (When displaying the description, Emacs omits the ‘;;; Commentary:’ line, as well as the leading comment characters in the commentary itself.)
If the file has a ‘Package-Requires’ header, that is used as the package dependencies. In the above example, the package depends on the ‘flange’ package, version 1.0 or higher. See Conventional Headers for Emacs Libraries, for a description of the ‘Package-Requires’ header. To depend on a specific version of Emacs, specify ‘emacs’ as the package name. If the header is omitted, the package has no dependencies.
The ‘Keywords’ and ‘URL’ headers are optional, but recommended.
The command describe-package uses these to add links to its
output. The ‘Keywords’ header should contain at least one
standard keyword from the finder-known-keywords list.
The file ought to also contain one or more autoload magic comments,
as explained in Packaging Basics. In the above example, a magic
comment autoloads superfrobnicator-mode.
See Creating and Maintaining Package Archives, for an explanation of how to add a single-file package to a package archive.
A multi-file package is less convenient to create than a single-file package, but it offers more features: it can include multiple Emacs Lisp files, an Info manual, and other file types (such as images).
Prior to installation, a multi-file package is stored in a package archive as a tar file. The tar file must be named name-version.tar, where name is the package name and version is the version number. Its contents, once extracted, must all appear in a directory named name-version, the content directory (see Packaging Basics). Files may also extract into subdirectories of the content directory.
One of the files in the content directory must be named
name-pkg.el. It must contain a single Lisp form,
consisting of a call to the function define-package, described
below. This defines the package’s attributes: version, brief
description, and requirements.
For example, if we distribute version 1.3 of the superfrobnicator as a multi-file package, the tar file would be superfrobnicator-1.3.tar. Its contents would extract into the directory superfrobnicator-1.3, and one of these would be the file superfrobnicator-pkg.el.
This function defines a package. name is the package name, a
string. version is the version, as a string of a form that can
be understood by the function version-to-list. docstring
is the brief description.
requirements is a list of required packages and their versions.
Each element in this list should have the form (dep-name
dep-version), where dep-name is a symbol whose name is the
dependency’s package name, and dep-version is the dependency’s
version (a string). The special value ‘emacs’ means that the
package depends on the given version of Emacs.
If the content directory contains a file named README, this file is used as the long description (overriding any ‘;;; Commentary:’ section).
If the content directory contains a file named dir, this is
assumed to be an Info directory file made with install-info.
See Invoking
install-info in Texinfo. The relevant Info files should also
be present in the content directory. In this case, Emacs will
automatically add the content directory to Info-directory-list
when the package is activated.
Do not include any .elc files in the package. Those are created when the package is installed. Note that there is no way to control the order in which files are byte-compiled.
Do not include any file named name-autoloads.el. This file is reserved for the package’s autoload definitions (see Packaging Basics). It is created automatically when the package is installed, by searching all the Lisp files in the package for autoload magic comments.
If the multi-file package contains auxiliary data files (such as
images), the package’s Lisp code can refer to these files via the
variable load-file-name (see Loading). Here is an example:
(defconst superfrobnicator-base (file-name-directory load-file-name)) (defun superfrobnicator-fetch-image (file) (expand-file-name file superfrobnicator-base))
If your package contains files that you don’t wish to distribute to
users (e.g. regression tests), you can add them to an
.elpaignore file. In this file, each line lists a file or a
wildcard matching files; those files should be ignored when producing
your package’s tarball on ELPA (see Creating and Maintaining Package Archives). (ELPA
will pass this file to the tar command via the -X
command-line option, when it prepares the package for download.)
Via the Package Menu, users may download packages from package
archives. Such archives are specified by the variable
package-archives, whose default value lists the archives
hosted on GNU ELPA and
NonGNU ELPA. This section describes
how to set up and maintain a package archive.
A package archive is simply a directory in which the package files, and associated files, are stored. If you want the archive to be reachable via HTTP, this directory must be accessible to a web server; See Interfacing to an archive web server.
After you create an archive, remember that it is not accessible in the
Package Menu interface unless it is in package-archives.
Maintaining a public package archive entails a degree of responsibility. When Emacs users install packages from your archive, those packages can cause Emacs to run arbitrary code with the permissions of the installing user. (This is true for Emacs code in general, not just for packages.) So you should ensure that your archive is well-maintained and keep the hosting system secure.
One way to increase the security of your packages is to sign them using a cryptographic key. If you have generated a private/public gpg key pair, you can use gpg to sign the package like this:
gpg -ba -o file.sig file
For a single-file package, file is the package Lisp file; for a multi-file package, it is the package tar file. You can also sign the archive’s contents file in the same way. Make the .sig files available in the same location as the packages. You should also make your public key available for people to download; e.g., by uploading it to a key server such as https://pgp.mit.edu/. When people install packages from your archive, they can use your public key to verify the signatures.
A full explanation of these matters is outside the scope of this manual. For more information on cryptographic keys and signing, see GnuPG in The GNU Privacy Guard Manual. Emacs comes with an interface to GNU Privacy Guard, see EasyPG in Emacs EasyPG Assistant Manual.
A web server providing access to a package archive must support the following queries:
Return a lisp form describing the archive contents. The form is a list of ’package-desc’ structures (see package.el), except the first element of the list is the archive version.
Return the long description of the package.
Return the signature for the file.
Return the file. This will be the tarball for a multi-file package, or the single file for a simple package.
Packages that wish to support older releases of Emacs, without giving up on newer functionality from recent Emacs releases, one can make use of the Compat package on GNU ELPA. By depending on the package, Emacs can provide compatibility definitions for missing functionality.
The versioning of Compat follows that of Emacs, so next to the oldest
version that a package relies on (via the emacs-package), one
can also indicate what the newest version of Emacs is, that a package
wishes to use definitions from:
;; Package-Requires: ((emacs "27.2") (compat "29.1"))
Note that Compat provides replacement functions with extended
functionality for functions that are already defined (sort,
assoc, …). These functions may have changed their
calling convention (additional optional arguments) or may have changed
their behavior. These functions must be looked up explicitly with
compat-function or called explicitly with compat-call.
We call them Extended Definitions. In contrast, newly Added
Definitions can be called as usual.
This macro calls the compatibility function fun with args.
Many functions provided by Compat can be called directly without this
macro. However in the case where Compat provides an alternative
version of an existing function, the function call has to go through
compat-call.
This macro returns the compatibility function symbol for fun.
See compat-call for a more convenient macro to directly call
compatibility functions.
For further details on how to make use of the package, see Usage in "Compat" Manual. In case you don’t have the manual installed, you can also read the Online Compat manual.
Emacs ships built-in packages which may also be packaged externally on ELPA. Knowing whether a built-in package has a higher version than on ELPA or other packaging systems may be useful for external packaging tools. Lisp programs which would like to query such information can use the following functions.
This function returns the list of packages that are built into Emacs and have a version. The returned list contains one symbol for each built-in package that has a version, which are likely also packaged externally on ELPA.
This function returns the version of a built-in package.
package should be a symbol. The returned value is a list of
integers representing the version of PACKAGE in the format returned by
the function version-to-list, or nil if package is
built-in but has no version, or is not a built-in package.