elm-book with Georges Boris

Georges Boris joins us to discuss elm-book and how it helps iterate on a design language of Elm widgets.
May 9, 2022


Hello, Jeroen.
Hello, Dillon.
And today we've got a guest joining us, Georges Borie.
Thank you so much for joining us, Georges.
Thank you.
I'm really, really glad to be here.
Yeah, we're very glad to have you.
And today we're going to be talking with Georges about Elmbook.
So before we dive in, Georges, do you want to just give a quick intro to what Elmbook
Elmbook is an application as library.
So it's a library that kind of like wraps your visual components.
And you can use it to build rich documentation and also to build like a storybook like applications
for your UI stuff, basically.
What is a storybook like application in your mind?
This is kind of like interesting.
I started using this thing called storybook, which is completely ubiquitous.
Can you define what storybook is?
Because maybe not everyone knows.
Yeah, definitely.
So storybook is this library that automatically generates an application that you can inspect
a lot of your UI components.
You can see them in different states.
You can like use that for developing components in isolation and just do a lot of testing
instead of like actually going down your application and clicking everywhere until you find your
component and you find the edge case.
You can actually kind of like showcase all of your different use cases for something.
And that can be used for a whole lot of things, right?
It's a really good common ground for designers and developers to discuss things.
All right.
So in the storybook is a JavaScript tool or for JavaScript?
Yeah, it started being like a React specific thing, but then it grew.
And these days, you can use it with pretty much anything that is not Elm.
That's oddly specific.
Oh, to be honest, like I've heard Matthew Griffith, I feel like they use storybook with
Elm as well.
So it's possible, but it's not that common, basically.
But then again, I used to work in a lot of different technologies.
So Dart and like React Native and other stuff.
And I've always seen people trying to replicate storybook as this.
So it became like a really poor man's storybook in all those different languages.
And I didn't want to do that in Elm.
So I've listened to Teresa say this once, like instead of trying to replicate the tree
for visualizations, she wanted to do something that was really unique and was special, like
in Elm's way.
And this was what drove me to think about this type of use case from scratch.
And at the same time, I just started using Elixir for work.
And the Elixir and the whole Beam ecosystem, they use something called Xdocs, which is
this automatically generated documentation library website.
For anyone looking it up, that's H E X.
Hexdocs with an H.
And I really loved it.
So everything was automatically...
I feel like since the whole ecosystem had this documentation thing ready for them,
it really entices everyone to be really good in creating documentations.
They can only focus on content and not getting the whole...
Like the whole...
How do I say it?
Like rubber...
I forgot the name.
They don't get sidetracked into building the foundation and they can just focus on getting
the actual content done.
Bike shading?
Bike shading.
Thank you.
There's rubber...
All of that.
I feel like we have the same thing in Elm where we have the packages that have their
documentation generated from the function and module documentations.
Do you feel like the Hexdocs system is better or does it have additional things that Elm
doesn't have?
I'm just curious.
Or is it a similar experience?
It's sort of similar, but they actually have...
They separate two different things.
One is function documentation and one of them is actually guides.
So you can actually host your guides inside your package documentation website.
You can access the two things at the same time.
So you don't actually need to have your own website to do the marketing and
everything else.
And you can actually...
If I'm not mistaken, you can actually team your documentation slightly.
So it feels like you are reading, I don't know, like Ecto's library instead of like
Phoenix library.
The branding is different.
So I don't know, I feel like Elm's documentation culture is already really, really good.
Exactly because you just mentioned.
The whole Elm packages are automatically generated.
The whole Sim version enforcement that the compiler does.
But then again, I feel like there was room for...
I'm not calling it improvement, but exploration basically.
And I tried to put together both the storybook interactive stuff.
And you can have snapshots that you are interacting with or just showcasing different states of
Or you can have actual guides and just use plain markdown and it already outputs into
something that is visually pleasing.
And you can mix them both.
So this is something that Xdocs does not have as well.
So Xdoc is pretty much static.
And in Elmbook, you can actually have this guide and suddenly there is an Elm component
that it can be whatever.
So there is this language called leaflink, if I'm not mistaken, that actually used Elmbook
to host our documentation.
And there is this small REPL where you can just...
And it's just built with Elmbook and it's interactive layer.
We'll drop a link there and show notes.
That's very cool.
I've been...I've thought about this a lot with the package documentation in Elm.
My personal experience has definitely been that I feel more confident figuring out how
to write code by navigating Elm documentation than any other ecosystem I've been in.
Like so many ecosystems, maybe you'll find something that automatically generates a placeholder
for every function.
But then you look at it and you're like, well, wait, but how do I use this and why would
I use this?
And you can't tell if it's like a low level building block or a function you should use
and it doesn't often have examples.
And the culture around that in the Elm ecosystem is amazing.
And largely, it's both an ethos that the tone is set by maybe people who build some really
high quality packages early on and people sort of promoting these things.
And then it's the tooling.
The tooling gives you these great tools for automatically have to have documentation
for every type and every function.
You can easily include example code.
You have tools like Elm verify examples, which is really beneficial.
But then, you know, and I've done some Elixir programming and I definitely have noticed
that it is very common that you'll see guides.
And in Elm, that's not very common.
You don't see guides.
You see amazing package documentation for each function and type in the API, but you
don't see guides as often.
Like you go and look at the Elixir absinthe GraphQL API and go to the hex documentation.
And it's a guide with like 50 different pages and grouped in these different categories.
And it's telling you how do you set up custom scalers.
And it's like a full on guide.
It's not just telling you how to use these low level functions.
So I have a hard time figuring out whether you say that in praise or as a bad thing.
I mean, you can find what you're looking for, for all these use cases.
And sometimes I feel like maybe we substitute those sorts of guides with just ask about
it on Slack.
There's not as much of an ethos as like, because package documentation is like, here's a function
or a type.
How do I use it?
But then what about I'm trying to solve this problem.
I have this use case.
How do I use this package to help me do that?
And that's not in our ethos quite as much to write full featured guides for that.
It takes a lot of work, but also we don't have the tooling for that.
So, yeah, it does feel like having a guide next to your API.
That does sound very good.
I think like what we do in the Elm communities use the ad docs and place them in the right
location so that you can write a story or write a guide or go from easiest to hardest
to simplest or more advanced in a way that is easy to understand.
But a guide next to it could be very, very helpful as well.
I feel like there is a kind of trap that you may fall into, which is when you have an actual
guide, sometimes you get a little too much.
You expect everything from it.
And you don't actually go to function definitions and try to piece the types out.
So in the hex, like the hex docs, the Elixir community, I feel like when something is not
documented in the guide, it's usually a lot harder to understand because everything is
There are types, but not the best types.
And even for Elmbook, I felt like since I do have the Elmbook guide, people usually
forget that there is also a package like Elmbook site that they can go through and just take
a look at functions.
That's a perfect example.
It would be ideal if both of them live together, right?
So in the Elmbook website, which is located...
What is the URL again?
It's on a Netlify page, but it's linked to in the readme for Elmbook.
So you have a guide with a lot of chapters and you've got one of the chapters, which
is the API, which links to the package documentation.
And I agree that it's a bit weird because you go through the whole guide, you skip over
the API at some point and you don't know when to reach or when to read one or the other.
Like, should I read the whole guide first and then look at the API or should I look
at the API and then read the guide?
So you have both of them together, but they're also very separate in a way.
I kind of dream to be able to just compile an Elmbook that it takes your Elm package
documentation as part of it as well, because it should be fairly simple, you know?
You have the docs.json file.
And you're not using like markdown to just like output everything.
So it should be possible.
But this kind of like leads me to another goal of Elmbook, which is to be completely
an Elm package.
And that in only that, you know, because I've really wanted to people to not need to like
install an NPM package or change their workflow to use Elmbook.
I really wish that I could like live inside the Elm ecosystem with its limitations and
et cetera.
But there are a few annoying things because of that.
For instance, like a really annoying like small thing for me right now is that if people
change the teaming mode, like if you go to light to dark mode, there is no way for me
to persist that state, right?
Oh, yeah.
As a pure Elm package that doesn't have access to local storage or...
Maybe a way for me to stay in the Elm ecosystem, but still be able to give more would be leaning
more into code generation, right?
So then I could output stuff like similar to Elm SPA or something like that.
Because like I don't say on pages because I feel like on pages is kind of drifting a
little bit with the whole Emdera, like the V3, right?
Right, right.
Server rendering and LameJar.
Yeah, I mean, it definitely supports static site generation still, but it's that's not
the only thing it's for.
Yeah, exactly.
So anyway.
So you mentioned that Elm Book is an application or an application in a package or...
The package is to build an application, right?
And it's not to build a Elm reusable element.
So if you use Elm Book, you necessarily get a program, you don't get a view, update, subscription
Maybe if you return that instead, then you can give more power to the user who can go
through code generation, who can have persistent storage of things, but they handle it themselves,
which is not as great an experience, but maybe you can provide both like an advanced setup
and the more simple built in setup that you have today.
Yeah, yeah, for sure.
Like this is one thing that I found interesting and I learned as I was doing it.
I'm trying to not change Elm Book that much right now because it's sitting on a V1 and
I'm doing a separate package.
I won't go into that much details, but it's called Elm Admin, which is the same idea.
It's kind of like this idea of creating an application, but the whole setup stuff is
built as a package, so you can just plug in and focus on your actual business domain instead
of the pipes.
One thing that I've learned while doing this new thing is that instead of trying to receive
just the views or anything like that, like I do with Elm Book, if I just really embrace
the Elm architecture and try to make it a full Elm architecture work and I can just
wrap it inside another Elm architecture, it enables a lot more for the user.
Elm Book is almost like that these days because people work...
I feel like this is kind of community driven.
When I first released, it tried to be like that, but I didn't notice all of the use cases
and people were asking me to do a few things, like to expose a few types, to expose a few
functions and these days, Elm Book, you can have pretty much your whole Elm application
there, but not as smoothly as I would want.
What I'm doing with this package is that you have your own one update function, one view,
one everything like you would have and it just handles routing and a lot of different
actions that you can use and I feel like Elm Book v2 would probably go into that direction
as well.
Yeah, that gives a lot more power to the user, I think.
I'm curious in an ideal world, when we were talking about that you should be able to include
examples in package documentation, is your vision that one day we would be able to embed
if we have a package for a date picker UI, that we would be able to embed interactive
examples where it actually runs that code and we can embed it like visual demos in the
package documentation in actual Elm package docs?
Would that be like a long term vision that maybe one day something like that would be
possible or would it be a separate thing that you deploy a separate site or how would that
I would love for it to be more kind of like an ecosystem thing because even though I don't
want to, it creates a little bit of competition which I really don't want.
But then again, a few packages, they end up doing the two things like Elm visualization,
there's a website full of examples.
Elm Shards, you have that amazing website full of examples that it's super useful.
If I'm using Elm Shards, that tab is open.
So it would be awesome to just have all of that available to everyone.
And especially if they don't have to actually spend time thinking about how to make things
work and be kind of like appealing to the eye and those things, just focus on their
own library.
Yeah, I've thought about that before with Elm Review as well.
Would it make sense for Elm Review to have its own special package documentation tools
that you could show, this is what this review rule will flag, this is the diff output it
will present to you for a rule fix?
Yeah, that would be amazing.
Complicated maybe, but that would be good.
But the effect, that's one of the fascinating things is the ecosystem impact of these types
of things.
When you have these tools available, like the tools that we were given in the Elm ecosystem
for building package documentation have really created this flourishing ecosystem of really
high quality documentation.
And it has an interesting sort of high level effect when you create these useful tools.
I'm actually quite curious, if you take the example of Elm Review again, the examples
that I give in the rules documentation is usually like this code would be flagged and
this code would be not flagged.
And I don't explain what the error message would be, I don't explain where it would be
Those would be cool things.
But I actually wonder, would it be useful for someone to know about that?
Because no one has ever requested that information in the documentation.
So I don't know if the documentation is enough as it is, or whether it's just a need that
no one has thought about.
It would be cool to have a more dynamic thing and to be able to showcase things.
But maybe this is good enough.
My hunch is that there's value to people seeing a concrete thing and that our minds are activated
in a different way when we see something real.
Like when you see a description of something, then you're like, okay, that could be interesting.
When you see a UI or a CLI error message or an Elm Review CLI message that's saying, here's
my proposed fix, would you like to change this?
Our brain does something different where it can connect to a concrete thing.
And I think there's value just to that.
The fixes would be cool.
The documentation for Elm Review Simplify would be so complex.
This definitely enables you to do a lot of yak shaving.
I hope that no one implements this, otherwise I have no life anymore.
No new projects will appear.
But then again, creating the playground for people to do stuff like that, it's always
pretty amazing when you see people do crazy stuff.
I would never imagine someone documenting their language using it.
And here it is.
With an actual REPL running the thing.
I'm curious, George, what were your motivations?
We talked a little bit about it, but can you just give a little background?
Because I know you're big on design.
That's an area of expertise for you.
I think you fit in that intersection of engineering and design, and you think about that a lot.
What were your motivations in creating this tool for presenting these UIs?
And what does your workflow look like?
Does every single UI widget that you build, does it go through this process and end up
on an Elm book page?
My motivation, basically, I feel like I wanted to build something in Elm.
Before doing anything in Elm, I used to do things in the storybook way.
I would create a storybook.
I would try to think about components in an isolated way.
Especially for other languages, side effects for languages, it's really useful to have
something that it will decouple your view layer from your logic layer.
It's a lot harder for someone to just, like, if it's a view component, it's a lot harder
for someone to put some crazy business logic inside it.
And storybook kind of, like, dinks into that.
Elm, that's already kind of like a given in a lot of ways, right?
But at the same time, I was used to it.
And thinking about visual functions and just, like, the arguments that they are receiving,
those things, it was just part of my workflow.
So I wanted to build something like that.
And it just kind of led to another, I believe.
That's really interesting.
Can you elaborate on that?
You said that storybook encourages people to think about components in an isolated way.
So you're saying in sort of, like, the React ecosystem, for example, is there sort of a
philosophy behind it that by testing your components that way, they don't have they're
not overly smart, they're more dumb rendering, pure view function type style?
Well, I'm a bit of a node school React folk.
I'm not anymore.
But I actually started using React when Redux was first announced.
And I kind of, like, really liked the whole approach.
And that eventually led me to Elm.
But as soon as Redux came out, there was also this idea of, like, components and containers.
I don't feel like people use that anymore.
But the whole idea is that you would decouple the visual thing from the smart component
that would only deal with the logic.
And from my perspective, that is a really good approach.
You can name it whatever you want.
But separating concerns is always a good thing.
So and for junior developers, I feel like this is especially useful, right?
Because if you are asking for them to build one specific thing here, and you give them
a storybook page, sorry, what?
A notebook page.
They are a lot more certain that what they need to do is more reusable and abstracted.
They are not relying on pure values that will just leak into the component.
You are creating clear separation that will need an API and et cetera.
So I was actually mentioning to you that I'm teaching Elm to designers at my company.
So using ElmBook is an awesome way of just giving them something that they can see something.
They can use everything that we have set up for our main application.
So we use Taowin, they can use Taowin inside of ElmBook.
And everything is kind of like everything feels the right way.
But then again, they are protected from the actual app and everything else, you know,
it would be different from using an le or the tri page on the Elm link, because then
we will not have all of this kind of like extra setup that we already created.
Yeah, you would also not have git versioning and stuff like that.
Which sounds useful.
Sometimes it's the best way to start, right?
Actually I have been using the Elm link tri page a lot to just like, okay, this is a small
Let's just do this.
And it's pretty amazing.
Yeah, I can imagine how I haven't personally worked in a sort of workflow using a tool
like ElmBook or Storybook in the past.
But I can imagine that it does make you be more deliberate about creating a design system
and thinking about both things in isolation and then how they fit into the overall look
and feel.
So you don't just say like, oh, let's add a little more padding to this button.
It looks weird.
You say, what do our buttons look like in our application?
And what do you know, what does this widget look like?
And when when Yurin and I first started Elm Radio, I, you know, it was like this big open
canvas of what does the Elm Radio website and styling and logo and stuff look like.
And I used Figma for the first time and that was really cool.
And that really helped me be like deliberate about like, at first I was trying to just
put together like an Elm pages page and it didn't look so nice.
And then when I started like being more deliberate and then I could like have a Figma mockup
and then say, what do you think of this Yurin?
And, you know, we'd go back and forth on it.
And that really helped being like deliberate about thinking about the look and feel rather
than just diving into code.
So I feel like there would be like a similar experience with this sort of design system
approach with Elm Book.
Yeah, definitely.
One thing that I noticed when I first joined, at least like it was how I felt.
It was that like the Elm community has a lot of flow, like a lot of packages to do with,
I don't know, complex data structures and like things that are more lower level.
But then again, when you go like the higher level, like I just want to get stuff done
and use the Elm architecture for the things that I really want to work on.
We don't get as much stuff like ready for to be picked off the shelf, right?
Yeah, like a select box or stuff like that.
And not only that, right?
Like even the UI frameworks, because we do have like awesome stuff like Elm UI and Elm
But those are, I will not call them UI frameworks in the sense of like reusable widgets, right?
Like they are more like structural.
Yeah, more like UI primitives.
And when you go to actual UI widgets, like collection of widgets, there are mostly translations
of things that are used outside of the Elm ecosystem.
And they sometimes require JS and they, it's like that I feel like this is an area worth
exploring as well, you know?
I don't know.
Like I feel like the whole make Elm a lot nicer for people to just like plug stuff with
the really awesome like logical tools that Elm give us.
This is something that maybe we could use.
Do you think that Elm lends itself to that or like how much of the state of sort of UI
widgets in the Elm ecosystem is because of like the size of the Elm community slash the,
you know, maybe number of people who gravitate towards it because they like thinking about
data structures more than nice designs?
I think I fall into that category perhaps, but versus how much of it is because some
sort of UI widgets want to be, have self encapsulated state and maybe something like a web component
would be a better fit for a date picker or something like that.
I feel like both.
I don't know.
I haven't seen yet a lot of designers in the Elm community.
When I started by taking a look at the whole like Elm cones videos on YouTube, et cetera,
and I thought that it was like a really plural community.
And it is like people like we have tons of different niches that people are really diving
But design, I don't feel like it's the like one of the bigger ones.
So at the same time, you are totally right, Dillon.
Like sometimes UI tends to, they could use like internal state for something that is
really complex, like a date picker or something like that.
And it's really hard.
I think it's really hard to both create something that is isolated enough to be like placed
as a package, but at the same time customizable enough that you can kind of like make it your
own and fit your use case.
Like those things are rarely something that you can just like plug and play and they output
exactly what you want.
Or even the look and feel sometimes is not what you want.
So those things are kind of like harder to get right.
Yeah, especially when you have a designer on your team and your designer says, oh, well,
we should have a date picker and it should look like this.
Or you're like, well, I can find a date picker on the Elm or the NPM package registry, depending
on the language you're working with, but it's not going to look like that.
I can try it, but it's going to be very hard.
Oh, and then it's missing a feature or there's some additional feature that we absolutely
don't want.
It's very, very hard to get things exactly right for everyone.
And that's why I feel like in Elm people just tend to re implement themselves.
And I think that ends up being for the better in practice.
But yeah, maybe you're right.
It's just we have a lack of people who are interested in designing and publishing UI
Yeah, but then again, I'm totally with you.
I feel like we tend to re implement everything again and again.
For better or worse.
But there are some things that are really hard to get right.
Like a date picker, whenever you're dealing with time, you try not to.
And if you take into consideration accessibility and everything else that goes along with it,
then there's no way.
So it would be awesome for us to either be closer to the custom elements community, if
there is one.
And at the same time, have something that is kind of like fills the gaps.
Because a lot of the times you don't need custom elements.
You can just have something that is more using the platform.
But then again, you need it.
I just listened to the episode.
So I'm kind of like, it's in my head.
So I don't know.
I feel like we could use both, probably.
I would love to see more widespread use of web components in the Elm community.
And I think, I mean, increasingly we're seeing, you know, very large sites are using it quite
a lot.
Like, YouTube uses web components a lot.
The Adobe Photoshop in the browser, from what I've heard, is built entirely out of web components.
And they're becoming more and more full featured and more widespread.
And it would be amazing to see a set of these sort of lower level UI widgets that have self
contained state.
Yeah, but they're not going to be published on the Elm package registry, though.
So it's like maybe a lot of applications use web components, and we don't know.
It's just we won't see them in the packages.
Whereas in React, well, or in JavaScript land, then yeah, you can publish packages with web
components and you can figure out whether people use them a lot in that community.
You can tell that.
I'm not saying it's used a lot.
I'm just saying it's hard to tell.
That's right.
Well, shameless plug here.
I'm actually muting one thing here.
I'm muting those two things, right?
Elm admin and Elm widgets, which is kind of like proposes itself to be kind of like that.
But I'm avoiding as much as I can to use any internal state because it gets harder to integrate,
even if it's a little bit.
And I'm going to focus on everything that I can do without custom state, basically.
And then maybe something like that could point to, okay, but you do need a dick picker.
If I do have something like if I'm using Elm book as a guide for the thing, I can actually
have guides that point to other stuff in the community and not just the same package that
you are using.
I don't know.
Doing things in this way, just like establishing the boundaries that you're trying to solve
and be really explicit about the things that are outside of the boundary, it makes sense
as well, right?
For the Elm community as a whole.
Yeah, it is also interesting how when you have vanilla Elm HTML and Elm UI and Elm CSS
and even other sort of less popular approaches are out there.
And in React or Svelte, it's just like JSX or HTML templates.
That's what you work with.
You don't have this abstraction over those types.
And whereas in Elm, we have the element type in Elm UI and the styled HTML types.
We have the virtual DOM.
That is primitive.
At the end of the day, it needs to turn into that.
But you can be using these building blocks that are a wrapped version.
And then at the very end, it's turned into that virtual DOM building block, which everything
turns into that if it's going to be HTML on the page.
But it does make it harder to intermix things that use these different tools.
And I wonder if that is a source of fragmentation that other ecosystems don't have to work with
in the same way.
In the React ecosystem, they have a lot of fragmentation with state management, the state
management layer.
I wonder if we have similar fragmentation in our UI layer.
To be honest, in the React world, it's kind of like a false sense that you can just plug
and play everything.
Because in practice, things work really differently from each other.
Sometimes they are not really compatible.
When you want to plug things into each other, then it becomes like a mess.
I'm not sure.
I feel like sometimes we see NPM with...
I was just taking a look at Sorrybook, for instance.
They have 16.5 million downloads a month and like 1400 contributors.
So then...
So it's kind of hard for us to take a look at that and not feel like, okay, it must be
But then again, when you are actually using it and feeling the pains and trying to make
things work together, it's not as nice.
And sometimes it's not possible as well, but at least it's more visible.
The boundary layers are really visible.
When you are using LMSSS and you want to use LMIUI inside it, you can.
You can just translate to HTML and then back to something else.
But then again, sometimes by doing that, you are making your application a lot slower because
you are creating the same styles over and over again.
Foot guns everywhere, basically.
I mean, the composability problem is always challenging.
How do you create a way to solve a problem and how does it compose with other ways to
solve the problem that might be operating at a similar level?
They don't necessarily fit together neatly.
It's hard to design things that way.
So would you use virtual DOM as the primitive if you were to build a UI package?
Because that is the easiest to...
And the most lightweight as well, way to create a UI package.
You're not adding LMSSS or you're not adding LMIUI, a lot of code that maybe wouldn't be
in there otherwise in your application.
Exactly that.
It's funny because maybe I'm doing something that is awful.
I hope not.
But I'm going really old style in the styling of those three things, the widgets, admin
and elm book.
Because I don't know, a few years ago, you had global CSS and it kind of worked in some
ways as well.
People managed.
You do not have to have a hash for every class that you are using in those things.
So I'm actually using standard CSS with all of those.
And I'm compiling them to a single node with styles that I want to use.
And if you do it right, it becomes a really small bundle and it works.
And you can just avoid name clashes by doing your own prefixing and then using something
like Banner or something like that.
And perhaps there will be another person that is using the same prefix and then things will
go wrong.
I totally forgot about the issue with CSS.
That's a problem.
For Elm book, for instance, I don't have any CSS reset.
In any of them.
Because if I do, well, what Storybook does, for instance, it creates an iframe so that
you can have your own component.
There's advantages.
You can have all of your styles only on that component.
You can actually mock different screen sizes, triggering actual mobile responsiveness settings.
It's harder for me to do that without relying on iframes on Elm book.
So what I'm doing is just like I'm styling in the more specific way possible each of
the elements that are part of Elm book.
And if someone says, like, okay, this is kind of broken, I just go there and battle test
the whole approach.
And sometimes it has been working pretty okay, at least.
Maybe the iframe solution would even work, right?
Because I could be hosting the same Elm book, like an internal URL, and then just displaying
the iframe for that URL of the same application and making things work in that way as well.
If you have control over the DOM because you use an HTML file, then maybe you can inject
the application inside a shadow DOM.
You don't know if you can do that through Elm.
Don't think so.
No, you need JavaScript to create a shadow DOM.
Iframes, as far as I know, they don't share styles, right?
Like at all.
I have no clue.
You tell me.
They don't.
Like it's basically a window to another.
I was even reading that it spins up a different...
It's kind of like a different tab in your browser, but you're just looking at it.
So it takes twice the resources and those things, all of the amazing things that you
can expect.
But it's an internal tool, right?
This is the one thing, the challenges that I'm trying to tackle, at least in this application
as libraries, they don't need to be user focused, performance focused applications.
It can be kind of like internal tools.
They need to work, but it's fine if they are a bit of the heavy side and if they work well,
Because there is...
I mean, one of my things that I spend a lot of time thinking about is avoiding running
markdown parsing and syntax highlight parsing in the client.
But to do that, I've thought a lot about how to use Elm pages to sort of do that pre processing
so it can send you the parse to mark down so that work doesn't have to happen in the
browser and same for syntax highlighting.
But you can sort of say, well, if a user is doing this on their mobile phone over a slow
3G network, maybe that's not ideal, but for internal tools, that's all right.
I hope so.
I don't know.
So I was noticing for the Elm UI, I believe you just do basic HTML rendering for the markdown
parsing and then you embed the components with Elm UI, but you don't change the render.
So when you do a custom renderer, you don't change the markdown rendering in Elm book.
Yeah, I don't.
Which makes sense.
It's only the components, right?
It's kind of in isolation of everything else.
So you don't have to have this heavyweight custom configuration where you're giving
a custom Elm markdown renderer for Elm UI if you use that.
For sure.
Maybe again, like maybe there are downsides for that, but I feel like that's okay for
an internal tool.
For instance, like there are possibly most definitely there are like duplicate styles
if you're using something like Elm CSS or Elm UI, but the duplicate styles are just
like extra weight in the HTML, right?
Like they are not really clashing with each other because you are using the same framework.
So that should be fine.
One thing that I was curious about your opinion on was, well, Elm book was my first Elm app
and also Elm library, right?
So coming from other ecosystems, I tried to replicate a few things on Elm book.
Like I feel like there is a lot more handholding in other ecosystems than in Elm when it comes
to just like using a package.
Do you mean through guides?
No, no, no.
No, I mean through kind of like helper functions instead of exposing the primitives that you
can create everything yourself.
I feel like in Elm it's pretty common to focus on primitives and kind of like explain how
would you roll your own something and then kind of like leave people to it.
And I actually asked a few people about Elm book and I got this response.
Like I don't know, I feel like there are too many helper functions and because I definitely
did that, like I feel like if I thought about our use case, it would be easier to do like
instead of everyone trying to like do this three steps, I just created a helper function
that did all of that.
But it should be possible by just like using this bare bones function, you know?
And I expose both.
And this is something that I'm kind of like struggling against right now.
I don't know if this is something that it's actually useful or if by doing that I'm actually
teaching people to expect everything to come from a helper function instead of like just
be creative and roll your own, you know?
Yeah, maybe.
I also feel like if you expose a lot of help functions or when you say help functions,
you mean one function that does the equivalent job of three functions composed in a specific
way, right?
Stuff like that.
So if you have a lot of combinations that are possible, you will have to add a lot of
And maybe at some point people will say, hey, well, there's a helper for this and this and
this, but not for this.
Can you please add it?
Like, yeah, sure.
And also for a user, they have more APIs to know about and some of them may have like
some specific workings like, oh, this one renders this chapter or this element.
But with this slight modification that you might not expect, I feel like it's easier
for people to read something that is slightly longer, but that is common.
If they see the same functions over and over again, they get a good grasp of the API.
But if you have a lot of helpers for different situations and they use all of them, then
it's really hard to know which one to use and to know what something does if it's the
first time you encounter it.
Maybe it goes into the guide direction because like if you just provide the primitives, but
you have kind of like an awesome Elm, like, you know, like those examples, folders or
something like that, that people can just like actually provide ideas of how you can
use those things, then you are doing both, right?
Like you're providing the cleanest steps, the cleanest API, but then you are also showing
how to do the, how to actually create the helper function that you need and then make
it your own, right?
People can write those helper functions themselves.
One thing that it was like, I released Elm book with like a bug in two helper functions
and the fix would be a major change.
So I never fixed them.
I just like wrote like, dude, this is a helper function.
Just write this instead.
And then that's fine, you know?
But then again, they are wrong and they will still be wrong when you hear this, listen
to this.
But only two, I promise.
I don't know.
I mean, there is an Elm review rule for reporting deprecated, usages of deprecated things.
Maybe you can just market as deprecated and then people will not use them anymore if they
use that rule.
But yeah, that's a very good reasons against a helper functions.
If you know that they have bugs, then don't write them.
There you go.
Lesson learned.
Lesson learned.
It is API design in Elm is fascinating because I have the feeling that more so than another
languages and ecosystems, Elm package authors really think very carefully about all possible
use cases and how to support them.
And I think that the Elm language to a certain extent is, it makes us be explicit about things
because for one thing, you have to be very explicit.
You have to be very explicit about what the types need to be and how many arguments something
takes and you can't just sort of fudge it or say whatever you can pass whatever in.
You have to be very thoughtful about what it's going to accept because the Elm language
requires that.
You can't say, oh, well now we have a new feature.
If the arguments of this existing function is now a Boolean, then it does that thing.
Like if something, if you pass in a list now, then it'll do this, but before it only accepted
a single item and it had this different behavior and you could pass in Nolan, it would do this
thing and in Elm you have to really think like, what do you want your API to be?
Because you're sort of putting the stamp, like setting it in stone to a certain extent
or making it a breaking change if you change it.
And now I have goosebumps because of the API.
It's a pretty intense experience to create Elm APIs because you have to think through
all these use cases very carefully and we try to make impossible states impossible.
So we try to like create all these types and APIs to avoid these things.
But yeah, as far as like helper.
And also we care about major versions because we have to.
So if you did the same thing in JavaScript, then you could just, oh, well, I'm just going
to remove this function or I'm going to change the way it's written.
Making a breaking change.
Just make a breaking change and do a patch version.
No one will notice.
We can't do that in Elm.
So we have to get more thoughtful or people will know that we have, that our version one
Well, one thing that I noticed that Teresa did with Elm shards was that she had the Elm
shards library and then there was like this shards or I don't know, like one other stuff,
one other library.
And the other one was kind of like version 18 or something like that.
20, I think now.
Like, I don't know.
It's crazy.
But I really liked the approach of it's still a valid use of the Elm packages.
If you have like an alpha version of your package that it just doesn't care about like
major versions and you can just like be completely crazy and then you stabilize and actually
create something that is more stable and ready to use.
So I actually talked to her about it.
Like, oh, I love the way that you are doing like the nightly releases.
And she was like, oh, likely releases.
And then this was like explained as night releases then, you know, and I'm seeing the
idea right now in everything I'm doing, like the whole, like the stuff that I mentioned
that they are already published, but all like alpha and please don't use them.
But then shortly, I hope they will be like actually released, you know?
Just a word of warning because it comes to mind.
If you have a package that depends on, let's say Elm charts and you want to switch, use
it and you want to switch to the alpha version.
So which was Teresa slash charts instead of Elm charts, then that's not going to work
because you're actually depending on the Elm charts package through the other package.
I don't know if that's clear.
So if you use Elm charts extra, for instance, that depends on Elm charts, which locks you
into using Elm charts and it doesn't allow you to use Teresa slash charts.
Got it.
Because of name clashes basically.
Because the Elm charts extra would depend on Elm charts.
You could depend on both, right?
In theory.
But then again, the names will be the same and you put them in the right way.
So the module names would be the same, so you couldn't use them together.
That's true.
I'm just using the alpha stuff because I'm using them right now, but I really strongly
advise like don't use them.
But then again, it helps you to just like there's a doc there and you can test it in
a standard way than just like doing the whole like source directories, you know?
I like the source directories.
I'm the only one.
Got it.
It's fun for examples, but when you are trying to just like the whole Git sub module stuff
Oh, yeah.
But that's alpha don't touch.
You should try the alpha package for the LN pages 3 alpha.
That would be helpful, actually.
For instance, like we in our company, we have like a shared package, but managing the dependencies
of it, like in everything, every time we start using it in other packages, we have to add
all of the indirect dependencies as well.
Like it's awful.
But at the same time, I really didn't want to share like this internal package, the own
I know that a lot of companies do that.
Like NoraLink does that for the UI, right?
But I don't know.
I mean, it's annoying, but you can at least you can make it crash.
It's not like there's insecurity about doing it wrong.
It's just like you'll get competitive errors and you have to do manual stuff.
Is it worth it?
I don't know.
So you use Elmbook for writing your company's style guide, right?
Do you have any recommendations on how to do it?
Like what are some things that are very important to know and to do for style guides that people
who have never written one should know about?
Well, in my opinion, the best thing to do is to think of style guides as kind of like
a part of your test case for your visual components.
Because if you're using Elm, you have like the whole compiler and the type checking as
part of your tests.
So I usually have like a module for something.
I don't know, like an UI.button.
And inside that module, I will have my usual functions, but I also have like a docs function.
And the docs is just like the chapter for that particular piece of my UI.
And it sits together like in the same module.
It's really easy for me to like, if I change something that something breaks, I can just
like go to the docs and change it.
It's a really non isolated way of working.
And in Elm, this is completely fine, right?
Because like we have that elimination.
And if I'm not using the docs in production, I don't care.
I can just like expose them.
And it's docs, right?
Like people wouldn't get confused about like just using the docs for this here inside this
page like by mistake.
I hope they won't.
Instead, the docs will expose an Elm book chapter.
So even if they did, it's not compatible.
So this is something that I always do.
I have like one chapter per feed.
Because you're, we actually didn't talk about how Elm book works, but Elm book is a series
of chapters, basically, right?
And each chapter you put in some markdown and list of things you want to add to that.
Elm book is basically a group of chapters that you glue them to a book.
But inside the chapter, you can give any piece of like markdown you want and just like create
this guide.
Or you can give like a list of components.
They can be static.
So it's super simple to just like give it some HTML and that's fine.
Or they can be dynamic and you can receive a dynamic state.
They can use that state.
They can trigger messages.
They can like change and just like work as a normal Elm application.
And you can mix both things together, right?
So you can kind of like each chapter has a registry of components.
And you can like add components to that registry and then use them inside your markdown whenever
you want.
So you kind of like tag them with labels and then you can specify the labels inside the
markdown when you want to use them.
It's very cool that you made a sort of meta tool around Dillon Kern's Elm Markdown for
sort of using the HTML renderer to render these components.
It's very neat.
Very clever.
Yeah, definitely.
Thank you.
I have no idea how would I have done that without it?
I really like how you're basically able to abstract away all of the details of the fact
that it uses Dillon Kern's Elm Markdown.
So as far as the users are concerned, they don't define a markdown renderer or touch
that API at all directly.
But under the hood, it can say, well, let me define an HTML renderer.
So if you say, if you do a component tag and you say with label equals, then I'm going
to take that over and render there.
But the user doesn't have to ever interact with Elm Markdown directly.
Yeah, that's exactly it.
One thing that I really like, Elm is just functions, right?
And our views are also just functions that receive stuff.
There is an alternative in the ecosystem called Elm UI Explorer.
It's slightly different from Elmbook.
As far as I know, it relies on an NPM layer.
You have to run a init script.
I feel like you have to run the application through it as well.
But they provide knobs.
I don't know if you are used to that idea, but it's basically kind of like ready made
tools for you to mess with component props, basically.
So you specify, okay, this component takes a bool, a string, a color, a list of values.
And those knobs can act inside that component and you can interact with it without actually
specifying the whole interaction layer.
So this is something that I really hope that could be possible in Elmbook, even without
being the main library.
Because if you have a view and a way to interact with the state, you could possibly wrap that
view with whatever you want.
We could have a separate knobs library that could just be plugged on top of Elmbook.
But I don't know, maybe Jeroen has a similar opinion.
But you created Elm Review.
But at the same time, for it to make sense, you also created a whole bunch of Elm Review
rules, right?
So maybe this is something that I, okay, this is kind of pluggable.
But maybe I'm the one that needs to do the plug in as well, you know?
So the idea behind the Elm Review in this case was I'm going to write a rule.
People might not agree with it.
And I don't want it to be something that is considered to be core.
Because otherwise, other things should be considered core and I should write it.
And if it's not done right, then it's just not done right.
But if it's a plug in, people can fork it, can improve it, can publish it.
In practice, I did write my rules pretty good.
So they didn't fork it.
So maybe they could have been put into the core rules.
But it's still like the idea that there are no core things.
So yeah, if you can have a plug in system like that, then that would be cool.
It doesn't require more API design, obviously.
And it's going to be harder to give all the tools to your plugins that you may want to
use with them.
But if it works well, then it's great.
I could imagine code generation being really cool for something like knobs.
I mean, I don't know, maybe that's overengineering.
But you know, I imagine it's a lot of wiring to sort of serialize, deserialize all the
UI interactions to change Elm custom types and wire them through.
So you're thinking if a view function takes an integer, then you have a slider, then you
auto generate a slider.
I guess those ones would be the easy ones that it's like, well, I know how to handle
input for strings and integers.
But then for a custom type to automagically have a dropdown that just auto generate.
So you could have an API to manually give me how to turn a custom type into a string,
how to turn a string into the custom type.
And I'll present a dropdown and choose the option based on that.
But could use some nice code generation to avoid having to write those two string from
string functions.
Yeah, definitely.
This is actually what I'm doing in Elm admin.
So for the forms, you can just place custom types.
And I don't need the from string to custom type back.
Because if you provide I can just like create the pairs, right?
And I can use the pairs to get back the custom type you provided.
But yeah, this is definitely possible.
One thing that I noticed is that the whole Elm architecture is a really awesome plugin
system for if you are building this application as libraries thing, like the whole idea of
like having a message that it would change your piece of the model and you get like an
update of that piece of the model.
And you can just like you can even trigger like HTTP requests or anything.
Everything is pretty well scoped.
And you can just like map those things so that they can like stick to their small like
loop of interaction, right?
There are some ways for you to kind of like watch everything that is going on and plug
into like the right pieces of interactions, you know?
I don't know.
I feel like for libraries as a whole, it can be tricky to create like an API for plugins.
But for applications that are kind of like wrapping everything up inside of them, it's
a bit easier, I believe.
It's cool to hear you talking about Elm as a good tool for building sort of pluggable
systems and frameworks because I don't know, I would imagine that people tend to think
of it actually the opposite, that everything has to be so explicit and you can't just have
implicit state, you can't just pass anything anywhere or grab global variables as needed
or do global side effects.
If the plugin uses a message or a model and you need to define it, then you can't make
a list of those because they have different types.
Right, exactly.
So I would imagine people tend to think of it the opposite, that Elm is not a good fit
for that type of thing.
But on the other hand, it's like a very well defined thing that you say where this box
fits in and you give it the pieces.
So it's very neat and isolated and clear what the contract is on the other hand.
Yeah, I feel like this is not something that I've been working on, but something that I've
really hoped to have the time to work on.
But I feel like having an Elm, not macro system, but an Elm template layer that will always
output the source of truth, but you can work in the template layer a lot, but just have
like this small Elm generation tags that will output something else in the other file and
you can have both all the time.
Maybe something like that could help a lot with just the amount of glue code that sadly
it's kind of like it comes with all of the good things that we have with Elm, right?
But there is no denying it.
There's a lot of boilerplate that comes with having something that is really explicit,
especially when you want to do impossible states and you want to just like define everything,
you want to be really defensive in your application.
Like people in my company, I always say like, don't fear like long pieces of code.
Just do that.
It will be easier to maintain.
It's Elm, it's safe, but it's a lot of code.
So if we could like remove all of the things that are always the same and just like have
a template that we could also create in Elm perhaps, I don't know, it would be pretty
awesome, right?
Kind of like an Elm review more focused on generating code.
With building Elm pages, it's been really interesting because I think that people also
underestimate what you can do with these building blocks.
And I mean, code generation is a big part of it, but like sometimes people ask questions
like how do I get an environment variable, which Elm pages has ways to reach in and get
an environment variable.
But people ask this with other tools and I say, well, I mean, if you really need to,
you could write like a node JS script that generates an Elm file and says process.env
and gets some value and generates a top level value and exposes it.
And it's actually like five lines of code.
It's pretty easy to think about.
You have to make sure you run it at the right time on your build and on your dev servers.
And that's a little bit annoying.
Maybe there could be some like tooling to help make those sorts of things more manageable,
but actually like doing a little bit of code generation is extremely powerful and pretty
Config, it's super useful, right?
Because since you are compiling the application, there is like you are checking that everything
is actually there.
You can't achieve something that is missing information, right?
So if Elmbook, you've talked about and I've seen in some of your notes, like some future
ideas for this CLI for Elmbook.
What might that look like if there, let's say, you were talking about sort of always
exposing docs from your sort of view modules.
What would it look like if you pointed a CLI at one of those modules?
What would it do?
Yeah, to be honest, like I would still want for people to use Elmbook like in Elm itself
so that they can actually have like all of the type safety and not like automatically
create examples for view components.
It could be possible.
But I was more leaning towards if you could output a complete Elmbook from your package
docs, for instance, and mix that up with extra stuff that you're defining as Elmbook, that
would be like for me even like more interesting.
If I accomplish that, it would be possible for me to actually like generate an Elmbook
for every package that is published.
And I could have like a second repository, like registry, and that would kind of act
as a duplicate of the packages.
We already have one like that, right?
Like a separate...
But one that we could maybe have like two tabs or something like that.
One would be like the hex docs.
One would be the actual docs and the other one would be the guides, right?
The guides, the design system and everything else.
This could be interesting.
Yeah, it would be very interesting.
I have not gotten around to it.
And I have mixed feelings about creating something that it's even more clashing with the package
docs, you know?
And then I would imagine, I mean, if there were some sort of package host for this, like
would there then be a place where you could have pure README files or Markdown files that
would be detached from a package?
Because that's what hex has, right?
You can have folders with Markdown that are independent of an actual API module.
Well, you could mix everything up, right?
Like you could have the guides as Markdown.
You could have like the more, I don't know, the more interactive stuff built with Elm.
Maybe register something with Elm and then use it from the Markdown file.
Because like, let's be honest, writing Markdown in an Elm file is not that great.
So like we can mix everything up.
But then again, I would not do that without first having the Elm book as a fully functioning
Elm package, right?
That would be definitely like only a layer built on top without changing any of the core.
I think it would be interesting what would happen with the ecosystem with that, you know,
because like right now, I know Evan has talked about writing package documentation by going
through an API and reading top to bottom, like a book, like a page in a book, you read
the package documentation and you try to present the docs in coherent sections and in a flow
that kind of makes sense and gradually introduces you to the more complex ideas, which is really
And I definitely have tried to do that, like with Elm GraphQL, if you look at the selection
set module documentation, like I'm, you know, I put a lot of thought into making that essentially
a tutorial where it's kind of presents you with like, what is the selection set?
And it walks you through, well, here's selection set dot empty.
Here's how you can create a selection set without any fancy ideas, without any understanding
of the generated code or anything.
Here's a selection set you can create and here's how you work with that.
But if we had a separate concept of guides, then, okay, well maybe that belongs in one
place, but I don't know, maybe there's a guide for the CLI.
This is how you use Elm GraphQL CLI and here's what the code gen means.
And maybe the read me gets like a little more concise and points you to the relevant sections
of the guide to get started, for example.
It could be interesting for the community to have something like that.
I think there might be a little bit less love for the API documentation if you have guides,
like how do you integrate them into the REST, which I think works really well at the moment,
but for sure there are definitely cases where it would be super valuable to have additional
documents like even just for Elm review, I need a read me for the CLI, which is on the
It would be super to have it inside the package registry as well.
And so I feel like I also do the story with the Elm review documentation, but if I had
a guide format, then I would probably do the same thing, but it would be better cut, better
separate into sub chapters because for instance, the review.rule module is huge because there
are so many examples in there.
And you've got extra stuff, right?
Like two things.
First, this is not really well done as I discussed with you before this chat, like the search
feature in Elmbook right now, it's really basic, but nothing for visits from being kind
of like a full search for the whole Elmbook and actually presenting some nice results
in a separate page, et cetera.
So this could be quite good for something like Elm review, right?
Like people would not have to search for functions, but something else.
And yeah, and the other thing is that like the interactive part of Elmbook, once you
have that ability, maybe you think of extra stuff that you wouldn't otherwise, right?
Like maybe you would create a code generation tool inside your own small thing.
Think of your HTML2 Elm site, Dillon, but maybe something like that could be part of another
package, but you can just generate code for the package that really fast.
This would be useful as well.
It opens up possibilities and that's mainly what is the main goal.
Well, now the question is what possibilities are those because you need to make an API
for that.
And that's the tricky parts.
If it's just having a nice way to present some sort of markdown pages and then embed
some widgets within those, then it sort of does that.
And then it's a question of how would you translate existing packages into something
that would turn into that and that gets interesting.
Yeah, because like the interactive part, you've got a kind of full Elm architecture.
You can send commands, you can get to the response and you can update your state, you
can do whatever.
So yeah, you could use an external API to do anything and just present it on your guides
or your docs or whatever.
Yeah, I like the simplicity of it.
I mean, like in a sense, it's like you said, you don't need that many features and you
don't really need to think about sort of navigating between chapters and pulling down the menu
of chapters to select from and grouping them.
Those sort of primitives are there.
You don't have to think about markdown rendering.
Some of those things are kind of annoying to set up and to think about and then kind
of presenting those things in a nice sort of overall layout.
So it's nice.
You can sort of get a jumpstart so you don't have to think about those basic details.
You can just think about your content and your widgets and that's all you have to think
Well, thanks again, George.
It's been a pleasure having you on.
If people want to find out more about you, where should they look?
Where can they follow you?
Where can they keep up with what you're working on?
Yeah, they can find me on Twitter.
My handle is the same everywhere.
So GeorgeBorys and I'm always on the Elmslack and the few Discord servers as well.
I'm everywhere.
So just ping me and I'll get back to you.
One thing that I'm kind of sometimes bad at is I don't know why, but I don't get any notifications
from GitHub.
So if you open an issue and I'm not responsive, please just like ping me.
I'm not like ignoring you.
I'm just like bad at it.
Sounds good.
And are there any other resources we should point people to?
Like if somebody wants to learn more about Elmbook, what resources should they be looking
Yeah, we should definitely link the Elmbook in Elmbook website.
But it's pretty easy to find in the package website as well.
If you write Elmbook, it will be the first match.
Are there multiple Elmbooks?
I feel like even book, there is like two.
There is the one that I made previously to Elmbook, which is called Elm UI book.
I didn't want people to get confused and I didn't want to be only about UI.
So I changed the name.
But Elmbook is the right one.
I know that Elm UI Explorer has the same issue.
Like it's not about Elm UI.
Just what is the author name?
What does it stand for?
This is my personal company.
It's kind of like DataWorks.
Something like that.
But my new work is coming under a new handle called
So if you want to follow the other stuff that I mentioned, please take a look at the
All right.
Thank you again, George and Jeroen.
Until next time.
Until next time.