Elixir Hex Package Tutorial

November 07, 2017

Elixir Hex Package Tutorial

When I first started learning Elixir a few months ago, I had an itch to make my own hex package of some kind. So I started making yt_potion.

Elixir logo from github

Making my own open source library like rsocialize was also a great help to me when I was first learning Ruby on Rails.

Since Elixir was so new, there wasn’t too much in the way of blog posts to help you get started. Thus, I decided to document what I did for future reference and to help others.

Preliminary Steps

If you’re coming from Ruby (or some other language) where you’re used to having an environment manager to manage different versions of Ruby and its associated libraries, check out my post Setting Up Elixir Like a Rubyist.

This will help you install Elixir if you haven’t done so yet. Mix is the build tool that ships with Elixir that has automated tasks for managing dependencies and other useful tricks when working with your Elixir application.

Step 1 – Initialize Your Package With Mix

First, you will use mix to initialize your new package. I’ll be walking you through what I did with yt_potion.

Initialize your package with the following command:

mix new yt_potion

You should see output similar to the following:

$ mix new yt_potion
* creating README.md
* creating .gitignore
* creating mix.exs
* creating config
* creating config/config.exs
* creating lib
* creating lib/yt_potion.ex
* creating test
* creating test/test_helper.exs
* creating test/yt_potion_test.exs

Your Mix project was created successfully.
You can use "mix" to compile it, test it, and more:

    cd yt_potion
    mix test

Run "mix help" for more commands.

Step 2 – Git init

Next, you’ll want to version control your work with Git.

git init yt_potion

Step 3 – Pick a license

GitHub has a nice way to help you choose a software license. I personally chose the MIT license as that gives permission to people to “do whatever they want” with the software and is easy to understand. You can read more about the license tool here on GitHub’s blog and if you’re ready to choose a license, you can use the tool here.

Step 4 – Register at hex.pm

Before you can start publishing your hex package, you should go over to hex.pm and register an account.

You’ll need the password you create during the registration process later to publish your package.

You’ll get a profile that looks something like the following:

A screenshot of my hex package profile

Step 5 – Add meta information to your mix.exs file

If you try to issue a mix hex.build command without properly configuring mix.exs first, you’ll end up seeing something like the below:

Building nested_filter 0.1.0
  Files:
    lib/nested_filter.ex
    mix.exs
    README.md
    LICENSE
    CHANGELOG.md
  App: nested_filter
  Name: nested_filter
  Version: 0.1.0
  Build tools: mix
  Elixir: ~> 1.4
** (Mix) Stopping package build due to errors.
Missing metadata fields: description, licenses, maintainers, links

You’ll want to configure description, package, and dependency (or deps) information in your project function in the mix.exs file. Here’s an example mix.exs file from a hex package I published called nested_filter

You’ll notice I have package, description, and deps information setup via private functions that are passed as values to the keys in the array in the project function.

defmodule NestedFilter.Mixfile do
  use Mix.Project

  def project do
    [app: :nested_filter,
     version: "0.1.3",
     elixir: "~> 1.4",
     build_embedded: Mix.env == :prod,
     start_permanent: Mix.env == :prod,
     description: description(),
     package: package(),
     deps: deps()]
  end

  defp package do
    [
      files: ["lib", "mix.exs", "README*", "LICENSE*"],
      maintainers: ["Bruce Park"],
      licenses: ["MIT"],
      links: %{"GitHub" => "https://github.com/treble37/nested_filter"}
    ]
  end

  defp description do
    """
    Drill down into a nested map and filter out keys according to user
    specified values
    """
  end

  # Configuration for the OTP application
  #
  # Type "mix help compile.app" for more information
  def application do
    # Specify extra applications you'll use from Erlang/Elixir
    [extra_applications: [:logger]]
  end

  # Dependencies can be Hex packages:
  #
  #   {:my_dep, "~> 0.3.0"}
  #
  # Or git/path repositories:
  #
  #   {:my_dep, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
  #
  # Type "mix help deps" for more examples and options
  defp deps do
    [{:ex_doc, ">= 0.0.0", only: :dev}]
  end
end

Step 6 – Build your package (and include a README)

To build your package, issue mix hex.build at the command prompt. You’ll see something like the below.

Again, don’t forget to include a README file otherwise you may get a complaint like the below when you build.

Building yt_potion 0.1.0
  Dependencies:
    httpoison ~> 0.10.0
    json ~> 1.0
  Files:
    lib/yt_potion.ex
    lib/yt_potion_channel.ex
    lib/yt_potion_parser.ex
    lib/yt_potion_video.ex
    mix.exs
    LICENSE
  App: yt_potion
  Name: yt_potion
  Description: YouTube v3 Data API Wrapper
  Version: 0.1.0
  Build tools: mix
  Licenses: MIT
  Maintainers: Bruce Park
  Links:
    GitHub: https://github.com/treble37/yt_potion
  Elixir: ~> 1.3
** (Mix) Stopping package build due to errors.
Missing files: README

Here is what a successful build might look like:

Building nested_filter 0.1.0
  Files:
    lib/nested_filter.ex
    mix.exs
    README.md
    LICENSE
  App: nested_filter
  Name: nested_filter
  Description: Drill down into a nested map and filter out keys according to user
specified values
  Version: 0.1.0
  Build tools: mix
  Licenses: MIT
  Maintainers: Bruce Park
  Links:
    GitHub: https://github.com/treble37/nested_filter
  Elixir: ~> 1.4
Package checksum:  XXX12345

Don’t forget to add ex-doc

If you see a message like the below, you’ll need to add :ex_doc in the deps function.

The "docs" task is unavailable. Please add {:ex_doc, ">= 0.0.0", only: :dev} to your dependencies in your mix.exs. If ex_doc was already added, make sure you run the task in the same environment it is configured to
** (Mix) The task "docs" could not be found. Did you mean "do"?


  defp deps do
    [{:ex_doc, ">= 0.0.0", only: :dev}]
  end

Step 7 Publish on hex.pm

Finally, you’re ready to publish.

Type mix hex.publish at the command prompt.

You should see something like the following:

$ mix hex.user auth
Username: treble37
Password:
Generating API key...
Encrypting API key with user password...

If need to enter a passphrase, use the password you used when you registered with hex.pm

Summary

Publishing a hex package is relatively painless. Just follow the above 7 steps and you’ll be on your way.


Profile picture

Written by Bruce Park who lives and works in the USA building useful things. He is sometimes around on Twitter.