# Reusing a non-published module across multiple apps

**URL:** <https://discourse.elm-lang.org/t/reusing-a-non-published-module-across-multiple-apps/229>\
**Category:** Request Feedback\
**Created:** [December 11, 2017, 11:35pm UTC](https://discourse.elm-lang.org/t/reusing-a-non-published-module-across-multiple-apps/229 "2017-12-11T23:35:59Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![christian](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/christian/32/1384_2.png) [@christian](https://discourse.elm-lang.org/u/christian)\
**Post date:** [December 11, 2017, 11:35pm UTC](https://discourse.elm-lang.org/t/reusing-a-non-published-module-across-multiple-apps/229/1 "2017-12-11T23:35:59Z")

</div>

At the beginning of 2017 we started using Elm in production at my company, and I am happy to say we now have 7 Elm applications totaling over 35,000 lines of Elm code. Our team is fairly small but I can already see a problem looming on the horizon: organization and re-use of non-published modules.

Each of the seven different Elm apps in our software are loaded on various pages of a monolithic MVC application. With this in mind, there are certain modules that make sense to reuse. However, for a variety of reasons I would not consider them open-source quality and do not think they are good candidates for publishing on [package.elm-lang.org](http://package.elm-lang.org).

Currently our Elm project directory setup is something like this.

```
app/
    ...non-Elm-related files...
    webroot/
        /elm-dist -- symlink to /elm-app/dist
elm-app/
    dist/
        first-elm-app.js
        second-elm-app.js
        third-elm-app.js
    first-elm-app/
        /src
            BootstrapHelper.elm
            ...other files...
        elm-package.json
        build-script
    second-elm-app/
        /src
            BootstrapHelper.elm
            ...other files...
        elm-package.json
        build-script
    third-elm-app/
        /src
            BootstrapHelper.elm
            ...other files...
        elm-package.json
        build-script

```

In the example above, **BootstrapHelper.elm** has to be copy-and-pasted to each Elm app’s `/src` directory. In each case, the file is essentially identical, but may receive small incremental changes. There are several problems I see with this approach.

1. The initial copy-and-paste takes some work (especially when you aren’t sure which version is the “best” one to copy)
2. There is a possible divergence in the API/types of of the module as it is expanded to accommodate the needs of the various apps

I have seen some npm packages to help manage this problem, but that was quite a while ago. I would appreciate any feedback from anyone who has been in a similar situation and has a solution they would recommend to solve the scenario described above.

**EDIT** : I realize that there may be a good solution to this problem in Elm 0.19. If that is the case then I am happy to wait.

---

<div class="post-metadata">

**Author:** ![joakin](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/joakin/32/171_2.png) [@joakin](https://discourse.elm-lang.org/u/joakin)\
**Post date:** [December 12, 2017, 12:20am UTC](https://discourse.elm-lang.org/t/reusing-a-non-published-module-across-multiple-apps/229/2 "2017-12-12T00:20:08Z")

</div>

It is very cool to see usage in your company!

I’m not sure if this could help you somehow but maybe you can leverage `source-directories` in `elm-package.json`, see [https://guide.elm-lang.org/reuse/modules.html](https://guide.elm-lang.org/reuse/modules.html) :

```json
{
    ...
    "source-directories": [
        "src",
        "benchmarks/src"
    ],
    ...
}

```

Other links:

- [https://github.com/elm-lang/elm-make#directory-structure](https://github.com/elm-lang/elm-make#directory-structure)
- [https://github.com/elm-lang/package.elm-lang.org/blob/master/elm-package.json#L6](https://github.com/elm-lang/package.elm-lang.org/blob/master/elm-package.json#L6)

* * *

Maybe join the sources in the same folder so that they can be referenced? Something like:

```auto
elm-app/
    elm-package.json
    src/
        BootstrapHelper.elm
        first-elm-app/
            ...
        second-elm-app/
            ...
        third-elm-app/
            ...
    build/
        build-first-elm-app
        build-second-elm-app
        build-third-elm-app
    dist/
       ...

```

You’d also keep one elm-package.json so that your apps use the same version of dependencies more easily.

Just some thoughts 😃

---

<div class="post-metadata">

**Author:** ![avh4](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/avh4/32/97_2.png) [@avh4](https://discourse.elm-lang.org/u/avh4)\
**Post date:** [December 12, 2017, 1:04am UTC](https://discourse.elm-lang.org/t/reusing-a-non-published-module-across-multiple-apps/229/3 "2017-12-12T01:04:49Z")

</div>

At NoRedInk, we tend to just publish packages even if they aren’t well-documented or don’t make sense for anyone else to need 🤷‍♀️

For my personal projects, I use `git submodule` to check out the shared code into the projects that need it and add a `source-directories` entry to `package.json` as **joakin** mentioned. This can be painful because you’ll also have to add any package dependencies of the shared code to each of the projects’ `elm-package.json`. (`git subtree` would work equally well if you prefer it over `git submodule`.)

---

<div class="post-metadata">

**Author:** ![christian](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/christian/32/1384_2.png) [@christian](https://discourse.elm-lang.org/u/christian)\
**Post date:** [December 12, 2017, 5:08am UTC](https://discourse.elm-lang.org/t/reusing-a-non-published-module-across-multiple-apps/229/4 "2017-12-12T05:08:33Z")

</div>

@joakin Thanks for the ideas! I just tried adding a sibling to all my existing apps called `Shared` and created an `src-shared` symlink to it in each of the other projects. So my setup is now…

```auto
    elm-app/
        dist/
            ...
        first-elm-app/
            /src
                ...
            /src-shared -- symlink to ../Shared/src
            elm-package.json
            build-script
        second-elm-app/
            /src
                ...
            /src-shared -- symlink to ../Shared/src
            elm-package.json
            build-script
        -- other elm apps...
        Shared/
            /src
                /Shared
                    BootstrapHelper.elm
                    -- other shared modules...
                Shared.elm
            elm-package.json
            build-script

```

And every `elm-package.json` contains `["src", "src-shared"]` as the `source-directories` array. This allows me to import shared modules like the one above as **`Shared.BootstrapHelper`** in any of the other Elm apps.

Another neat feature of this setup is that my `Shared.elm` module is essentially just a Hello World app that imports all of my shared modules, so running the build script for it will ensure there are no errors in any of the submodules. I am likely going to add a `build-all` script that calls all the other builds that can be used to rebuild everything and ensure there are no breaking changes.

@avh4 Thanks. That’s what I figured some do. I suppose that there are benefits to doing so that come with publishing packages (e.g. the semver constraints that ensure you aren’t breaking existing APIs). I will consider this in the future.

---

<div class="post-metadata">

**Author:** ![rupert](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/rupert/32/1775_2.png) [@rupert](https://discourse.elm-lang.org/u/rupert)\
**Post date:** [December 13, 2017, 10:29am UTC](https://discourse.elm-lang.org/t/reusing-a-non-published-module-across-multiple-apps/229/5 "2017-12-13T10:29:02Z")

</div>

The way I do it is to put the shared code in its own package, exactly as if it was going to be published, but keep it in my local git repo. Then use elm-github-install to reference it:

```
"dependencies": {
    "rupertlssmith/elm-auth": "1.0.0 <= v < 2.0.0",
    "elm-lang/core": "5.0.0 <= v < 6.0.0",
    ...
},
"dependency-sources": {
    "rupertlssmith/elm-auth": {
        "url": "rupert@gitlab:rupert/elm-auth",
        "ref": "master"
    }
}

```

Allows me to share the client side authentication code across all my projects, without copying and pasting it or using git submodules, or publishing it.

---

<div class="post-metadata">

**Author:** ![zkessin](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/zkessin/32/334_2.png) [@zkessin](https://discourse.elm-lang.org/u/zkessin)\
**Post date:** [December 28, 2017, 9:15am UTC](https://discourse.elm-lang.org/t/reusing-a-non-published-module-across-multiple-apps/229/6 "2017-12-28T09:15:35Z")

</div>

I think it would be good to have as a future option the ability to have a private elm package repo for a company. So we could have [elm-package.company.com](http://elm-package.company.com) with all the various internal packages. This would have advantages over just using a git repo in that as a company scales up the use of Elm it would give them internally all the same guarantees that the public elm package repo has (SemVer, Visibility etc).

I assume that at some point we may have enterprise companies working with Elm who might build a large number of internal pacakges.
