Publishing a package

Publishing a package to Hex consists of registering a Hex user, adding metadata to the project’s mix.exs file, and finally submitting the package with a mix task.

Registering a Hex user

When registering a user, you will be prompted for a username, your email and a password. The email is used to confirm your identity during signup, as well as to contact you in case there is an issue with one of your packages. The email will never be shared with a third party.

$ mix hex.user register
Username: johndoe
Password (confirm):
Generating API key...
You are required to confirm your email to access your account, a confirmation email has been sent to

Once this step has been completed, check your email inbox for the confirmation email. Once you have followed the enclosed link, your account will be ready to use.

Naming your package

Before publishing, you will have to choose the name of your package. Remember that packages published to Hex are public and can be accessed by anyone in the community. It is also the responsibility of the community to pick and encourage good package names. Here are some tips:

With a name in hand, it is time to add the proper metadata to your mix.exs file.

Adding metadata to mix.exs

The package is configured in the project function in the project’s mix.exs file. See below for an example file.

First, make sure that the :version property is correct. All Hex packages are required to follow semantic versioning.

Fill in the :description property. It should be a sentence, or a few sentences, describing the package.

Under the :package property are some additional configuration options:

The name of the package in case you want to publish the package with a different name than the application name. By default this is set to the same as the name of your OTP application (having the same value as ``), written in snake_case (lowercase with underscores as word separator).
The organization the package belongs to. The package will be published to the organization repository, defaults to the global "hexpm" repository.
A list of licenses the project is licensed under. This attribute is required.
A list of names (and/or emails) of maintainers to the project. Optional but highly recommended.
A map where the key is a link name and the value is the link URL. Optional but highly recommended.
A list of files and directories to include in the package. Defaults to standard project directories, so you usually don't need to set this property.
List of build tools that can build the package. It's very rare that you need to set this, as Hex tries to automatically detect the build tools based on the files in the package. If a rebar or rebar.config file is present Hex will mark it as able to build with rebar. This detection can be overridden by setting this field.

To improve the documentation generated by ExDoc, the following fields can also be supplied as part of the project function:

An URL to the location where your source code is publicly available. This will be used to link directly to the code of the different modules functions from within the documentation.
An URL to the homepage of your application. This will be used to link back to your homepage from within the generated documentation.

Consult the ExDoc documentation for more information on improving the generated documentation.


A dependency defined with no SCM (:git or :path) will be automatically treated as a Hex dependency. See the Usage guide for more details.

Only Hex packages will be included as dependencies of the package, for example Git dependencies will not be included. Additionally, only production dependencies will be included, just like how Mix will only fetch production dependencies when fetching the dependencies of your dependencies. Dependencies will be treated as production dependencies when they are defined with no :only property or with only: :prod.

Example mix.exs file

defmodule Postgrex.MixProject do
  use Mix.Project

  def project() do
      app: :postgrex,
      version: "0.1.0",
      elixir: "~> 1.0",
      build_embedded: Mix.env == :prod,
      start_permanent: Mix.env == :prod,
      description: description(),
      package: package(),
      deps: deps(),
      name: "Postgrex",
      source_url: ""

  def application() do

  defp deps() do
      {:decimal, "~> 1.0"},
      {:ex_doc, "~> 0.14", only: :dev},

  defp description() do
    "A few sentences (a paragraph) describing the project."

  defp package() do
      # This option is only needed when you don't want to use the OTP application name
      name: "postgrex",
      # These are the default files included in the package
      files: ["lib", "priv", "mix.exs", "README*", "readme*", "LICENSE*", "license*"],
      maintainers: ["Eric Meadows-Jönsson", "José Valim"],
      licenses: ["Apache 2.0"],
      links: %{"GitHub" => ""}

Submitting the package

After the package metadata and dependencies have been added to mix.exs, we are ready to publish the package with the mix hex.publish command:

$ mix hex.publish
Publishing postgrex v0.4.0
    decimal ~> 0.1.0
  Excluded dependencies (not part of the Hex package):
  Included files:
Proceed? [Yn] Y
Published postgrex v0.4.0

Congratulations, you’ve published your package! It will appear on the site and will be available to add as a dependency in other Mix projects.

Please test your package after publishing by adding it as dependency to a Mix project and fetching and compiling it. If there are any issues, you can publish the package again for up to one hour after first publication. A publication can also be reverted with mix hex.publish --revert VERSION.

When running the command to publish a package, Hex will create a tar file of all the files and directories listed in the :files property. When the tarball has been pushed to the Hex servers, it will be uploaded to a CDN for fast and reliable access for users. Hex will also recompile the registry file that all clients will update automatically when fetching dependencies.