Hello!
I’m super excited to announce elm-codegen
, an Elm package and CLI tool for generating Elm code!
- Here is the package on NPM
- And the code docs on the Elm package website
My goal is to make it easy to write maintainable code generation for Elm.
Basically I wanted something that was easier to write than that string template you have lying around. And more maintainable than juggling a raw AST.
Here’s a simple example!
This code
Elm.declaration "anExample"
(Elm.record
[ ("name", Elm.string "a fancy string!")
, ("fancy", Elm.bool True)
, ("theTime", Gen.Time.millisToPosix 0)
]
)
will generate the following:
import Time
anExample : { name : String, fancy : Bool, theTime : Time.Posix }
anExample =
{ name = "a fancy string!"
, fancy = True
, theTime = Time.millisToPosix 0
}
Let’s break down what this tool does for you in order to make generating code simpler.
- Automatic imports — Import declarations are calculated. If you use a value from another module, it will know and write your import declarations accordingly.
- Built in type inference — The types for your generated code are inferred. This means generated things can figure out their own type signatures!
-
Use existing packages easily — For generating code that uses a specific library such as elm-ui, the
elm-codegen
CLI can create some Elm code to help you out. In the above example, we’re using generated bindings to theelm/time
package.
Using Existing Packages
Let me elaborate on the 3rd point for a moment because this turned out to be one of the most interesting aspects for me.
Using the elm-codegen
CLI, you can install bindings to any package from the Elm universe.
For example — running elm-codegen install elm/html
will create the following files —
Gen/Html.elm
Gen/Html/Attributes.elm
These will help us generate calls to Html
. What does that look like? Well, we can now write something like this:
import Gen.Html
import Gen.Attributes
div : Elm.Expression
div =
Gen.Html.div
[ Gen.Html.Attributes.class
"hello"
]
[ Gen.Html.text
"Hello world!"
]
Which will generate
Html.div
[ Html.Attributes.class "hello" ]
[ Html.text "Hello world!" ]
And would automatically include imports for import Html
and import Html.Attributes
Crazy, right?
The generated helpers also include a number of other ways it can assist you, but for me, this basic mirroring of how you would interact with a library normally makes things very intuitive in a lot of cases.
The Guides
There is a very succinct guide to get people started:
Also, major thanks to Leonardo Taglialegne aka @miniBill
, you’ve been a massive help in developing this tool from the very beginning, I’m incredibly grateful
Live, at Strange Loop!
I’m going to be giving a talk on this library at Strange Loop on this and a bunch of related work that is built on top of it (that will hopefully be ready for release soon!)
We use this at Vendr.com
We have roughly 300k lines of Elm code at Vendr.com, a wonderful, talented Elm team, and use Elm CodeGen to power our new GraphQL library (which I will be posting about very soon.)
I also have some fun stuff in the works with regards to this and elm-ui
!
Happy to answer any questions. Lots more to come!