Building Your First Hex Package

As a full-time rubyist, I rely on open-source libraries on a daily basis to do my work. And, like many other ruby programmers lately, I have taken an interest in elixir. So, as I started learning more about the elixir ecosystem I had a question; what is the elixir version of rubygems?

As it turns out, elixir has a very similar analog to gems called “hex”. Just as you would search for ruby gems on rubygems.org, or node packages on npmjs.com, you can find packages for the erlang ecosystem on hex.pm.

As of this writing, there are about 3,600 hex packages available on hex.pm. That might not seem like a lot compared to rubygems (about 8,300 gems) or npm (over 250,000), but interest in erlang and elixir is a much more recent phenomenon. I would expect that number to rise in the coming months and years.


Getting Started

First things first, you need to install hex on your machine. If you have elixir installed, chances are you already have it. (If not, go to http://elixir-lang.org/install.html ) You can check by typing: mix hex -v you should get an output like this:

Hex v0.15.0
Hex is a package manager for the Erlang ecosystem.
...

If you do not have hex installed, type: mix local.hex to install it.


Create an Account

You will need an account on hex.pm before you’ll be able to submit your package. Type: mix hex.user register to begin the registration process. Just enter your email address, select a username, and a password. You will be emailed to confirm your account. Once your account is confirmed, you will be ready to submit packages.


Choose a Name

There are very few rules when selecting a name for your hex package. In fact, the only real rule is:

Avoid using offensive or harassing package names, nicknames, or other identifiers that might detract from a friendly, safe, and welcoming environment for all.

That being said, there are some names that are better than others. For instance, if your package extends the functionality of another library, use that library name as a prefix. (eg. If you are adding xml parsing to the Poison json package, a good name would be “poison_xml”.)

If you are porting a library from another ecosystem, it is common to prepend (or less commonly append) “_ex” to that library’s name. (eg. The aws rubygem is called “ex_aws” in hex. There is a Spotify package named “spotify_ex”.)


Create an Empty Project

Time to start writing code. To start, type: mix new <yourprojectname> . You should see an output like this:

* creating README.md
* creating .gitignore
* creating mix.exs
* creating config
* creating config/config.exs
* creating lib
* creating lib/yourprojectname.ex
* creating test
* creating test/test_helper.exs
* creating test/yourprojectname_test.exs

Adding Metadata to Your Package

Metadata will help define your package dependencies as well as describe it to potential users. Open your mix.exs file and you’ll see a template like this:

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

Hex packages are required to follow semantic versioning.

Dependencies are defined in a private method, deps/0 . This is where you will document any other packages your package requires (if any.) For example, you might want to require ex_doc to generate documentation:

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

After you add dependencies, you need to type: mix deps.get to include them in your project. This is just like adding a gem to your gemfile and typing: bundle install .

To learn more about dependencies, type: mix help deps .

In addition to the attributes predefined for you in your mix file, you will need to include a description and package information.

def project do
[app: :yourprojectname,
version: "0.1.0",
elixir: "~> 1.4",
build_embedded: Mix.env == :prod,
start_permanent: Mix.env == :prod,
description: description(),
package: package(),
deps: deps()]
end
defp description do
"""
Type your multi-line description here. This will be what users
see when they view your package on hex.pm
"""
end
defp package do
[# These are the default files included in the package
name: :yourprojectname,
files: ["lib", "mix.exs", "README*", "LICENSE*"],
maintainers: ["Your name and/or email"],
licenses: ["GPL 3.0"],
links: %{"GitHub" => "https://github.com/user/yourprojectname"}
]
end

Add a License

I have chosen to publish this package under the GPL 3.0 license. As such, I am required to include the text of that license in a file within the project. You can find the descriptions and full text of open source licenses on https://opensource.org/licenses . The full text should be in a file named LICENSE.mdand placed at the root of your project.


Compile Your Project

Assuming you have written your elixir code (in lib/yourprojectname.ex) and tests (in test/yourprojectname_test.exs). You did write tests, didn’t you!? You are ready to compile your package. Type: mix compile . This will compile any .ex files and generate documentation files.


Submit Your Package

You are almost there. Now it’s time to submit your package to hex.pm to be shared with the elixir community. Type: mix hex.publish . You’ll see some output as it reads your package. Review it carefully.

Publishing yourprojectname 0.1.0
Files:
lib/hexdemo.ex
mix.exs
README.md
LICENSE.md
App: yourprojectname
Name: yourprojectname
Description: Type your multi-line description here. This will be
what users see when they view your package on hex.pm
Version: 0.1.0
Build tools: mix
Licenses: GPL 3.0
Maintainers: Your name and/or email
Links:
GitHub: https://github.com/user/yourprojectname
Elixir: ~> 1.4
Before publishing, please read the Code of Conduct: https://hex.pm/policies/codeofconduct
Proceed? [Yn]

Confirm, and your package will be published.


Congratulations! 🎉

You should see your package on https://hex.pm within a few minutes.

Show your support

Clapping shows how much you appreciated Todd Resudek’s story.