How suitable is Elixir for a CLI application?

I need to develop a CLI application and I’m wondering how suitable Elixir is for this kind of application. The application must be distributed to clients and it should be as simple as possible to run, ideally a static build with a single binary. I know Elixir has some build systems and I’m wondering if some of these systems can produce a binary, in the end, packing everything inside like the Erlang VM, etc, etc…

Protecting the source code is also desirable.

You should not use elixir for this.

8 Likes

Use Go, Zig, or Rust for that. Elixir is a poor choice there.

4 Likes

maybe I should be more specific about the different points:

ideally a static build with a single binary.

Not generally possible. If you’re okay with a zipped artifact that decompresses into a directory, I would argue that deployment with Elixir as a client application in theory could be easier, than say python, but I have not heard of anyone who has done this.

packing everything inside like the Erlang VM…

Releases (zipped directory) do this. But you must know a considerable amount about your target environment for this to work successfully.

Protecting the source code is also desirable.

This is probably a show-stopper.

Other concerns, if you are expecting a responsive cli app (think like grep) where you might be integrating it as a part of a toolchain that runs very quickly (like generating tab-completion suggestions on a command line), this is not going to be feasible. But if you’re building something where it is going to do something necessarily long-running (like fetching files over the internet) it’s not the worst. I deployed an internal CLI tool once that concurrently-downloaded files from dropbox, S3, box, gcloud… but this was internal and not meant for customer distribution, so realistically it only had to work on one flavor of MacOS, and one flavor of linux.

Also, the erlang vm will default to hogging as many processes as there are CPUs on your system, so you may want to think about that too.

1 Like

You can have a look at Bakeware, which compiles an Elixir, a Scenic or a Phoenix application into single executable binary.

Bakeware still doesn’t main problem with Elixir for CLI tooling - startup time. Most of the CLI tools is one-time quick tools that are launched often and that finish quickly. In such environment Erlang features aren’t that appealing and do not bring much to the table except familiarity.

3 Likes

Any language with a runtime that’s not super light like Go is not going to be good for CLI applications. If you are making a CLI app which is going to run for a bit and won’t need to be called quickly and opened many times or piped into etc, you could get away with it. It depends on the use case but in general Elixir is definitely not good for this use case.

Disagree. Python, Ruby, Perl, etc. are quite good solution for CLI tools. Sometimes even Java is ok solution.

1 Like

I’ve written several CLI apps in elixir for interactive use (i.e. converting data, automating ansible, etc) using escripts. Due to familiarity I write Elixir code much faster than anything else and it works great if you can don’t mind the ~200ms “boot time” (depending on machine of course) to run the CLI app as the whole VM must be brought up even for a quick task.

For me that is a good tradeoff for interactive use as I can control the small internal team’s environment these tools are distributed to and make sure proper Erlang is installed. Your case of “packing … Erlang VM” and “distributed to clients” leads me to suggest what others have already said in Go, Rust, etc which would be much faster to boot and easier to distribute. I haven’t tried Bakeware maybe that solves the distribution problem at least.

1 Like

From a pure runtime startup time perspective:
perl < python2 < python3 < ruby < java < elixir < nodejs
So elixir is not the worst. Hell, many CLI programs are written in nodejs; I cringe every time I run webpack.

I think really the main reasons why I usually wouldn’t go for elixir for a CLI app is that you probably won’t get or need it’s best benefits in a CLI too. Things like reliability and recovery features, distributed computing, maybe concurrency. But you’d still have to deal with a lot of the tradeoffs - lower portability, startup times, etc.

Elixir is designed to do a lot of things really well but it’s hard to beat languages that were designed specifically to be good for CLI tools without trading off the things that make it great for all other stuff.

Then again if your cli tool needs to be able to run a long lived command with a focus on reliability and concurrency, elixir would probably be great.

1 Like

I would say the biggest frustration with elixir scripts is you can’t use libraries in a naked .exs file. I wish there were some middle ground where we don’t have python global package/venv/conda hell, but you could still ship a script pinned to some version of a useful library (like Jason or Toml or Finch/Mojito), and you don’t have to go all the way to setting up a project with an escript

Here is my summary:

  1. Are you making a CLI tool for Elixir developers only? If yes:
    a. Do you want to extend Mix (like mix phx.new)? If so, use mix archive
    b. Otherwise, use mix escript

  2. Otherwise, don’t use Elixir (for all the reasons mentioned above and for the same reasons I wouldn’t use ruby, python, java, etc)

11 Likes

You should take a look at https://github.com/doawoo/teex @ityonemo, it helps with your points.

Does the introduction of Mix.install() in 1.12 change your recommendation?

PS Thank you for creating this awesome language. ; )

I wouldn’t say so. Mix install is great for one-off scripts, notebooks, etc. I wouldn’t build a CLI app with that. :slight_smile:

1 Like