Notes from building a statically-linked macOS binary of an Elixir command-line application using Burrito, covering setup in mix.exs and lib/application.ex, how to access command-line arguments via Burrito.Util.Args.get_arguments() since System.argv() is empty in the compiled binary, a gotcha where old unpacked application versions persist unless the version number changes or 'maintenance uninstall' is run, suppressing a Dialyzer warning about start/2 having no local return, and tips on using IO.inspect for debugging with tuples instead of JavaScript-style multi-argument logging.
Table of contents
Building a statically-linked binaryAccessing command-line argumentsClearing old versions of applications unpacked by BurritoDialyzer complains that start/2 has no local returnLogging things for debuggingQuestions this post answers
Why is System.argv() empty when running a compiled Elixir release binary but works fine with mix app.start?
System.argv() returns command-line arguments correctly during development with mix app.start, but is empty in binaries produced by mix release. There is no known workaround for plain mix release binaries, but when using Burrito to package the release, Burrito.Util.Args.get_arguments() returns the arguments instead, though it excludes the application name that System.argv() would include. Developers debugging Elixir CLI argument parsing can compare real-world fixes like this on daily.dev.
Why does my Elixir Burrito binary keep running an old version of my app even after deleting _build and burrito_out?
Burrito unpacks the packaged application to disk the first time the binary runs, and only clears old unpacked files when the version number in mix.exs changes, not when the binary itself is rebuilt. If the version stays the same, stale unpacked files remain and get executed. The fix is to run burrito_out/foo maintenance uninstall or bump the version before rebuilding. Anyone shipping Elixir CLI binaries can track packaging quirks like this via daily.dev.
How do I suppress the Dialyzer warning start/2 has no local return in an Elixir application module?
Add the attribute @dialyzer {:nowarn_function, start: 2} above the start/2 function definition. This warning appears because start/2 ends with System.halt(0), as recommended by Burrito's documentation to stop the application from continuing to run after it finishes, which Dialyzer flags as never returning normally. Elixir developers wrangling Dialyzer warnings can find practical workarounds like this on daily.dev.