Subscribe to access all episodes. View plans →

#162: Publishing a Package to Hex

Published May 1, 2023

Hex.pm publishing a package docs

Follow along with the episode starter on GitHub


Hex - the package manager for the Erlang ecosystem - is an essential piece of tooling whenever you’re building Elixir applications.

In previous episodes, we’ve downloaded packages from Hex, but in this episode let’s see how we can publish one to Hex.

The package we’ll publish is this example Elixir project I’ve created called animal_sounds. It has a single module - AnimalSounds - that has a few different functions we can call to return common animal sounds like a cow, chicken, and pig.

$ iex -S mix
> AnimalSounds.cow()
"Mooo"
> AnimalSounds.chicken()
"Cluck cluck"
> AnimalSounds.pig()
"Oink"

While you can get packages from Hex without an account - we’ll need to create one to publish our package. If you don’t already have a Hex account, pause this video - open hex.pm - and create an account.

Now that we’ve created an account, let’s go to the command line and we can run mix hex to see all the commands that Hex gives us:

$ mix hex
...

Before trying to publish anything to Hex we’ll need to authorize our user with mix hex.user auth, and when prompted we’ll enter our username, and password. Then let’s confirm everything worked by running mix hex.user whoami - and great - that returns our user.

$ mix hex.user auth
Username: elixircastsio
Account password:
...

$ mix hex.user whoami
elixircastsio

Now that we’re authenticated, let’s get our application ready to be published.

We’ll go back to our application and open the Mixfile and we’ll add some additional configuration to the project function here. By default, the name is set to use the same name as the OTP application, written in snake case.

Let’s specify the name of “AnimalSounds” here with no spacing and we’ll also include a short description of our package. Then let’s include the package property - this will contain a few different configuration options, so let’s create another function to keep them organized.

The different options are listed on the Hex docs under their great write-up on publishing a package to Hex. Let’s include a license in our options. I’ll use “MIT” here, but be sure to choose the appropriate license for your use case. Then we can add some useful links for our package. Let’s include links to the “Website” and the “GitHub” repo.

mix.exs

...

def project do
  [
    app: :animal_sounds,
    ...
    name: "AnimalSounds",
    description: "AnimalSounds is a test package for common animal sounds.",
    package: package(),
    ...
]
end

...

def package do
  [
    licenses: ["MIT"],
    links: %{
      "Website" => "https://elixircasts.io/publish-hex-package",
      "GitHub" => "https://github.com/elixircastsio/161-publish-hex-package",
    }
  ]
end

...

Great, with those changes let’s go back to the command line, and we can publish our package our package with the mix hex.publish package command. One note here - running mix hex.publish package will publish a package without documentation.

$ mix hex.publish package
...

And that’s it - our application was published to Hex and here we have a URL of where to find our package. Let’s open it in our browser.

Great! Now users can find our package on hex.pm, add it to their Mixfile, and use it in their projects. But if we look down to the “Links” section of the page. We see the GitHub and Website links, but there’s no link to our package’s documentation on Hexdocs. To fix that we’ll need to go back to our Mixfile and include ex_doc in our list of dependencies. ex_doc includes the mix docs task that’s used to generate documentation.

mix.exs

...

defp deps do
  [
    {:ex_doc, "~> 0.29.4", only: :dev, runtime: false}
  ]
end

...

With that added let’s go to the command line and run mix deps.get.

$ mix deps.get
...
New:
  ex_doc
...

Now to publish our docs let’s run mix hex.publish docs - this will only publish the documentation for our package.

$ mix hex.publish docs
Generating docs...

Now when we go back to view our package in Hex we see the link to view our documentation on HexDocs is now included!

This is great - we can now easily view any documentation for our package. Now let’s make a change to our application. We’ll go back to the animal_sounds.ex module and let’s add another function to return the sound for a duck.

lib/animal_sounds.ex

...

  @doc """

      iex> AnimalSounds.duck()
      "Quack"

  """
  def duck do
    "Quack"
  end

...

Great, now that we have these changes, let’s push up a new version of our package to Hex. We’ll go back to our Mixfile and in our project function we’ll update the version.

mix.exs

...

def project do
  ...
  version: "0.1.1",
  ...
end

...

Then to publish it we’ll go back to the command line and the first time we published just our package with mix hex.publish package, but now that we have our docs set up we can publish both at the same time with mix hex.publish.

$ mix hex.publish
...

Now when we go back to our package in Hex we see the new version of our package is available on Hex!

© 2024 HEXMONSTER LLC