Surface - A component-based library for Phoenix LiveView

Bummer! Would be great if we could somehow use it on non-LV projects without requiring significant work on core LV. Is there a way to make a new component type like Surface.StaticComponent or something with the current behaviour that doesn’t depend on LiveView?

Just hoping there is an easy way to support this because I much prefer the benefits of using this (so eloquently laid out in your earlier reply) versus EEx in non-LV projects.

You have to pick your battles. Trying to decouple early on will slow down development to accommodate a small fraction of users, so punting on this is something that I’d continue to kick down the road.

1 Like

I see this more as a design choice that can hurt down the road, then a question of decoupling code, but I don’t know the code as well as you :wink:

Are you really sure that is a small fractions of users? Seems that you are over confident that “everyone” will be using LiveView in their projects?

Sorry, I didn’t mean for it to come across that way. Speaking from experience, folks very often push for maintainers to decouple too early in projects, and it almost always is the wrong call. You can get lost in the weeds way too early instead of making forward progress to 1.0. For now, I’d focus on getting the surface model and features intact for its intended purpose.


I know that you haven’t said it with that intention, that’s why I used “everyone” between commas :wink:

Since I’m still working on the core features, I didn’t have time to build a full suite of components yet. However, all examples in my demo were created using Bulma, including a live Dialog component that handles events. As far as I know, there’s also a WIP by @joerichsen using bootstrap.

I understand your concern but I have to agree with @chrismccord on this one. The problem is that having too many different kinds of components at this moment will certainly slow me down. My main goal now is to validate the model in the most complex scenario, which is using stateful components with LV. If everything works as expected, adding a simpler version for non-LV projects will be a breeze, trust me :slight_smile:

I’ll definitely come back to this discussion as soon as I finish If until then we have no solution on the LV side and we find out that a lot of people want this feature, I’ll consider creating a new separate Surface.StaticComponent as suggested by @tme_317.


is there a way to render a component in a .leex template? I am looking to add a Live Layout, and I believe that means I need to point to a leex file, but if possible I would like to reuse some Surface components in that template. I have tried <%= live_component @socket, MyComponent %> but it appears it is missing some preparation (the :surface value).

Hi @regal!

Currently, surface components require some preparation as you noticed. I opened this issue to create a surface_component/3 wrapper that could replace live_component/3 for those cases.

I have a quick question though. Would you still use a .leex file if you could load a .sface file that accepts the surface’s syntax instead? The .sface proposal is described here. I’m trying to list a few possible scenarios where this feature would be useful before start working on it.



@msaraiva thanks! re: .sface vs .leex, I would definitely use .sface files in this case. I’m a big fan of Surface and it is my go to approach to LiveView whenever it is possible to use.

ps. thanks so much for your work on this great library!

This is very interesting. What’s the story around forms? Currently I get a lot of mileage out of the phoenix html form helpers, would that require a port to this or is there a way to embed ordinary LEEX inside this?

1 Like

Hi Ben!

Any LEEX code generated with ~L or loaded from a file can be injected in a Surface template. You can even use ~L directly instead of ~H in your render/1 function. That’s the strategy I use to wrap form helpers when I need. However, the plan is to create official built-in wrappers around all those helpers to offer a more context friendly set of components that can be used directly without the need to fallback to LEEX. There’s already an issue for it and it’s on the roadmap for the first stable version :wink:


Hi folks!

Surface v0.1.0-alpha.1 has just been released with lots of bug fixes and new features. Here are some highlights:

  • Slots - Support for default and named slots has been added to the API. Features like fallback content and slot props are also available. See for full documentation and live examples.

  • New built-in LivePatch and LiveRedirect components

  • Update LiveView to v0.11.1

  • Improved documentation with new sections and live examples for all main features. See for more.

  • A minimal boilerplate app is now available for those who want to take Surface for a spin without even installing npm/node, i.e., no webpack, no babel, etc. Details can be found at the Getting Started page.

  • A new version of the VS Code extension has been released adding syntax highlighting for slots.

The support for slots was the last planned feature that was supposed to have a big impact on how you write components. From now on, you shouldn’t expect any major change in the API until we reach the first stable version.

What’s next?

  1. Performance tuning

  2. Improve error handling

  3. Extend the built-in set of components (e.g. wrappers around Form helpers and friends)

  4. Create a full-featured suite of UI components using Bulma or Tailwind.

I’ll probably spend the next couple of weeks working on #1 and #2, so if you’re willing to contribute and wanna give #3 or #4 a try, please let me know. I’ll be glad to give any assistance you might need!

I’ve spent quite some time working on the docs and examples to make sure you have enough resources to get started. I hope you enjoy it!




This isn’t related to your library, but I wanted to check out the demos on the site you linked.

If you load (you linked to this in your reply), and in the sidebar you click any other links, such as “Events”, and then click “Slots” again, it will always dim out the entire side bar’s icons after you do that more than once.

Then if you keep alternating clicks between 2 items that are “Slots” + anything else, it consistently dims and un-dims the side bar icons.

I’m curious, is this a bug with navigating pages with LV, or something else?


Just wanted to thank you for creating Surface - I have used it extensively the last couple of weeks and it has been so much fun :slightly_smiling_face:

The latest updates and docs look awesome. Keep up the good work :+1:


Hi @cnck1387!

I’m curious, is this a bug with navigating pages with LV, or something else?

Definitely something else! :slight_smile:

It’s not directly related to LV. I believe it’s fixed now. I’ll review all CSS stuff to make sure I get rid of any other CSS style leaking.

Thanks a lot for reporting this! :heart:


No problem, I’m noticing it’s fixed here too. I even tried in a fresh browser to make sure it wasn’t cached.

1 Like

Really digging this library, I have used Vue a lot in the past so it’s really nice to have a familiar mental model.

One thing I’m not clear on is, can you use template files (like LiveVIew .leex files) or do you have to define your Surface markup in render/1? Can’t see this in the docs but perhaps I’m having a case of the Mondays :grin:

Hi @darraghenright!

Support for colocated template files (.sface) is planned and should be available before the first official release.


That is beautiful news!

This is terrific work @msaraiva !

any chance of a version bump to phoenix 1.5.1 and live_view 0.13 ?

My mix complains about surface (version 0.1.0-alpha.1) requires ~> 0.11.1

Wanting to get “on the surface boat” :slight_smile: