erli18n

July 3, 2026 · View on GitHub

Hex.pm HexDocs CI License: Apache 2.0 OTP 27+

Modern, GNU gettext–compatible internationalization (i18n) for Erlang/OTP — in pure Erlang.

This repository is a rebar3 umbrella that ships two separately-published Hex packages:

PackagePathWhat it is
erli18napps/erli18n/The runtime i18n library — .po/.pot loading, CLDR pluralization, copy-free persistent_term lookups, and the full GNU gettext facade family (gettext, ngettext, pgettext, npgettext, plus interpolating f-suffix siblings), optional per-request localization middleware for Cowboy & Elli, and an optional erlydtl template bridge.
rebar3_erli18napps/rebar3_erli18n/The companion rebar3 plugin — an Erlang-native string extractor that walks your source's abstract forms and produces .pot templates, giving you rebar3 erli18n {extract,merge,check,report,compile}. It is a separate Hex package that depends on erli18n.

The two packages have independent versions, coupled only by the plugin's ~> dependency constraint on the library (the plugin reuses erli18n's public PO read/serialize API across the package boundary). The umbrella co-locates them for atomic cross-package changes and shared tooling; each is published to Hex on its own.

Getting started

To consume both packages from a downstream project, add the runtime library as a dependency and the extractor as a plugin in your rebar.config:

%% rebar.config of a downstream consumer
{deps, [{erli18n, "~> 0.7"}]}.
{plugins, [rebar3_erli18n]}.

For the runtime library — installation, the full facade API, locale negotiation, interpolation, and worked examples — see the package README:

➡️ apps/erli18n/README.md

For the string-extraction plugin — installation as a {plugins, [...]} entry and the extract/merge/check/report/compile commands — see the plugin README:

➡️ apps/rebar3_erli18n/README.md

A runnable downstream consumer that wires up both — real gettext call sites and committed catalogs — lives under examples/erli18n_demo/. Two runnable middleware examples show per-request locale negotiation in a web server: examples/erli18n_cowboy_demo/ (Cowboy) and examples/erli18n_elli_demo/ (Elli). A third example, examples/erli18n_erlydtl_demo/, renders erlydtl templates whose {% trans %} / {% blocktrans %} tags translate through the erli18n_erlydtl bridge.

Repository layout

.
├── apps/
│   ├── erli18n/          # the erli18n runtime library (Hex package)
│   │   ├── README.md     #   package-facing README (install + full API)
│   │   ├── CHANGELOG.md  #   the erli18n package changelog
│   │   ├── LICENSE       #   Apache-2.0
│   │   ├── rebar.config  #   runtime deps + this package's doc/hex config
│   │   └── include/ src/ test/
│   │                     #   (doc/ is generated ex_doc output → HexDocs,
│   │                     #    gitignored; not part of the source tree)
│   └── rebar3_erli18n/   # the rebar3 plugin (Hex package)
│       ├── README.md  CHANGELOG.md  LICENSE  rebar.config
│       └── src/ test/
├── examples/                 # runnable standalone example apps:
│   ├── erli18n_demo/         #   downstream consumer of both packages
│   ├── erli18n_cowboy_demo/  #   per-request localization middleware (Cowboy)
│   ├── erli18n_elli_demo/    #   per-request localization middleware (Elli)
│   └── erli18n_erlydtl_demo/ #   erlydtl template tags via the bridge
├── scripts/                # gen_docs.sh + ex_doc_config.escript (doc helpers)
├── rebar.config            # umbrella-wide settings only (plugins, profiles,
│                           #   dialyzer/xref/hank/erlfmt policy) — no
│                           #   package-specific doc/hex config lives here
├── LICENSE                 # umbrella license (Apache-2.0)
├── CHANGELOG.md            # umbrella-level history → links to per-app changelogs
├── CONTRIBUTING.md  CODE_OF_CONDUCT.md  SECURITY.md

Per published-app convention (each Hex package ships its own LICENSE, README.md, and CHANGELOG.md physically inside the app directory), the package-facing docs for each app live under apps/<app>/. The repo-root README.md (this file), CHANGELOG.md, CONTRIBUTING.md, CODE_OF_CONDUCT.md, and SECURITY.md are umbrella-level dev/community docs and are not shipped inside either package tarball.

Development

git clone git@github.com:eagle-head/erli18n.git
cd erli18n
rebar3 compile
bin/quality-gate.sh --fast    # ~30s:  compile + xref + erlfmt + elvis + hank + elp lint
bin/quality-gate.sh --full    # ~5min: + dialyzer + eqwalize-all + Common Test (+ coverage)

See CONTRIBUTING.md for the full setup: toolchain pinning with mise, git hooks, local CI emulation with act, and the contribution workflow.

Documentation

Security

To report a vulnerability, see SECURITY.md — please do not open a public GitHub issue for security reports.

License

Apache License 2.0 (SPDX: Apache-2.0). Each package ships its own copy of the license under apps/<app>/LICENSE.

References