Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
A tiny library to facilitate record upgrades in Elixir
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.


ExRecord is a simple convention and a library to facilitate easier Elixir record upgrades (normally during code change / release upgrades).


In order to benefit from ExRecord, define your records this way:

defrecord MyRecord, __version__: 1, field: nil do
  use ExRecord

You can also rename __version__ to any other name:

use ExRecord, version: :__version_field__


In order to upgrade (or downgrade) your record, call MyRecord.__convert__(record_to_be_converted) and you'll get a converted up-to-date record.

By default, the algorithm for conversion is very simple: it takes the original (to be converted record), extracts all fields values and creates a new record with these fields. It will silently ignore fields that no longer exist in the actual record.

You can also override a convertion procedure for any version by overriding __convert__(version, record) function:

defrecord TestCustomChangeRecord, __version__: 2, a: 1 do
  use ExRecord

  def __convert__(1, src) do
    super(version, src).a(2)

You can also rename the __convert__ function:

use ExRecord, convert: :__my_convert__


iex(1)> defrecord Foo, __version__: 1, bar: nil do
...(1)>   use ExRecord
...(1)> end
iex(2)> 1)
Foo[__version__: {1,[:__version__,:bar]}, bar: 1]
iex(3)> inspect v(-1), raw: true

Now, let's copy the raw record representation and reuse it in a new IEx session:

iex(1)> defrecord Foo, __version__: 2, bar: nil, foo: nil do
...(1)>   use ExRecord
...(1)> end
iex(2)> record = {Foo,{1,[:__version__,:bar]},1}
iex(3)> Foo.__convert__(record)
Foo[__version__: {2,[:__version__,:bar,:foo]}, bar: 1, foo: nil]

As you can see, the old record got automatically converted to a new record that contains more fields.


It is important to understand that each ExRecordified record will carry its version & field information in the very first field:

iex(1)> defrecord Foo, __version__: 1, bar: 2 do
...(1)>   use ExRecord
...(1)> end
Foo[__version__: {1,[:__version__,:bar]}, bar: 2]

Also, you don't need to have a runtime dependency on the exrecord application as all work is done during compile time. All of the conversion code gets compiled into your record modules.

Something went wrong with that request. Please try again.