- Configure `erlfmt` in `rebar.config` with `{erlfmt, [write]}` — run `rebar3 erlfmt` to format and `rebar3 erlfmt --check` in CI to verify.
- Add `-spec` annotations to all exported functions and run `rebar3 dialyzer` in CI to catch type errors and unreachable clauses.
- Add `{dialyzer, [{warnings, [error_handling, race_conditions, underspecs]}]}` to `rebar.config` to enable additional warning categories.
- Build a Dialyzer PLT (persistent lookup table) in CI and cache it between runs — use `rebar3 dialyzer --update-plt` to update incrementally.
- Use `-type` and `-opaque` attributes to define named types for module boundaries — `opaque` types are not inspected by external modules.
- Enable `{erlfmt, [{print_width, 100}]}` to set the target line width — erlfmt reformats multi-line expressions to fit within the column limit.
- Use `Elvis` (Erlang linter) with `elvis.config` to enforce naming conventions, module structure, and macro usage rules beyond formatting.