User friendly CLI apps for Elixir
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.
lib Change default command syntax May 14, 2018
sample Change default command syntax May 14, 2018
test Added default command support May 8, 2018
.formatter.exs Add a .formatter.exs to export the DSL Oct 7, 2018
.gitignore Add documentation and type specs. May 5, 2016
.travis.yml Update Travis build Feb 3, 2018
LICENSE Add documentation and type specs. May 5, 2016 Update Nov 16, 2018
mix.exs Bump version Oct 12, 2018
mix.lock Bump version Oct 8, 2018


Build Status Coverage Status

User friendly CLI apps for Elixir.


Here is a small screencast of what a generated CLI app looks like.



Add ex_cli to your list of dependencies in mix.exs:

def deps do
  [{:ex_cli, "~> 0.1.0"}]


The basic usage is to use ExCLI.DSL to define your CLI, and to run it. Here is a sample application:

defmodule MyApp.SampleCLI do
  use ExCLI.DSL

  name "mycli"
  description "My CLI"
  long_description ~s"""
  This is my long description

  option :verbose, count: true, aliases: [:v]

  command :hello do
    aliases [:hi]
    description "Greets the user"
    long_description """
    Gives a nice a warm greeting to whoever would listen

    argument :name
    option :from, help: "the sender of hello"

    run context do
      if context.verbose > 0 do
        IO.puts("Running hello command")
      if from = context[:from] do
        IO.write("#{from} says: ")
      IO.puts("Hello #{}!")

Which can be used in the following way.

sample_cli hello -vv world --from me

or using the command's alias:

sample_cli hi -vv world --from me

The application usage will be shown if the parsing fails. The above example would show:

usage: mycli [--verbose] <command> [<args>]

   hello   Greets the user

escript and mix integration

You can very easily generate a mix task or an escript using ExCLI


Pass escript: true to the use ExCLI.DSL and set the module as escript :main_module:

# lib/my_escript_cli.ex
defmodule MyEscriptCLI do
  use ExCLI, escript: true

# mix.exs
defmodule MyApp.Mixfile do
  def project do
    [app: :my_app,
     escript: [main_module: MyEscriptCLI]]

mix integration

Pass mix_task: TASK_NAME to the use ExCLI.DSL.

# lib/my_cli_task.ex
defmodule MyCLITask do
  use ExCLI, mix_task: :great_task

You can then run

mix great_task

and get nicely formatted help with

mix help great_task


Check out the documentation for more information.


  • Command parser

    The command parser is now working and should be enough for a good number of tasks.

  • Integration with escript and mix

    ExCLI.DSL can generate a module compatible with as well as a mix task.

  • Usage generation

    A nicely formatted usage is generated from the DSL.

  • Help command

    Then the goal will be to add a help command which can be used as app help command to show help about command.

  • Command parser improvements

    When the usage and help parts are done, there are a few improvements that will be nice to have in the command parser:

    • the ability to set a default command
    • the ability to easily delegate a command to another module
    • command aliases
  • Man page generation

    When all this is done, the last part will to generate documentation in man page and markdown formats, which will probably be done as a mix task.


Contributions are very welcome, feel free to open an issue or a PR.

I am also looking for a better name, ideas are welcome!