paulstatezny
Hello everyone, I’ve just released a new library called SurfaceFormatter.
A special thanks to @msaraiva for his help and collaboration!
What is it?
SurfaceFormatter is a code formatter (like mix format) for Surface code.
If you’re not familiar with Surface, you can find it on Hex, GitHub, or the original ElixirForum post.
Why did I create it?
So that Surface developers can focus on building things without sacrificing valuable time and attention to make the code nicely formatted.
How does it work?
Add it to a Surface project, and run mix surface.format. That’s it!
Where can I find it?
https://github.com/surface-ui/surface_formatter
A short example
Surface code that looks like this:
<RootComponent with_many_attributes={{ true }} causing_this_line_to_wrap={{ true}} because_it_is_too_long={{ "yes" }}>
<!-- An HTML comment -->
{{#An Elixir comment}}
<div :if={{@show_div}}
class="container">
<p> Text inside paragraph </p>
<span>Text touching parent tags</span>
</div>
<Child items={{[%{name: "Option 1", key: 1}, %{name: "Option 2", key: 2}, %{name: "Option 3", key: 3}, %{name: "Option 4", key: 4}]}}>
Contents
</Child>
</RootComponent>
will be formatted like this:
<RootComponent
with_many_attributes
causing_this_line_to_wrap
because_it_is_too_long="yes, this line is long enough to wrap"
>
{{ # An Elixir comment }}
<div :if={{ @show_div }} class="container">
<p>
Text inside paragraph
</p>
<span>Text touching parent tags</span>
</div>
<Child items={{[
%{name: "Option 1", key: 1},
%{name: "Option 2", key: 2},
%{name: "Option 3", key: 3},
%{name: "Option 4", key: 4}
]}}>
Contents
</Child>
</RootComponent>
Trending in Announcing
WebAuthnLiveComponent WebAuthnComponents
See this post about renaming the package.
Passwordless authentication for Phoenix LiveView app...
New
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
In 2021 I started a new library called Tempo with the objective of modelling time as a set of intervals - not as instants. In 2022 I gave...
New
Hello,
I’m sharing my plugin here in forum after some time so it has time to mature and proof yourself.
I use Claude Code daily on a pr...
New
Aloha gang,
There’s a new class of AI model out from TypeSafe. Jev is their flagship model. You can learn about it here:
...
New
Other Trending Topics
Hey there,
I haven’t seen a list of useful Elixir specific skills for the popular AI tools yet so I’m starting one here with my first.
...
New
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
With AI doing more of the implementation work, I’ve been wondering how much coding I should deliberately keep doing myself.
My main conc...
New
(I just needed to vent somewhere and LinkedIn is full of hope, or hype, I’m not sure which exactly)
AI dream has many faces, but general...
New
Fly’s CEO posted this recently - Turn And Face The Strange · The Fly Blog
It says that Fly is going all-in on sprites, which is a worry ...
New
Code BEAM Europe 2026 – Call for Talks is Open!
We’re excited to announce that Code BEAM Europe 2026 is now open for talk submissions :t...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #ai
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #blog-post
- #ecto-query
- #elixirconf-us
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #elixirconf-eu
- #api
- #forms
- #security
- #hex










Showing Posts 1 to 5- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
Eiji
Does this comment disappear? Looks like just a tiny
in your example …
harmon25
This is amazing, been needing exactly this!
Thank you!
paulstatezny
@Eiji Great observation
Yes, the parsing library from
Surfaceitself (whichSurfaceFormatteruses under the hood) does not expose those comments, so we lose them. However, you can replace them with interpolated Elixir comments instead.I think it would be great to be able to keep HTML comments. If there is enough interest, perhaps the Surface parser can be modified to expose them.
In the meantime, I have added a more thorough explanation in that section of the docs to hopefully make the “why” more clear: https://hexdocs.pm/surface_formatter/Surface.Code.html#format_string!/2-html-comments
paulstatezny
SurfaceFormatter v0.2.1 has been released.
Previous versions didn’t allow inline elements to stay on the same line among text nodes, for example:
The previous rules were that each node (HTML element, text, or interpolation) would always be moved to a separate line. Therefore, this represents a pretty generous “relaxing” of the formatter. If anyone finds that it has become “too relaxed” in any scenarios, please post here and let me know!
paulstatezny
SurfaceFormatter v0.7.0 was released. It comes packaged with a Formatter Plugin (available in Elixir 1.13) so that you can now run
to format both Elixir and Surface code in one command.
Special thanks to José Valim for adding Formatter Plugins to
mix format! And to Marlus Saraiva for his part in it as well!The next steps for SurfaceFormatter are:
To merge it into Surface so that formatting works with even less setup out of the box.
To attempt porting it into a HEEx formatter. As I understand it, formatting HEEx comes with some unique/extra technical challenges compared with Surface. We’ll see what happens.