# Write CLI scripts in Elm (IO Monad)

**URL:** <https://discourse.elm-lang.org/t/write-cli-scripts-in-elm-io-monad/7543>\
**Category:** Request Feedback\
**Created:** [July 13, 2021, 2:45pm UTC](https://discourse.elm-lang.org/t/write-cli-scripts-in-elm-io-monad/7543 "2021-07-13T14:45:28Z")\
**Posts on this page:** 1\
**Showing post:** 30

<div class="post-metadata">

**Author:** ![albertdahlin](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/albertdahlin/32/868_2.png) [@albertdahlin](https://discourse.elm-lang.org/u/albertdahlin)\
**Post date:** [July 20, 2021, 2:31pm UTC](https://discourse.elm-lang.org/t/write-cli-scripts-in-elm-io-monad/7543/30 "2021-07-20T14:31:48Z")

</div>

> [@miniBill](#):
>
> Does `callJs` allow for (almost) arbitrary code execution?
> 
> Do you have any plans for file I/O or http servers?

My idea for this package is to make it more ergonomic to write simple CLI scripts, for example dev tools and build pipelines. I also want to make it as open as possible to allow others to implement their own I/O in nodejs. Supporting HTTP-servers is however out of scope for now.

I’m currently working on specifying the API for the following I/O modules:

- Read / write files.
- File system, (move, copy, delete, list etc).
- Http client, make http requests.
- Spawn sub processes and run shell commands.

My plan for [callJs](https://elm-doc-preview.netlify.app/Posix.IO?repo=albertdahlin%2Felm-posix&version=new-api#callJs) is to simplify user specific I/O implementations and allow people to experiment.

## CallJs Example

CallJs is just a wrapper for communicating with the “outside” using two ports.  
To create your own project specific I/O implementation my current thinking goes along these lines:

### Javascript

Create a standard nodejs module that exports an Object with all your I/O functions, e.g

`js/my-functions.js`

```javascript
module.exports = {
    addOne: function(num) {
        this.send(num + 1); // this.send is a normal Elm port
    },
}

```

### Elm

Then create an Elm module where you supply the Encoder / Decoder for communicating with Javascript, e.g `src/MyModule.elm`

```elm
addOne : Int -> IO x Int
addOne n =
    IO.callJs
        "addOne"
        [ Encode.int n
        ]
        Decode.int

program : IO.Process -> IO String ()
program _ =
    ...

```

### Put it together

When you run or compile you can add arguments to supply your I/O implementation, something like this:

```auto
elm.cli run --extend-io js/my-functions.js src/MyModule.elm

```

---

_[View the full topic](https://discourse.elm-lang.org/t/write-cli-scripts-in-elm-io-monad/7543)._
