dcominottim

dcominottim

How do Hex and Elixir handle multiple versions of the same dependency?

Coming from a Java and Node.js background, I am really interested in how Hex/Elixir handles multiple versions of the same dependency in comparison to Maven and npm. However, it seems that this is not explained in any docs about Elixir or Hex themselves. Could someone please elaborate on this?

Most Liked

Qqwy

Qqwy

TypeCheck Core Team

For the uninitiated: Semantic Versioning is one of the true pearls of standardization out there.
The idea is extremely simple:

Given a version number MAJOR.MINOR.PATCH, increment the:

  1. MAJOR version when you make incompatible API changes,
  2. MINOR version when you add functionality in a backwards-compatible manner, and
  3. PATCH version when you make backwards-compatible bug fixes.
    Additional labels for pre-release and build metadata are available as extensions to the MAJOR.MINOR.PATCH format.

When you follow these rules, then anyone who depends on your library has a strong guarantee about which version of your library could be used together with their library version.

michalmuskala

michalmuskala

A single module can only exist in one version on the VM. So this gives restrictions on the application structure. This basically means everybody needs to agree on a single version.

To clarify the naming: every mix project is an OTP application and that’s usually what the “application” means in Elixir.

benwilson512

benwilson512

Author of Craft GraphQL APIs in Elixir with Absinthe

Libraries and applications in the erlang world are one and the same. The notion of an application is used because while libraries are often thought of as just bundles of code, libraries in Erlang can also start stateful processes when loaded to manage the state of that library, and are thus better thought of as applications.

A good example would be the package Briefly, which generates temporary file paths. It has code / functions that let you ask for a temporary file path, but it also manages in memory process state to ensure that the paths are deleted when no longer in use.

As noted by @Ankhers, applications define a range of acceptable versions for each dependency ( ie ~> 1.0). When you to a mix deps.get for the first time mix will attempt to find a specific version for each application that falls within all the defined versions. If it cannot, you have the option to override the version to be whatever you want, and see if things work anyway.

Most of the time though it isn’t too hard to get a set of versions acceptable to all relevant libraries.

dcominottim

dcominottim

Does that apply to “libraries” as well? (Sorry if some of the terminology from the Elixir/Erlang ecosystem is not so clear in mind yet, but I believe that you are referring to something else with “application.”) Suppose I want to use library “moment” to handle date/time in Elixir but I also want to use library “anotherlib”, which also uses library “moment”. Is that not possible at all?

dcominottim

dcominottim

Wow, thanks a lot for all the detailed responses, @benwilson512, @Ankhers, and @michalmuskala – the concepts are much clearer to me now.

I suppose that minor versions (1.0, 1.1, etc.) are never expected to introduce breaking changes then. If I intend to publish an application for consumption by 3rd parties, it is good practice to always define its dependencies in the range format instead of targeting a single specific version?

Where Next?

Popular in Questions Top

Brian
What is the proper way to load a module from a file in to IEX? In the python world, doing something like this pretty standard: from ....
New
LegitStack
I’m hoping you guys can give me some general advice and perhaps code examples if you’re feeling up to it. I’m very interested in Elixir,...
New
New
quazar
How to set Jason to encode all fields in ecto schema, I don’t care about security and implementing only is taking long list of attributes...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod -- where is this set? Thanks.
New
makeitrein
Hey all, just started picking up Elixir last week and am writing a scraper as a learning project. Baby step #1 is extracting the number ...
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
alice
Hey, Just curious what are the main benefits of Elixir compared to Clojure? When is Elixir more useful than Clojure and vice versa? Th...
New
beno
I will often find my self writing things similar to: case some_value do nil -> something() "" -> something() _ -> someth...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New

Other popular topics Top

peerreynders
Manning 2016 Halloween weekend sale via Deal of the Day Friday, October 28 - Half off all MEAPs - code WM102816LT Saturday, October 29 ...
326 29600 154
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
sergio
I couldn’t find any guides that worked well with Phoenix 1.6.0 and esbuild. I hope this helps people test the waters and eases you into t...
New
ycv005
I have followed this StackOverflow post to install the specific version of Erlang. And When I am running mix ecto.setup then getting fol...
New
grych
Hi folks, Few months ago I have announced the proof-of-concept of the library to manipulate the browsers DOM objects directly from Elixi...
639 49522 488
New
chrismccord
As promised, the first release candidate of Phoenix 1.3.0 is out! This release focuses on code generators with improved project structure...
New
aadeshere1
I have a another noob question about loop. Since elixir is immutable, while loop is not directly possible. total = 10 while total != 0 ...
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
9mm
I am constructing a JSON object (map) and I need to conditionally set a field. I’m trying to write proper elixir-way code… and I’m at a l...
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New

We're in Beta

About us Mission Statement