# Blog: Implementing VDOM in Elm

**URL:** <https://discourse.elm-lang.org/t/blog-implementing-vdom-in-elm/810>\
**Category:** Request Feedback\
**Created:** [March 8, 2018, 2:09pm UTC](https://discourse.elm-lang.org/t/blog-implementing-vdom-in-elm/810 "2018-03-08T14:09:32Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![gampleman](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/gampleman/32/43_2.png) [@gampleman](https://discourse.elm-lang.org/u/gampleman)\
**Post date:** [March 8, 2018, 2:09pm UTC](https://discourse.elm-lang.org/t/blog-implementing-vdom-in-elm/810/1 "2018-03-08T14:09:32Z")

</div>

I just wrote a blog post entitled Implementing VDOM in Elm. It’s meant as an example of some non-trivial Port usage as well as an example of how VDOM actually works without using very much JavaScript.

> **[Implementing VDOM in Elm](https://gampleman.eu/post/171567093310/implementing-vdom-in-elm#_=_)**
>
> What if Elm didn't ship with a VDOM library? No HTML or SVG? You might be tempted that it wouldn't be very useful, but we can implement it ourselves using pure elm and ports. Ports? You heard right,...

I’m interested to hear your comments: both on the actual code as well as on the presentation (which is mostly code with a bit of writing). I’m not sure how clear it is.

---

<div class="post-metadata">

**Author:** ![mfeineis](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/mfeineis/32/104_2.png) [@mfeineis](https://discourse.elm-lang.org/u/mfeineis)\
**Post date:** [March 9, 2018, 7:26am UTC](https://discourse.elm-lang.org/t/blog-implementing-vdom-in-elm/810/2 "2018-03-09T07:26:18Z")

</div>

That’s incredibly neat 🌞 Great work!

---

<div class="post-metadata">

**Author:** ![gampleman](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/gampleman/32/43_2.png) [@gampleman](https://discourse.elm-lang.org/u/gampleman)\
**Post date:** [March 9, 2018, 9:58am UTC](https://discourse.elm-lang.org/t/blog-implementing-vdom-in-elm/810/3 "2018-03-09T09:58:21Z")

</div>

I think I’ve managed to simplify the article considerably by introducing the `SafeHtml` abstraction a section earlier. This allows me to omit a lot more decoders (as they are now trivial) and present `extractListeners` only once. It also makes the virtual section more focused on the diffing.

---

<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:** [March 9, 2018, 10:20am UTC](https://discourse.elm-lang.org/t/blog-implementing-vdom-in-elm/810/4 "2018-03-09T10:20:18Z")

</div>

That is a very nice experiement, well done.

“If you want to build your own rendering engine in Elm, I’ve just shown you how. I hope this can encourage some experimentation with cool techniques. One of the popular ones these days is to not diff against a Virtual DOM, but against the real DOM. You can try that pretty easily.”

I would be tempted to try this out by diffing against a server side rendered DOM in the first instance. However, I think this feature is coming in 0.19 right?

---

<div class="post-metadata">

**Author:** ![mfeineis](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/mfeineis/32/104_2.png) [@mfeineis](https://discourse.elm-lang.org/u/mfeineis)\
**Post date:** [March 9, 2018, 10:29am UTC](https://discourse.elm-lang.org/t/blog-implementing-vdom-in-elm/810/5 "2018-03-09T10:29:54Z")

</div>

I agree, doing rehydration with ports would be interesting, indeed. It would also be interesting to see how an approach like [re:dom](https://github.com/redom/redom) would perform in real world scenarios that uses the real DOM instead of a virtual DOM and can therefore skip the `apply patches to the real DOM` stage of VDOM libraries…

---

<div class="post-metadata">

**Author:** ![gampleman](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/gampleman/32/43_2.png) [@gampleman](https://discourse.elm-lang.org/u/gampleman)\
**Post date:** [March 15, 2018, 9:52am UTC](https://discourse.elm-lang.org/t/blog-implementing-vdom-in-elm/810/6 "2018-03-15T09:52:58Z")

</div>

I wonder how the performance of this approach differs from the real implementation. It will certainly be worse, but by how much?

I’m starting to think this might be a better idea for real systems than I originally thought. Having control over the rendering means one can easily add more constructors to the `Node` type. Need a custom kind of element? Bam! Done. In pure elm with a small bit of ports code.

Seems a lot more flexible than trying to hook into the existing virtual dom or trying to use something like Custom Elements.

---

<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:** [March 15, 2018, 10:28am UTC](https://discourse.elm-lang.org/t/blog-implementing-vdom-in-elm/810/7 "2018-03-15T10:28:01Z")

</div>

I’m having a play with your code because I want to try rehydration.

I think there is a small error in the type signature for `diffChildren`, which should be:

```
diffChildren : Int -> List SafeHtml -> List SafeHtml -> List Change
diffChildren index before after = 
    ...

```

Isn’t the useful thing about custom elements that they are opaque to the Elm VDOM though? So you can embed native DOM manipulating code within an Elm application.

---

<div class="post-metadata">

**Author:** ![gampleman](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.elm-lang.org/gampleman/32/43_2.png) [@gampleman](https://discourse.elm-lang.org/u/gampleman)\
**Post date:** [March 15, 2018, 10:55am UTC](https://discourse.elm-lang.org/t/blog-implementing-vdom-in-elm/810/8 "2018-03-15T10:55:05Z")

</div>

But you can do that with a custom node as well. Then the handling code in you port can do the custom dom manipulation based on instructions it gets from the Elm side.
