Libraries are an important part of the Elixir programming language ecosystem. In this article, I will present the most important ones with their use cases and rules of applying them to your projects.
What are libraries in Elixir?
In software development, we take a lot of things for granted. As developers, we have access to many SaaSes, tools, utilities, which do most of the work for us.
We are used to building software from blocks, where frameworks can be treated as large and solid foundations for our platforms, while libraries are small pieces of puzzle, which we connect together by our own, custom code.
This approach has one big advantage: we can deliver quickly and efficiently.
But every solution comes with drawbacks. I believe that many bad decisions in functional programming can be avoided.
That is why I want to go through common mistakes Elixir developers can git commit while building software. I will also mention some common rules and patterns to lower the technical debt in your Elixir project.
Start an Elixir project with a solid foundation
The framework choice for Elixir web applications is simple.
You have two options:
- use mix to bootstrap a pure Elixir project and add necessary utilities yourself: you can use Plug, Cowboy and rest of the libraries you need,
- bootstrap project with Phoenix framework.
Phoenix is usually the way to go, unless you are building a small microservice, which will be programmed and tested once, and not changed later in its lifetime (but we all know this is quite rare in software development).
I highly recommend bootstrapping your project as an Umbrella app.
Umbrella apps support Domain-Driven Design and make it easier to separate responsibilities of your modules.
Elixir libraries you will usually need
In most cases, you will want to have Postgrex as your database driver, and Ecto as your query language. This approach is a robust standard in the Phoenix community. Postgres is a high-efficiency open source database, and Ecto is a powerful query language which helps you write complicated queries in a simple way.
Jason - JSON encoder/decoder:
Jason is your go-to choice for your JSON encoder/decoder. Written by Michał Muskała, Jason has proven to be a fast and reliable JSON utility. Jason is now the default JSON encoder for Ecto, Postgrex and Phoenix.
Tesla - HTTP client:
Tesla is a brilliant HTTP client for Elixir. It has a plenty of configuration options, as well as possibilities to use in two different ways: as middleware or directly. HTTPoison can be a solid pick for HTTP client as well.
Bamboo - mailing:
Bamboo is the only library you need for handling emails. It is purely functional and provides adapters for over 10 different mailing services.
ExAws - Amazon services:
ExAws is a decent solution to connect with Amazon Web Services. This is a flexible and easy-to-use set of AWS APIs. Every API is separated in different dependency, which makes it lightweight and intuitive.
Bcrypt - password encryption:
Bcrypt is an Elixir wrapper for the Bcrypt password hashing function. It provides convenience functions which make working with passwords simpler and safer.
All of the above packages are well-tested and are in production versions.
...and then things start to break
Eventually, you will encounter a problem that is not so trivial to solve in Elixir.
Let’s say image parsing. There are three main ways to approach this problem.
1. Use a library in the 0.y.z version
This is a highly discouraged one, since the library may have a plenty of bugs and issues, and in most cases won’t reach the 1.0.0 version. In case you use such a library, do not use it as a core part of you application. Make sure to bootstrap it around a custom module:
defmodule Images.Utilities do def cut(file, x, y) do png_file = # some file magic # some more hacks ExternalImageLibrary.cut(png_file, x, y) end end
instead of using them directly in the domain code.
This approach will allow you to easily change a library, and to do some nasty code hacks needed to get the library working without staining your domain code.
2. Use a UNIX utility
When there were not so many libraries in Elixir, a common way to solve a problem was to run a unix executable program via
System.cmd. This approach is a great way to solve a problem if you keep the code around clean, by extracting the logic to a module or a private function.
3. Use a microservice or an online API
This is the easiest approach. If you can afford it, and can get a dedicated, robust solution, e.g. Amazon Lambda, use it. You will keep your code clean and decoupled, and it can end up cheaper than building it on your platform (if you need to do processing only once in a while).
When to use Elixir libraries...
Libraries are great for features which would take a long time without them or require a lot of testing. Things like, but not limited to, encryption, image processing, integrations with external services, data manipulation, rendering templates, parsing complicated data formats can be coded faster using libraries.
...And when not to use
For simple tasks like exporting .csv files, generating random strings, slugging which are straightforward in Elixir, not using library will be a better call.
Elixir libraries: Wrapping up
Using libraries in Elixir is a great way to shorten delivery time as well as to simplify the code. However, as any tool in programming, use them when you actually need them. Adding too many dependencies to project can deepen its technical debt and make things unnecessarily complicated.
Have an interesting experience using Elixir libraries Share it in the comments section!
Meanwhile, take our Free Elixir Course if you want some hands-on experience in programming.
Looking for a trusted Elixir development team? Drop us a line.