# Newbie: using React components in Elm

**URL:** <https://discourse.elm-lang.org/t/newbie-using-react-components-in-elm/1229>\
**Category:** Learn\
**Created:** [May 6, 2018, 10:38am UTC](https://discourse.elm-lang.org/t/newbie-using-react-components-in-elm/1229 "2018-05-06T10:38:28Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![akavel](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/akavel/32/943_2.png) [@akavel](https://discourse.elm-lang.org/u/akavel)\
**Post date:** [May 6, 2018, 10:38am UTC](https://discourse.elm-lang.org/t/newbie-using-react-components-in-elm/1229/1 "2018-05-06T10:38:28Z")

</div>

I want to write an app in Elm (specifically, a Progressive Web App). I want to be able to quickly prototype a UI using premade components from the Wide Web, maybe from npm ecosystem, maybe from React ecosystem. Actually, I’m not sure which, because I’m a JS noob (and I desperately want to stay one). The goal is to _ **reuse** _, i.e. I don’t want to have to build my own html+css as much as possible. I’ve seen some React xml-like layouts and components and they seem perfect.

How can I do this in Elm? It can be non-idiomatic, I just want to do it as easily as possible to focus on the actual app, not some low level yak shaving.

I’ve seen [a similar question on stackoverflow](https://stackoverflow.com/questions/41367354/is-there-a-way-to-use-react-components-within-elm); but as an Elm and JS noob I don’t get much of it. I mostly see it as a few 2016 answers of “boooo, you shouldn’t, it’s not idiomatic!”, but some guy there also tried to hack something in 2017 and it seems to work for him? I’m interested in this constructive even if hacky and ugly attitude. Is this still the state of art as of 2018? Can somebody please help me and expand on this in an ELI5 way, that I could ideally repeat for any third party React component? I’d be super grateful!!!

---

<div class="post-metadata">

**Author:** ![lydell](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/lydell/32/178_2.png) [@lydell](https://discourse.elm-lang.org/u/lydell)\
**Post date:** [May 6, 2018, 4:20pm UTC](https://discourse.elm-lang.org/t/newbie-using-react-components-in-elm/1229/2 "2018-05-06T16:20:58Z")

</div>

You might be looking for [http://package.elm-lang.org/packages/rundis/elm-bootstrap/latest](http://package.elm-lang.org/packages/rundis/elm-bootstrap/latest) or [http://package.elm-lang.org/packages/debois/elm-mdl/latest](http://package.elm-lang.org/packages/debois/elm-mdl/latest).

---

<div class="post-metadata">

**Author:** ![akavel](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/akavel/32/943_2.png) [@akavel](https://discourse.elm-lang.org/u/akavel)\
**Post date:** [May 6, 2018, 8:20pm UTC](https://discourse.elm-lang.org/t/newbie-using-react-components-in-elm/1229/3 "2018-05-06T20:20:38Z")

</div>

Woohoo, that looks cool, thanks! Will certainly try them; should be enough to build some reasonable first prototype on top of them (esp. MDL, given I want to build a phone app).

The MDL package seems to have stalled; do you know if any of the numerous forks has picked the ball, by chance? For example, the dialog feature seems incomplete, while the bootstrap package seems to have a similar one in better shape. Or I don’t see support for a “drawer” widget, which would also be interesting to me.

Also, are there some more alternatives apart from your 2 suggestions, or is it all there is as of now?

And still somewhat interested in the original question, regardless!

---

<div class="post-metadata">

**Author:** ![edkv](https://avatars.discourse-cdn.com/v4/letter/e/439d5e/32.png) [@edkv](https://discourse.elm-lang.org/u/edkv)\
**Post date:** [May 7, 2018, 10:31am UTC](https://discourse.elm-lang.org/t/newbie-using-react-components-in-elm/1229/5 "2018-05-07T10:31:30Z")

</div>

It’s surely possible to use JS components in your Elm app and there is nothing wrong with it, but you should do this rather in exceptional cases when reimplementing such components in Elm is impossible or very hard in practice. The most common examples are Google Maps and rich text editor.

You have two options: [ports](https://guide.elm-lang.org/interop/javascript.html) or [web components](https://developer.mozilla.org/en-US/docs/Web/Web_Components).

With ports the sequence of actions is the following:

1. When the component is initialized on the Elm side, make a port call to JS giving it id of your component’s root element.
2. On the JS side create the component and insert it into the DOM under your root element.
3. Use [Html.Keyed](http://package.elm-lang.org/packages/elm-lang/html/2.0.0/Html-Keyed) around your root element to prevent the virtual DOM algorithm from messing up its children (which it is not aware of).
4. Communicate with the JS component via ports.

The biggest downsides of this approach is that you don’t have a declarative interface to your component on the Elm side and you can’t implement your component as a pure function since it requires sending `Cmd`s to use ports.

I recommend to use web components instead. Web components API consists of four parts: custom elements, shadow DOM, HTML imports and HTML templates. You only need custom elements. Basically this allows you to define custom HTML tags like `<my-component>` and perform some actions whenever they are inserted or removed from the DOM.

To get started see [this talk](https://www.youtube.com/watch?v=ar3TakwE8o0) and [this article](https://developers.google.com/web/fundamentals/web-components/customelements). The plan is the following:

1. Define a custom element like it is described in the article.
2. Define a `connectedCallback` method inside of which initialize your component and add it to the DOM using for example `document.createElement` and then `this.appendChild`.
3. Use a `disconnectedCallback` if you need to do some cleanup when the component is removed from the DOM.
4. In your Elm app use `Html.node "my-component" [] []` to render your component. Use `Html.Attributes.attribute` and `Html.Attributes.property` to pass data to it. Use `attribute` for simple things like strings and `property` for passing JSON. Then on the JS side use `this.getAttribute`, `attributeChangedCallback` and property setters to listen for changes in attributes/properties and react accordingly (see the article, it has some examples).
5. Use `this.dispatchEvent(new CustomEvent("my-event", { detail: { some: data }})` to send events to Elm and `Html.Events.on` to listen for them. Read more about `CustomEvent` [here](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent).
6. Keep as much state of your component as you can in your Elm app and pass it down to JS (make your Elm app the source of truth). You may still want to use `Html.Keyed` if some critical state is kept in JS.

Web components don’t have perfect [browser support](https://caniuse.com/#feat=custom-elementsv1) so you’ll need a [polyfill](https://github.com/webcomponents/custom-elements). You’ll also need a polyfill for `CustomEvent` for IE. You can use [this package](https://github.com/jsPolyfill/CustomEvent) or just copy it directly from [here](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill).

PS: I don’t have much experience using web components myself so if somebody thinks that I said something wrong please correct me.

---

<div class="post-metadata">

**Author:** ![lydell](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/lydell/32/178_2.png) [@lydell](https://discourse.elm-lang.org/u/lydell)\
**Post date:** [May 7, 2018, 8:30pm UTC](https://discourse.elm-lang.org/t/newbie-using-react-components-in-elm/1229/6 "2018-05-07T20:30:35Z")

</div>

I have never used any of the packages, just seen them mentioned in news feeds. So unfortunately I don’t know the state of the forks. I don’t know of similiar packages either.

---

<div class="post-metadata">

**Author:** ![joefiorini](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/joefiorini/32/665_2.png) [@joefiorini](https://discourse.elm-lang.org/u/joefiorini)\
**Post date:** [May 9, 2018, 4:07pm UTC](https://discourse.elm-lang.org/t/newbie-using-react-components-in-elm/1229/7 "2018-05-09T16:07:02Z")

</div>

> [@akavel](#):
>
> The MDL package seems to have stalled; do you know if any of the numerous forks has picked the ball, by chance?

I’m using MDL on a prototype project and it’s working well. You are right, from what I heard in the elm-mdl channel it’s stalled and there is a replacement, but don’t remember the name off the top of my head (on my phone atm, will look soon). If this is a prototype I’d say use it; it’s pretty complete and works well. If this will be maintained long-term, then I’d find a more maintained solution.

---

<div class="post-metadata">

**Author:** ![Sidney](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/sidney/32/3290_2.png) [@Sidney](https://discourse.elm-lang.org/u/Sidney)\
**Post date:** [May 9, 2018, 4:16pm UTC](https://discourse.elm-lang.org/t/newbie-using-react-components-in-elm/1229/8 "2018-05-09T16:16:43Z")

</div>

> [@joefiorini](#):
>
> > [@akavel](#):
> >
> > The MDL package seems to have stalled; do you know if any of the numerous forks has picked the ball, by chance?
> 
> I’m using MDL on a prototype project and it’s working well. You are right, from what I heard in the elm-mdl channel it’s stalled and there is a replacement, but don’t remember the name off the top of my head (on my phone atm, will look soon). If this is a prototype I’d say use it; it’s pretty complete and works well. If this will be maintained long-term, then I’d find a more maintained solution.

Actually, MDL (the library created by Google) has also been replaced. I believe this is partially why development has stalled for elm-mdl.

Google’s replacement is called [material-components-web](https://github.com/material-components/material-components-web) (MCW?) and the new Elm package is called [elm-mdc](https://github.com/aforemny/elm-mdc)

---

<div class="post-metadata">

**Author:** ![akavel](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/akavel/32/943_2.png) [@akavel](https://discourse.elm-lang.org/u/akavel)\
**Post date:** [May 11, 2018, 1:37pm UTC](https://discourse.elm-lang.org/t/newbie-using-react-components-in-elm/1229/9 "2018-05-11T13:37:53Z")

</div>

Thank you all very much for your help! I’m going with elm-mdl for now, plus some custom CSS hacking, trying to force it to my will on a case by case basis. I’m scared that CSS will punish me at some point, but for now I’m very satisfied. And I must say I’m genuinely astonished how much easier it is to build the UIs that way than in native Android Java. I feel like it should be opposite, but it’s not. Thank you all again for helping me and showing the way!

I’m also very interested in the Web Components approach; I feel I will hit a wall at some point with pure elm-mdl plus my amateur CSS, and WC sound like interesting shrink-wrapped composable & well isolated utilities. But I don’t know yet how to meld them into the awesome create-elm-app infrastructure. Which, by the way, works so flawlessly, quickly and fluently for me, that I feel really privileged and amazed, and grateful to the author (Eduard Kyvenko a.k.a. _halfzebra_) and all contributors that they built it, shared it and continued to improve it. I may be repeating but - thanks, you’re awesome!!!

---

<div class="post-metadata">

**Author:** ![kraklin](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/kraklin/32/385_2.png) [@kraklin](https://discourse.elm-lang.org/u/kraklin)\
**Post date:** [May 15, 2018, 8:27am UTC](https://discourse.elm-lang.org/t/newbie-using-react-components-in-elm/1229/10 "2018-05-15T08:27:43Z")

</div>

To use web components in Elm you may find some hints in this thread: [Ways of embedding other libs or frameworks into Elm app?](https://discourse.elm-lang.org/t/ways-of-embedding-other-libs-or-frameworks-into-elm-app/1029)

---

<div class="post-metadata">

**Author:** ![akavel](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/akavel/32/943_2.png) [@akavel](https://discourse.elm-lang.org/u/akavel)\
**Post date:** [May 15, 2018, 8:55am UTC](https://discourse.elm-lang.org/t/newbie-using-react-components-in-elm/1229/11 "2018-05-15T08:55:46Z")

</div>

Yes, thanks! Actually I’ve already stumbled upon this thread a day or two ago. As of now, I believe I more or less understand how communication with Web Components can be done on Elm side (I think the [article on elmprogramming.com](http://elmprogramming.com/interacting-with-web-components.html) is a nice summary; though it doesn’t mention the “Html.keyed” thing, which I still don’t grasp, but see mentioned quite often).

One thing I’m still unsure about, is how to properly integrate/“import” a Web Component into a project based on the awesome [_create-elm-app_](https://github.com/halfzebra/create-elm-app) template. But I haven’t really tried yet; I’m still managing with some _ad hoc_ HTML + CSS, though I feel like fighting with it at times.

---

<div class="post-metadata">

**Author:** ![edkv](https://avatars.discourse-cdn.com/v4/letter/e/439d5e/32.png) [@edkv](https://discourse.elm-lang.org/u/edkv)\
**Post date:** [May 15, 2018, 2:04pm UTC](https://discourse.elm-lang.org/t/newbie-using-react-components-in-elm/1229/12 "2018-05-15T14:04:15Z")

</div>

@akavel If a Web Component you wish to use is available on npm: [https://github.com/halfzebra/create-elm-app/blob/master/template/README.md#installing-javascript-packages](https://github.com/halfzebra/create-elm-app/blob/master/template/README.md#installing-javascript-packages)

---

<div class="post-metadata">

**Author:** ![berend](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/berend/32/2250_2.png) [@berend](https://discourse.elm-lang.org/u/berend)\
**Post date:** [May 15, 2018, 9:11pm UTC](https://discourse.elm-lang.org/t/newbie-using-react-components-in-elm/1229/13 "2018-05-15T21:11:48Z")

</div>

@akavel, do not use elm-mdl. The Material Design Light framework itself [has been obsoleted](https://material-ui-next.com/getting-started/comparison/). Use [elm-mdc](https://github.com/aforemny/elm-mdc) instead, which uses the Google supported version Material Design Web Components.

---

<div class="post-metadata">

**Author:** ![akavel](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/akavel/32/943_2.png) [@akavel](https://discourse.elm-lang.org/u/akavel)\
**Post date:** [May 19, 2018, 12:51am UTC](https://discourse.elm-lang.org/t/newbie-using-react-components-in-elm/1229/14 "2018-05-19T00:51:00Z")

</div>

Why change if MDL works for me? What important advantages over it does MDC have? I don’t understand the linked article with the “comparison”.

---

<div class="post-metadata">

**Author:** ![system](https://canada1.discourse-cdn.com/flex035/uploads/elm_lang/original/1X/50a05e53677a2c3b47776d7abd0f113eb50193a1.png) [@system](https://discourse.elm-lang.org/u/system)\
**Post date:** [May 29, 2018, 1:03am UTC](https://discourse.elm-lang.org/t/newbie-using-react-components-in-elm/1229/15 "2018-05-29T01:03:52Z")

</div>

Closed on May 29, 2018, 1:03am UTC

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.
