ChaseGilliam

ChaseGilliam

Hello everyone,

I’m finally happy enough with my library Assay to share it here. Assay is an incremental Dialyzer wrapper built for CI and local workflows. It reads your existing Dialyzer settings (with caveats) from mix.exs, runs the incremental engine, filters warnings via dialyzer_ignore.exs, and outputs results in formats suited for humans, CI, editors, and LLM-driven tools.

Why Assay?

Running Dialyzer in Elixir projects has long meant slow full rebuilds, cryptic Erlang-style output, and poor integration with CI and editor tooling. Assay tackles these pain points:

  • Incremental by default — leverages OPT26 Dialyzer’s incremental mode so re-analysis is fast after the initial run
  • Watch mode — mix assay.watch debounces file changes and re-runs analysis automatically, giving you continuous type-checking feedback as you code
  • Multiple output formats — text, github (annotations) lsp, llm, and elixir (pretty-prints Erlang terms as Elixir notation via erlex with some really nicely formatted errors)
  • Igniter-powered installer — mix assay.install auto-detects your project/umbrella apps, configures apps and warning_apps, creates ignore files, and optionally generates CI workflows (GitHub Actions or GitLab CI)
  • Good umbrella app support- Assay was built to run on a large umbrella app
  • It’s fast: We’ve seen a 7m Dialyzer run fall to as little as 9s for small changes.

How does this relate to Elixir’s new type system?

Elixir 1.18+ introduced gradual set-theoretic types in the compiler, with significant inference improvements landing in 1.19 and 1.20. This is exciting work but Dialyzer and the new type system are complementary, not competing. If you like Dialyzer you should like Assay.

Dialyzer, by contrast, performs whole-program analysis across module
boundaries. It catches things the compiler currently cannot:

  • Contract violations between callers and callees across modules
  • Functions that will never return due to type mismatches
  • Unreachable code and impossible pattern matches that span module boundaries
  • Violations of your existing @spec annotations (which the compiler doesn’t check yet)

Even as the compiler’s type system matures, there’s a good chance Dialyzer will continue to catch a different class of bugs. Running increment Dialyzer via Assay is cheap insurance.

Quick Start

Using the Igniter installer (recommended):

mix.exs

  [`
    {:assay, “~> 0.5”, runtime: false, only: [:dev, :test]},
    {:igniter, “~> 0.6”}
  ]
end

then run:

mix assay.install --yes
mix assay

Or configure manually — just add the dep and set your config in mix.exs:

def project do
[
  app: :my_app,
  assay: [
    dialyzer: [
      apps: :project_plus_deps,
      warning_apps: :project]
  ]
]
end

Assay supports symbolic selectors like :project, :project_plus_deps, :current, and :current_plus_deps — particularly handy for umbrella projects.

Output Formats

Run with multiple formatters at once for CI pipelines:

mix assay --format github --format sarif

The github formatter produces rich annotations with formatted bodies instead of raw Dialyzer text. The sarif formatter emits SARIF 2.1.0 JSON for standardized CI tool consumption. The llm format outputs
structured JSON optimized for LLM agents.

Links

https://github.com/Ch4s3/assay

Showing Posts 1 to 2

ChaseGilliam

ChaseGilliam OP

I just released 0.6.1there are various fixes and the following new features:

  • --format markdown output format renders Dialyzer warnings as a Markdown document, suitable for pasting into issues, PRs, or documentation.
  • --format marcli output format renders warnings with rich terminal styling via the optional marcli dependency (add {:marcli, "~> 0.3"} to your project deps to enable).
ChaseGilliam

ChaseGilliam OP

Forgot the hex link last time assay | Hex

— All posts loaded —

Where Next? Top

Trending in Announcing Top

woylie
Flop is an Elixir library that applies filtering, ordering and pagination parameters to your Ecto queries. offset-based pagination with...
New
MRdotB
I needed to reuse React components from my Chrome extension in my Phoenix/LiveView backend. I noticed that for Svelte/Vue, there are live...
New
woylie
I released Doggo, a collection of unstyled Phoenix components. https://github.com/woylie/doggo Features Unstyled Phoenix components....
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
anuaralfetahe
Hello Published a new library - ProcessHub! ProcessHub is a library designed to manage process distribution within the Elixir cluster. ...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New

Other Trending Topics Top

mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
webofbits
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself. My main conc...
#ai
New
sergio
It’s not that it’s vocabulary is too advanced. It’s something worse. I get lost trying to follow even a paragraph written by Claude. It’...
New
AstonJ
This showed up on my feed.. anyone heard of it? Just hype? Ox Alpha is a reasoning model designed for coding, sustained ag...
New
bartblast
Hey folks, I just published a post about Hologram’s funding and where the project goes next - the short version: Curiosum as Main Spons...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews