Howt to create a CLI with Elixir?

Hello,
I want to create a CLI program in Elixir, but i’m having problems with it. Thinking in distribution of this CLI program, i was seaching the best away to do this, but no success. One possibility was to use mix release, however it not generates a executable that work well with CLI needs. I tried mix escript.build too, but it isn’t being executed on Windows. Any ideias?

1 Like

I think escript is the way to go. For escripts it is important to remember that you need an Erlang installation on the target machine.

Also, under windows, you need to call escript YOUR_PROGRAM_NAME with which you can run your program.

3 Likes

Yes, you can also use bakeware (GitHub - spawnfest/bakeware: Compile Elixir applications into single, easily distributed executable binaries. Spawnfest 2020 project winner) see the code samples (simple_app or simple_script).

3 Likes

Mix releases doesn’t require an Erlang installation in the target, but requires that you build it to the target.

In other words you need to build the release in a machine with the same architecture of the target, and this is usually done with docker.

The tricky bit is that the target needs to have all the static linked dependencies required at runtime, like for example a compatible version of OpenSSL or any other your application may require.

So, building a CLI in Elixir is not hard, the problem is to distribute it, and not even Bakeware solves it as I mentioned here:

I would love to be proven wrong and be told that Bakeware indeed solves the issue like Go and Rust :slight_smile:

2 Likes

Thanks. It was what i’m looking for.

1 Like

While this is true I found it easier (for scripts at least) to simply use escript and make sure erlang is installed on the target machine.

Afaik you’re right. Even though this is off-topic: Bakeware is simply a wrapper that makes the build behave like a binary but has still all the dependencies to libraries on the target machine.

I made some experiments with Flatpak, AppImage and nix-bundle (the latter being the most promising candidate) to bundle everything in one binary. But it is really not worth it most of the time. E. g. it produces long start up times and hard to debug issues that I experimenting with this.

1 Like

I was studying a little more the solution with escript. What’s the difference from take all the source code to the client? I’m thinking to try this solution, It’s like the same that happens in NodeJs, and there’s the advantage of compilation in the architecture of the client. Like NodeJs, the client will need only to install the elixir (?), erlang (?) - i’m new in elixir, trying to understand things - compilers.

For the cli behavior, i’ll only need to setup the corrects paths in OS and create specific scripts files (Bat Files or Bash files etc).

An escript has a function that accepts an arguments vector. This means you can run escript MY_TOOL param1 param2 param3 and all the params get passed into the application.

If you don’t need that and you’re good with sharing the code instead of a “binary”, you can of course simply distribute the code and build and run the tool from your development setup.

It largely depends on what exactly you want to achieve. :grinning_face_with_smiling_eyes:

1 Like

Mix releases don’t require Erlang installed in the target, therefor I don’t see why depending on Erlang in the target is easier :thinking:, but I don’t have enough experience on the matter to say anything more.

Indeed. But you can pass params to application even it’s a script.

Mix releases don’t have a straight forward way to parse the argv in the same way an escript does. Escripts are, essentially, a binary that needs a runtime but otherwise behave like every other “one off” command line tool.

So if you want to release a server, daemon or another long-running-process you would bundle it with mix release and in this case: yes you can bundle the runtime along with the rest of your application.

But the two tools are simply used for different use cases :slight_smile:

1 Like