I was gearing up to publish my first package, and was a bit surprised that I was unable to find an explanation of the basic steps involved. There are a couple of posts for Elm 0.18 but they are out of date now, so I decided to write down all the things I had to do as I went. Granted, the steps are quite straightforward, as you will see, but it's still a bit of a barrier when they aren't spelled out (or at least a great excuse to procrastinate for me)!
You can get started the same way as you would with an application: by running
elm init. This will create an application
elm.json file, which you'll need to update later.
Local development and testing
You can compile your package by running
elm make in its directory.
You can add tests to your package, but you might also want to try using it from an application. How do you do it before the package is published? Obviously you can't add it to your application
elm.json before it's published!
Instead, you can add the source of the package to your application directly, by adding the relative path to the package source to "source-directories" in the application's
elm.json, something like:
Note that you will need to add all the dependencies of the package to your application
elm.json manually to make things compile.
Requirements for publishing
When you are ready to publish, you can update
elm.json in your package directory with
"type": "package" and all the other required package fields.
The rest of the fields for a package are as follows:
name: Name of the package's GitHub repo, eg
alexkorban/my-package (note that packages must be published via GitHub)
summary: Summary for package.elm-lang.org, max 80 characters
license: License identifer from the OSI approved licence list
version: Package version - see details below
exposed-modules: Array of exposed module names
elm-version: Range of compatible compiler versions
dependencies: A list of dependencies (with version ranges rather than specific versions)
test-dependencies: A list of dependencies that are only used in the
tests/ directory by
Here is a sample
elm.json to put these into context:
"summary": "A pack of monoids in the category of endofunctors",
"elm-version": "0.19.0 <= v < 0.20.0",
"elm/browser": "1.0.0 <= v < 2.0.0",
"elm/core": "1.0.0 <= v < 2.0.0",
"elm/html": "1.0.0 <= v < 2.0.0",
"elm/json": "1.0.0 <= v < 2.0.0",
"elm/time": "1.0.0 <= v < 2.0.0",
"elm/url": "1.0.0 <= v < 2.0.0",
"elm/virtual-dom": "1.0.2 <= v < 2.0.0"
With regards to versioning, let me quote the rules spelled out by the
elm publish command:
- Versions all have exactly three parts: MAJOR.MINOR.PATCH
- All packages start with initial version 1.0.0
- Versions are incremented based on how the API changes:
PATCH = the API is the same, no risk of breaking code
MINOR = values have been added, existing values are unchanged
MAJOR = existing values have been changed or removed
The incrementing of the version is done by running
elm bump before
elm bump changes the version of the package according to the rules above based on the changes it finds in the package code.
Documentation is required for packages. You will need to provide a
README.md in the root of your project, as well as inline documentation in the code which has to be in a specific format.
You can preview the documentation using an online previewer. To preview the inline documentation, you need to collate it into a JSON file, which can be done by running
elm make --docs=docs.json.
A license is also required. In addition to specifying a license identifier from the OSI approved licence list in the
"license" field of
elm.json, you need to include the text of the licence in a file called
LICENSE in the root of your project.
Publishing the package to the package index is done via GitHub (it's the only option available).
$ git init
$ git add elm.json src/
$ git commit -m "Initial commit"
$ git tag 1.0.0
$ git push --tags origin master
$ elm publish
After you've made changes to the code, you can run
elm diff to find out whether the changes result in a patch, minor or major version change. The output will detail the API changes.
Then you will need to run
elm bump to update the package version in
The last steps are the same as for the initial release: tag the commit, push to GitHub, and run
elm publish to publish the new version of your package.
And that's it! Now you know how to publish a package and how to update it later.
(Thanks to Ian Mackenzie for pointing out a couple of things I missed.)
elm.json format details
Higher-level design considerations for packages