When you're new to a programming ecosystem it can be hard to know where to start with libraries that you should be dropping into your project.
While it's important to balance not taking on unnecessary new dependencies that could make things more difficult down the line, you also don't want to reinvent everything yourself.
This is especially true when there are so many great open source options with commercially friendly licenses.
Rather than attempting to organize these by category I'm going to present the 24 libraries alphabetically, so that I can more easily keep track of and update the article as needed. (Last updated 2022/12/1)
The GraphQL library in Elixir. It even has a book. Craft GraphQL APIs in Elixir with Absinthe.
If you're looking to implement GraphQL, as far as I know there aren't any other options that are even worth considering.
Should be paired with
Dataloader in order to avoid as many n+1 pitfalls as possible, and just make things faster/easier/nicer to develop.
A simple, unified authorization (authz) policy library.
While nothing you couldn't roll yourself, utilizing
Bodyguard means that you don't have to roll the code or the docs.
The data processing pipeline tool for Elixir. Allows you to build robust, concurrent, multi-stage data ingestion and data processing pipelines, all from the comfort of the language and ecosystem that you know and love.
mix format, the second most important linter in the ecosystem, and definitely one you should adopt.
It gives you warnings about potential negative behaviors of code, and helps further push your code to look indistinguishable from the code written by other Elixir developers, making onboarding new folks easier.
A collection of mix tasks to make the integration of
Dialyzer (the BEAMs optional discrepancy/type checker) easier.
Non-optional in my experience if you're looking to add type checking to your Elixir experience.
A data mapping and integrated query toolkit. Your "ORM" that isn't an ORM.
Provides mapping between your SQL (mostly SQL) data layer, as well as a thin wrapper around raw SQL queries that makes it harder to do the wrong thing, like accidentally write injectable SQL, and easier to do the right thing, like avoid n+1s through explicit eager loading.
Test data generator for Elixir and
Ecto. Best paired with
Faker, allowing you to generate relevant fake data for your tests in your test suite.
Or in your local environment via seeding.
Either way, in my experience it's preferable to fixtures. Your mileage may vary. If you aren't familiar with the debate between factories and fixtures I'd recommend just giving
ExMachina a try, and seeing what you think.
Essentially a linter for your SQL database migrations. Though this linter uses the AST.
Prevents you from accidentally locking a table and causing production downtime, while not having to keep a bunch of silly rules about how to avoid that in your working memory, freeing that up for the application code you're writing instead.
FunWithFlags in more depth here, but at a high level it is feature flagging functionality baked into the language that you didn't have to write yourself.
Not just boolean on or off for the whole user base either, heavily customizable/granular feature flagging is possible with this library.
The only thing missing with it is instrument-able experiments. But it's a great starting point.
Not technically its own library, as it's part of the standard library.
A module for implementing the server of a generic client-server relationship.
It's worth pointing out for folks that are new to Elixir that
GenServer, and OTP as a whole are worth spending some time on, as they are key runtime elements that allow Elixir to be such a powerful ecosystem.
OTP, of which
GenServer is a part, has books dedicated to the concept, but unfortunately no easy getting started guides outside the official docs, but includes all of the interactions with the actor runtime.
Producer and consumer actors with back-pressure for Elixir.
Unlike GenServer, you may not ever need to reach for GenStage, as you can reach for the higher level abstraction
Broadway, referenced above, and it generally will meet all of your needs better.
That said, this is another interesting library composed of
GenServers and OTP supervision trees in order to achieve back-pressure.
An Elixir rate-limiter with pluggable backends.
An easy way to handle rate limiting for anything, including handling incoming requests to your APIs, making outgoing requests to external APIs, etc.
Automatic cluster formation/healing for Elixir applications.
This makes clustering Elixir applications, for the sharing of state across nodes in the cluster (leveraging things like
Supports a number of clustering strategies, including when the infrastructure is managed through K8s, EC2, Hashicorp's Consul, etc.
I've written a bit about mocking libraries in Elixir, and as far as I'm concerned Mimc is still the king, with Hammox still being the second place.
If you need to mock a function in order to quickly, reliably, and deterministically, Mimic is still the way to go.
A mix task making sure all your code looks as much like everyone else's code as possible.
Run it often, and stop having opinions about the way your code should be formatted. Use its opinions instead.
A file watcher that runs your test suite on relevant changes. A must for TDD or other testing enthusiasts.
Background job processing framework backed by PostgreSQL.
There are a number of other resources that you can reach for with background jobs in Elixir, including
GenStage, etc. But sometimes you need reliability and retry-ability guarantees that those processes can't make out of the box, including persisting across deploys. Oban shines when you need that, as well as a few other guarantees that become much easier when using a SQL persistence layer.
The MVC framework in the Elixir community, and the home of
LiveView enabling us to build highly interactive real-time client experiences using server side rendered HTML.
A cron style job scheduler for Elixir.
While you can often achieve what you need with regard to scheduled jobs simply using
GenServer, occasionally you need them to run at specific times of day, and for that cron syntax, and therefore Quantum, shines.
Sage is a library for running distributed transactions in Elixir.
Ecto.Multi, but for cases when you need to reach outside a single database transaction, and maybe make an API call to an external service, or to ensure state is kept in sync across multiple logically isolated data stores.
A static analysis tool for
Phoenix focused on catching potential security issues.
Paired with the
Finch adapter, the easiest to use, most performant, and most fully featured HTTP request library in the ecosystem.
In either case, make sure you grab the Finch adapter, because it gives you the best performance.
A file upload and attachment library for Elixir that can integrate tightly with
Phoenix, making it dead simple to handle files in your application.
A browser testing tool that integrates deeply with your
Phoenix application, allowing you to test when necessary in a browser, rather than just using rendered HTML.
I've written about it at more length here, and spoken about it at The Big Elixir 2022 in New Orleans.
Now you know about a handful of incredibly useful libraries when getting started with Elixir.
Did I miss anything? If so, let me know. Happy to get emails at email@example.com or via DMs on various social platforms.