top | item 29594763

Building a simple room-based chat application in Nim (using HTMX)

154 points| todsacerdoti | 4 years ago |arhamjain.com | reply

28 comments

order
[+] wpietri|4 years ago|reply
For those that want to know more about Nim, it is "a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula." : https://nim-lang.org/

And HTMX "allows you to access AJAX, CSS Transitions, WebSockets and Server Sent Events directly in HTML, using attributes, so you can build modern user interfaces with the simplicity and power of hypertext": https://htmx.org/

[+] treeform|4 years ago|reply
I love Nim. I been using it professionally for more than 3 years now. At first I started with it just as a faster python with types, but it so much more! You can run Nim everywhere regular places such as backend, frontend, mobile, but also in crazier places like GPU shaders and imbedded.

I also like the community. It's not so big that it feels like you only see people once but not so small that there are no useful libraries written. Just the right size for me. You can always get people to help you out on stuff, reminds me of old IRC days.

[+] iffycan|4 years ago|reply
> but not so small that there are no useful libraries written...

Says the person responsible for a ton of really useful, well-done Nim libraries, such as this amazing Cairo/Skia-like library: https://github.com/treeform/pixie#readme

Thank you for all the things you've made for Nim!

[+] speg|4 years ago|reply
Reminds me of Crystal, which I’m also using with HTMX. I’m afraid if I check out nim I’ll have to start all over :)
[+] 0-_-0|4 years ago|reply
Wait, did you say GPU shaders? How?
[+] probotect0r|4 years ago|reply
How do you use it professionally?
[+] fouric|4 years ago|reply
> In Nim, converters are automatically ran to convert between types if needed.

Huh, this is an interesting take. Instead of taking either of the extremes of "coerce types aggressively" (Perl, PHP, C (kinda)) or "no type coercion ever" (CL (kinda), Rust?), Nim has programmable type coercion, so you can enable it just when you need it.

[+] oneplane|4 years ago|reply
At this point I'm more worried about the whole supply chain of libraries and dependencies in the background than how nice the abstractions are.

It used to be that a powerful demo of a framework or language would be a pretty sweet starting point, but I'm not so sure about that anymore.

[+] ajusa|4 years ago|reply
As far as Nim's dependencies go in this case, it's literally just Karax (no dependencies), Jester (depends on httpbeast which has no dependencies) and treeform's ws library (no dependencies). So the only thing in this chain that isn't transparently being used is httpbeast. Thankfully I've read through that code and contributed a bit to that project, so I can reasonably trust it.

Nim has a smaller community, so the supply chain tends not to be more than one or two levels deep in my experience. This is also because the standard library is fairly large.

[+] recursivedoubts|4 years ago|reply
i can't speak for nim, but htmx is a dependency-free, 10k javascript library that doesn't require a build step
[+] nyanpasu64|4 years ago|reply
There's some odd syntax in this post, which passes colon-delimited indented code blocks to function calls, than control flow primitives. It reminds me of Ruby/Kotlin blocks or Swift's blocks (criticized in https://blog.metaobject.com/2020/06/the-curious-case-of-swif...), but it's quite unusual from my Python/C++/Rust background and I think it's worth explaining in the blog post, since I don't know if it's passing a key-value map/struct or a lambda.
[+] ajusa|4 years ago|reply
+1 to what planetis mentioned. I didn't include a full explanation of the macro because I was more or less showing off a project - not doing a full tutorial of all of the internal bits and implementation details of what libraries I was using.

So in this case, the `template` bits are doing plain code substitution at compile time, and the buildHtml `macro` is doing more advanced code generation, also at compile time. This means that it should avoid the overhead you mentioned with a key-value struct/lambda.

For what it's worth, this could also have been implemented as a `proc` which would then take in a lambda/anonymous function to generate the HTML, but that incurs additional overhead and requires a bit of extra syntax, which felt like a hassle.

[+] gunapologist99|4 years ago|reply
Very, very cool demo! If someone decides to use this for production, don't forget about sanitizing inputs to mitigate XSS, CSRF, etc (and, of course, message storage, authentication, and all those other things.)
[+] ajusa|4 years ago|reply
(Author here) Thanks! The inputs aren't sanitized in this example, but the output (the generated HTML) actually is in this case. Specifically this part:

  text ": " & sentMessage.getStr()
The `text` function in the Karax DSL is actually escaped once it is converted to a string, see https://github.com/karaxnim/karax/blob/c71bc927494418c3f52f9... for the implementation if you are curious. There is a way to render raw HTML using `verbatim` instead of `text` in Karax.

So in this case, I believe it would be protected against XSS to some extent, but I obviously haven't done an in depth security check for a demo/simple project. There are plenty of other potential issues as well (username collisions, websocket errors, user lists) but I judged those to be out of the scope of a simple project like this.

[+] kitd|4 years ago|reply
This is a really good sales pitch for both Nim and Htmx IMHO. I've used htmx a bit but never Nim. Even so, the code is easy to read and follow.