Publishing your Elixir package

There’s a couple of ways to share your code as packages. The first is by simply creating a GitHub repository and putting your code there, the second is to add the package to the hex.pm packages website. To be honest we’re most likely going to create a GibHub repos, so we’ll end up doing both…

Github packages

I’ve implemented a new library by creating it via mix new ex_unit_conversions (naming is always a problem, do also check hex.pm to ensure your name is not duplicated). Then I’ve added the code to the lib folder and tests to the test folder, see ex_unit_conversions.

We can create a dependency on this package without a version, but for this one I create a release named v0.1.0, so now I need to update the deps of any application/code that is going to download and use this package, i.e. in mix.exs I have this

defp deps do
  [
    {:ex_unit_conversions, git: "https://github.com/putridparrot/ex_unit_conversions.git", tag: "v0.1.0"}
  ]
end

As you can see the tag needs to be the same as the tag name. So in my case I put the v prefixing (for the later version of package I named the release in GitHub without the preceding v, i.e. 0.1.1).

Now when you run mix deps.get you’ll see a new deps folder created with the code from your repo downloaded to it.

Pretty simple. Now let’s look at making things work in hex.pm.

Updating mix.exs

Before releasing your package to hex.pm you may wish to update the mix.exs project section to ensure your app name is correct, update a version add source_url, home page etc. For example (I missed these for the GitHub only release but added for release to hex.pm). If you miss anything you will be prompted for it to be added before you can publish to hex.pm.

def project do
    [
      app: :ex_unit_conversions,
      version: "0.1.1",
      elixir: "~> 1.17",
      source_url: "https://github.com/putridparrot/ex_unit_conversions",
      homepage_url: "https://github.com/putridparrot/ex_unit_conversions",
      start_permanent: Mix.env() == :prod,
      deps: deps(),
      package: [
        links: %{"GitHub" => "https://github.com/putridparrot/ex_unit_conversions"},
        licenses: ["MIT"],
      ],
      description: "Unit conversion functions"
    ]
  end

You may wish to also create a dependency in your package to include ex_doc, i.e.

def deps do
  [
    # Other dependencies
    {:ex_doc, "~> 0.34.2", only: :dev, runtime: false},
  ]
end

Install your dependencies using mix deps.get and then you can generate your docs using mix docs but this will also allow hex.pm to generate docs for your package.

hex.pm

To create a package on hex.pm, first we need to create an account. See Publishing your package for the official guidance on this process, but I’ll recreate some of those steps here

  • If you’ve not already done so, create a user account via hex.pm OR using mix, we can register a user using
    mix hex.user register
    
  • Once you have your mix.exs upto date (and hex.pm may prompt your for missing information during this next step), you can try to publish your package using the following via the your shell/terminal from your package folder (as created using mix new).
    mix hex.publish
    

    You will be prompted for your username, password and are required to have a local password (this will be setup during this process).

If you want to check the latest publish options etc. run mix help hex.publish.

That’s all there is to it.

References

Package configuration options
Publishing a package