elixir-boilerplate: Mirego's Phoenix and Absinthe starting point
⚗ The stable base upon which we build our Elixir projects at Mirego.
At a glance
- What is it?
- Mirego publishes the base it builds its own Elixir projects on, and it is an opinionated one: Phoenix, Ecto, a GraphQL API through Absinthe, Gettext, Credo, Sobelow, Sentry, OTP releases and Docker. A setup script renames the project for you, and a table of preferred libraries tells you what the team uses instead of what it shipped.
- Who is it for?
- elixir-boilerplate fits a team starting an Elixir web service that wants the standard Mirego stack, including a GraphQL layer with dataloader and error handling already wired, a linting and security gate in place, and a Docker and OTP release path that works on the first try. It does not fit a team that wants a REST service with no GraphQL, or one whose preferences differ from Mirego's in ways the preferred libraries table makes obvious.
- Can I use it commercially?
- Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 51 days ago.
- What is it written in?
- Mainly Elixir, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A company's own base, offered to the world
The repository describes itself as the stable base upon which Mirego builds its Elixir projects, and says it wants to share it with the world so you can build awesome Elixir applications too. The project is BSD-3-Clause licensed, and the licence notice dates it to 2017 to 2020 with Mirego.
The interesting part of a published house style is that it is opinionated in a way a generic starter kit is not. The README lists the batteries that come included, and the list is long enough to tell you what kind of team this came from.
There is Phoenix as the web framework and Ecto for the database. The GraphQL layer is the most fully specified part: Absinthe, Absinthe.Plug, Dataloader, AbsintheErrorPayload and AbsintheSecurity together, which is a complete stack rather than a single package, and the Dataloader in particular is the piece that stops an N+1 problem in a GraphQL resolver.
Around that there is Gettext for translations with Accent running as a scheduled GitHub Actions workflow, ExUnit with ExMachina factories and ExCoveralls for coverage, Corsica for CORS management, Credo for opinionated linting, MixAudit and Sobelow for security scanning, plug_checkup for a health check, Sentry for error reporting, TelemetryUI for dashboard metrics, and an OTP release with mix release packaged through Docker. The utilities list includes Plug.BasicAuth and PlugCanonicalHost, which tells you the team's idea of a web application's floor.
The documentation is bilingual as well, with a README template in English and in French, so a new project starts with a README that is meant to be filled in rather than deleted.
The table of what they left out tells you as much as the list of what is in
There is a section headed Preferred libraries, and the reasoning given is that some batteries are not included since all projects have their own needs and requirements. The table is the most opinionated part of the README.
For authentication, the choices are ueberauth and pow. For asynchronous job processing, oban. For emails, bamboo and swoosh. For file upload, waffle. For the HTTP client, tesla. For HTML parsing, floki. For pagination, scrivener. For mocks, mox and mimic. For search, elasticsearch.
Read as a list, that is a coherent Elixir stack, and it is worth noticing what is missing. There is no background job library installed, so a project that needs queued work adds oban itself. There is no authentication, so a project that has users adds ueberauth or pow. There is no search, so a project that needs full-text search adds elasticsearch.
That is the right trade for a boilerplate, because those five or six decisions are the ones that differ most between projects, and a template that picked them for you would be making your most consequential architectural choices on your behalf. What the template does supply is the part that is expensive to get right and identical everywhere: the GraphQL stack, the linting rules, the security scanning, the release pipeline.
The repository also ships a .credo.exs and a .sobelow-conf, so the linting and the security scanning are configured rather than merely enabled, and there is a .formatter.exs for the Elixir formatter.
Two ways to start, and a script that renames everything
The usage section has two paths, and both end with the same step.
With the GitHub template, you click the Use this template button to create a new repository, clone your newly created project, run the boilerplate setup script with your project name, and commit the changes with the message Rename elixir-boilerplate parts.
git clone https://github.com/you/repo.git
./boilerplate-setup.sh YourProjectName
git commit -a -m "Rename elixir-boilerplate parts"Without the template, you clone this project, delete the internal Git directory, run the same setup script, create a new Git repository and make the initial commit.
git clone https://github.com/mirego/elixir-boilerplate.git
rm -rf .git
./boilerplate-setup.sh YourProjectName
git init
git commit -a -m "Initial commit"The setup script is the interesting piece of engineering in the template. Renaming a project means the application name in mix.exs, the module namespaces, the Docker image names, the database names, the compose file, the release configuration and the README, and doing that by hand is exactly the kind of chore that people skip. The script at the root of the repository, boilerplate-setup.sh, takes the new project name as its argument, and the fact that the commit message in the official instructions is about renaming tells you what it does.
The Makefile in the repository is built around the same idea, since it derives the application name and the application version by parsing mix.exs and the git revision from Git, and computes the Docker image tag and the local and remote image names from them.
Docker, a pinned toolchain, and a local PostgreSQL
The container build is where you can see exactly which versions the template targets, because the Dockerfile declares them as build arguments.
The arguments are Node.js 22 on bookworm-slim, Elixir 1.18.1, OTP 27.2 and a Debian bookworm 20241223 slim base, and the builder image is assembled from hexpm with that Elixir and Erlang combination. The build runs in stages: a Node stage for the npm dependencies of the asset pipeline, a hex stage that installs hex and rebar, fetches only production dependencies, compiles them, installs esbuild, compiles the assets with mix assets.deploy and compiles the release, and then a runner stage on the plain Debian image.
Two details in there are deliberate. The dependencies are compiled before the application code is copied, so that a change in the application does not force a recompile of every dependency, and the asset install is separate from the hex install so that the npm cache and the hex cache can be reused independently.
For local development there is a docker-compose file with two services. The application service runs an image built from the repository, loads its environment from .env.dev, sets a DATABASE_URL pointing at a postgres user, publishes port 4000, and depends on the database. The database is postgres:14-bookworm with its own volume, published on 5432, with a development password. The .env.dev and .env.test files in the repository are the two environment files the setup expects.
The .tool-versions file pins the local toolchain to match, and the package.json exists mostly for the Accent translation CLI, with Node 18 and npm 9 as the engine constraints.
The quality gates are already wired, which is the real value
A boilerplate's worth is measured in the things you would otherwise have to set up in week two, and this one has a full set of them.
The linter is Credo, described as opinionated, and its configuration is checked in as .credo.exs. The security scanning is MixAudit, which checks your dependency tree for known advisories, and Sobelow, which looks for security issues in the code itself, with a .sobelow-conf file for its settings. Tests are ExUnit, with ExMachina for factories and ExCoveralls for coverage reporting, wired to a coveralls.json. Error reporting is Sentry. Health checks come from plug_checkup, which is the library Phoenix applications use to expose a readiness endpoint for a load balancer or an orchestrator.
The translations are handled with Gettext, and the Accent tool runs as a scheduled GitHub Actions workflow, which is a nice touch: the language review happens on a schedule rather than whenever somebody remembers, and the accent.json configuration in the repository root is what defines the setup.
The documentation mention that a blog post explains why the team created and maintains the boilerplate, and there is a docs/ directory in the repository alongside a CHANGELOG.md, a CONTRIBUTING.md and a CODE_OF_CONDUCT.md, so the project is run with the same care as its output.
Licence details, and what the absence of releases tells you
Two licence details are worth copying into your notes if you use this. The Elixir Boilerplate is copyright 2017 to 2020 Mirego and may be freely distributed under the New BSD licence, which is the permissive three clause variant, so there is no obligation to open source anything you build with it. And the drop logo is based on an icon by Creative Stall from The Noun Project, used under a Creative Commons BY 3.0 licence, which is a separate grant for the artwork.
That second point is the kind of thing that gets missed. A boilerplate that you fork inherits its branding assets, and those assets are licensed separately from the code.
There are no GitHub releases in this repository, so the versioning of the template lives in the CHANGELOG.md and in the mix.exs version, and the last push was on 2026-09-02. That is worth weighing against the dependency versions, because a template that pins Elixir 1.18.1 and OTP 27.2 in its Dockerfile is telling you the age of the stack it was last verified on, and the Elixir and OTP release cycles are the constraint on how long those pins stay current.
The team behind it is Mirego, which describes itself as a team building web and mobile applications and says it loves open source software and tries to give back to the community as much as it can, and its open source site is open.mirego.com.
Editorial conclusion
elixir-boilerplate fits a team starting an Elixir web service that wants the standard Mirego stack, including a GraphQL layer with dataloader and error handling already wired, a linting and security gate in place, and a Docker and OTP release path that works on the first try. It does not fit a team that wants a REST service with no GraphQL, or one whose preferences differ from Mirego's in ways the preferred libraries table makes obvious. Verify three things before you build on it: which Elixir and OTP versions you will run, since the Dockerfile pins Elixir 1.18.1 with OTP 27.2 and the images are built around those, that the GraphQL stack is what you want, since Absinthe with Dataloader, AbsintheErrorPayload and AbsintheSecurity is a large part of what you are adopting, and that the parts left out are the parts you will have to choose, since authentication, background jobs, email, uploads and search are all absent by design.
Frequently asked questions
What does the Mirego elixir-boilerplate include?
Phoenix, Ecto for the database, a GraphQL stack of Absinthe, Absinthe.Plug, Dataloader, AbsintheErrorPayload and AbsintheSecurity, Gettext with Accent for translations, ExUnit with ExMachina factories and ExCoveralls coverage, Corsica, Credo, MixAudit and Sobelow, plug_checkup, Sentry, TelemetryUI, OTP releases with mix release and Docker, and README templates in English and French.
How do I start a new project from the boilerplate?
Either click the Use this template button on GitHub, or clone the repository and delete the .git directory, then in both cases run the setup script with your project name, for example ./boilerplate-setup.sh YourProjectName, and make the initial commit. The script handles renaming the project parts, which the official commit message refers to as Rename elixir-boilerplate parts.
Which libraries are deliberately not included?
The README says some batteries are not included since all projects have their own needs, and lists preferred ones instead: ueberauth and pow for authentication, oban for asynchronous jobs, bamboo and swoosh for email, waffle for file upload, tesla for the HTTP client, floki for HTML parsing, scrivener for pagination, mox and mimic for mocks, and elasticsearch for search.
Which Elixir and OTP versions does the boilerplate build against?
The Dockerfile declares its build arguments as Elixir 1.18.1 with OTP 27.2 on a Debian bookworm 20241223 slim base, and Node.js 22 for the asset pipeline. The .tool-versions file pins the local toolchain to match, and there is a local compose file with postgres:14-bookworm for development.
Can I use the boilerplate commercially?
Yes. The Elixir Boilerplate is copyright 2017 to 2020 Mirego and may be freely distributed under the New BSD licence. One detail to keep separate is the branding: the drop logo comes from an icon by Creative Stall under a Creative Commons BY 3.0 licence, which is a separate grant for the artwork.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/mirego-elixir-boilerplate)Was this useful?