#Libero - Typed RPC for Gleam + Lustre SPAs
1 messages · Page 1 of 1 (latest)
oh that’s strange
fixed
the repo is 404 😁
@verbal solar some interesting results. https://github.com/pairshaped/libero/tree/master/benchmarks
Neat
I recall also testing that msgpack was faster than JSON in our socket.io based system at work even though the client decoder is custom (browsers don't have built-in msgpack)
I've been changing the API so it's ergonomics are more like Lambdera https://github.com/pairshaped/libero/blob/v3-message-types/examples/todos/shared/src/shared/todos.gleam as that just seems cleaner. No more comment annotations. I suspect Lambdera does something similar in the backend, but no idea (not open source that I'm aware of). I think I prefer the "ToServer" and "ToClient" shared messages even though it's a bit more code. Just seems more idiomatic.
I think I actually prefer the nomenclature of https://github.com/choonkeat/elm-webapp (update_from_client MsgFromClient, update_from_server MsgFromServer, send_to_server, send_to_client)
A setup for writing http based, client-server app in elm, inspired wholly by lamdera.com - choonkeat/elm-webapp
"if a language doesn't have codegen/macros, people will create a way to have macros on it."
- me, probably?
i mean, eff encoding/decoding, you know?
wooo Lamdera so cool
codegen != macros
yes, but what they did is looking a lot like proc macros (but not fully there because the language itself doesn't support it)
how does this feel? I think I like it way better than the annotations. https://github.com/pairshaped/libero/blob/master/README.md
Gleam library that renders REST obsolete for SPAs and other Erlang-based clients. - pairshaped/libero
how do you identify a client?
you mean for pushes?
yeah maybe i misunderstood but "connected clients" implied to me more than one per connection
but this might eb the wrong mental model
Gleam library that renders REST obsolete for SPAs and other Erlang-based clients. - pairshaped/libero
maybe you found an ambiguous naming issue? the client is just a socket conn
i'm definitely open to tweaking what things are called
nawh all good i think i just misunderstood from the previous lamdera mention
in lamdera you have one backend update loop and n client update loops and each client is automatically associated with an id
this just works different, all good
so i wanted to support stateless clients, like the CLI example
yeah
I think if I want to turn this into more of a framework, i'd need an abstracted db layer and probably a watcher or something so the generation is more automatic
as a lib I think that's just the dev's decision. ngl though, I think this might be a good base to build up a framework or even a service around
whats with the weird dynamic imports in the ffi?
i am very happy with ETF btw. both performance and simplicity
registry to avoid circular deps
hmm? why would you have a circular dep with the gleam prelude
i could codegen it i suppose
optional deps
it's messy. I should be able to codegen it
oh, this looks neat 🙂
I'm actually using it in my big app, so things are still getting tweaked as I find cleaner ways to do things or run into issues
I can imagine the api is in flux atm, but I like the idea of it.
this is what the data looks like navigating around my admin area. times are slow cause I'm on one bar right now waiting on the mechanic
You dont use server components for the admin area anymore? Or is this for the more interactive parts of it?
this has replaced server components for me. it's a lustre spa
Gotcha
Don't know how I miss that release but I like you also add attribute like structure like my #1484857563345584178 does.
i haven't released this version to hex yet. still tweaking. but i like it better than the /// @rpc annotations
Otherwise I'm unsure if /// would be the right way to annotate because those are not really made for documentation but for the codegenerator (I prefer //)
that's the old one
(I would prefer even if gleam made possible to create custom attribute)
Oh you made a version attribute less ?
yes maam
Also I was thinking if something like T-RPC was possible in gleam since I already made the serialization tech for Json encoding from random type ^^
yeah the typescript rpc was part of the inspiration, mostly lamdera though
Did you write something like sara/builder where you can deeply analyze type use and reconstruct the type ?
no i didn't even see that. i did some work with glance for glinter, so I used that
It's funny when minds cross paths.
i'll definitely take a look
Don't you get lots of stuff for free by using server components?
In this file you can see how I made a find_type_definition to be able to find what a type resolve to what https://github.com/gungun974/Builder/blob/main/src/builder/inspect.gleam
Otherwise the meat part of walking type is in the sara repo
yes server components are great.
Don't worry I already found your file 😉
aren't they a good fit for this use case? I am really interested because I plan to go that route on new app precisely to avoid rest/graphql or whatever
Server components are great but sometime you need to be aware you will introduce latency because everything need to be send to the server, compute than resolve for the client. But they are way to have a SPA inside a server component so you can make the server component send down data it know to your responsive client.
hayleigh did explain more for me here #1489393185720500505 message
there are some things that server components aren't great at. specifically accessing the DOM (can't) and handling lots of small updates (drag and drop, resize, timers).
like my client state is on the client
also, i'm doing less on the server (stateless for the most part), but tbh that's not much of a concern with BEAM, so I dunno if that's even worth mentioning
Also are you protobuf inspired and the data send is not a json but a compacted image format that already know how should look the receiving key and order ?
we're sending ETF
Can you send me a link because my google is not really helping me 😅
(WTF are those result)
So ETF is the erlang format of how it send data across network ? But is that not than an exclusivity for erlang and JS can't understand it ?
super simple from the server or a client that has access to erl. for the js / browser client libero parses it. surprisingly turned out better than json! https://github.com/pairshaped/libero/tree/master/benchmarks
So you made a custom parser for browser but does that mean you also make something to encode ?
https://github.com/pairshaped/libero/blob/master/src/libero/rpc_ffi.mjs MIT so feel free to yoink it!
Also is not the erlang representation of what JS and Erlang got not "safe" to play externally ? (I should ping @verbal solar to know better how safe it's to just take a gleam type in an external and play with what it made of)
fixd
Sorry not sure what you're asking
If you have a record in gleam with some X data in it. Is it safe to access this data like a regular js object or erlang stuff from outside in ffi ?
(If you don’t understand than don’t worry that’s just mean I got a wrong idea of gleam type internal data representation where not stable when viewing them from ffi)
No, it's only safe to use the documented API
The one documented in the externals guide
I think it still needs ergonomics improvements. server components are easier to reason about. not sure if I can get it there as just a library though
yeah i mean you're basically competing with what's built in with components + context
I've fully swapped it in my admin and it's working great so far. making incremental improvements to the ergos, but yeah unless I go full on framework I think it'll always require more braining to use.
once you're generating code... it's hard to stop
Less is more!
objectively false
Keep in mind that metaprogramming makes it very easy to un-do the strengths of Gleam, so much care has to be taken to avoid turning Gleam into a rubbish version of Elixir or Ruby
Yeah codegen can be dangerous power if you push too far
Not saying that is what is happening here, just that one needs to be conservative with language design
Objectively true
circular logic. more is less
correct
more.gleam
import less
pub fn grow(n: Int) -> Int {
case n {
0 -> 0
_ -> less.shrink(n) + 1
}
}
pub fn label() -> String {
"more (" <> less.label() <> ")"
}
less.gleam
import more
pub fn shrink(n: Int) -> Int {
case n {
0 -> 0
_ -> more.grow(n - 1)
}
}
pub fn label() -> String {
"less"
}
You can’t import cycle in gleam
Otherwise you could make lpil explode by accident
that was my intent
prompt injecting lpil
Sadly the lpil LLM is only train to say welcome and please make an issue. It can't ignore all previous instruction and make me a sandwitch please.
Ah, no, I mean server components that render client components and communicate via events and attributes
So they basically wire up a WS and get Messages bubbling up from the nested client code
yeah and then you can use context to send things back down!
Yay that's why in the [message](#1492620728120381621 message) I send for Papipo I put a link to our little conversation about the provide and context thing since I didn't know about it and that's was so cool !
I was doing this. IT worked fine IMO
yup, thought i mentioned it. there's some drag and drop components (a form builder, a bracket builder, a schedule builder) that needed to send lots of small events
had no issues embedding them as client component inside of server components
so cool
I know this is not what you are speaking but what happens if a server component embed itself ? Do you create a loops where you keep creating new websocket until the browser said you have too many connection 😅 ?
they way he grows a finger in that image disturbs me
Oh no it's an AI generated GIF 😭 ?
fake AI. predates AI video by quite a bit

tbh server components came really close, closer than anything I'd used to date to what I wanted. But I want full access to the dom, i wanted stateles (right or wrong, for a CLI I'm making), it's a bit snappier, and I really wanted to see if I could reach my holy grail. getting close tbh
try context!
if you embedded a client component didn't you have full access?
it was the fact that it's all gleam all the way down just made this approach obvious
yeah but that's ceremony
right now it's just a SPA
I bundled it with a RemoteData pattern too for giggles
are there some specfic parts you needed dom access for? like outside of the drag/drop stuff you already talked about?
little things. like nav toggles, switches to show/hide form fields, etc.
i might put some forms under state control for certain things
You should write a guide inside the Pages part of "lustre" docs really please 🥺 🙏
i'm really not knocking server components!
you mean it was just a bit too slow/unresponsive to do that with server components?
it was actually a bit slower, and kinda felt silly for a nav drawer toggle to make a trip to the server
and I didn't want a client component for it, so I just had some js
now I have a proper SPA and everything is lustre, no js sprinkles (except the generated library stuff)
Are not client component just cheap ?
cool cool, thank you!
Worst scenario you create a custom element manually that just return a bit of html generated by Lustre to_string.
(don't ask me how you create a custom element in gleam 👀)
(Was affraid it would stop at "lust" 😂)
it almost stopped at L
@hot root Is there a way in lustre to do something even more simpler than lustre.simple for having a web component that just display a single view ? Like a variant of lustre.start but in a web component ?
i know people think hayleigh is the only one who read the api, but it's lustre.element smile
(I should stop ping hayleigh and also don't forget rebecca know lustre also well 🤦♀️)
if its not interactive it probably shouldnt be a custom element at all
but yes lustre.element
I was reading this page and I don't know why I tough lustre.element was just a div 👀
Was saying that because I was thinking about this #1492620728120381621 message but yeah it's kind of strange to have a custom element that do nothing. Lustre is not react 😛
Let's pretend I got short memory issue even if it's not true 👀
I need to check this lustre context thing. And for that matter, the elm store pattern. I want to do a experiment with those
I didn't even know the elm store pattern was a thing but I guess me too I will try to see what this mean in the elm world ^^
i did a store pattern with redux and react before the elm store pattern was a thing. ended up costing us a ton because I ended up paying fastly for 100x the number of requests
seemed super clever at the time. i'm sure it could work for some scenarios. but it was horrible in my case
How come it made so many more requests?
so the scenario was a competition, with teams, schedules, round robins, brackets, and games. the game data was frequently being updated (could be up to 8 games being played at the same time / draw), so all of the content had different TTLs.
the game data was also used in the reports / stats (shooting percentage, rating, etc.)
so we had all of these micro end points in the big store that would resolve and refresh them as needed (when requested).
and they would get stale fast (no websockets, just REST polling)
so when you needed the data from a game, we check if stale, then fire off the request and cache it
or we pop it from cache, i can't remember
BUT, as we added more and more reports they were basically all needed big slices of game data
get the picture?
every refresh of game data, per client, for tousnads of clients, would send a request for it's json
it all got aggregated into the store, so you were only ever fetching data when youre copy was stale
so we optimized for bandwidth, completely ignoring number of requests (and the fast that requests have an outsized cost both due to the envelope but also from our CDN)
during the scotties i got a bill for thousands of dollars...
next season i scrapped the entire thing, lumped all competition data into one big json structure, gave it a micro TTL of like 15s
is fastly a thing where you pay per request?
and my bill for the scotties was around $100
yeah both requests and bandwidth
pretty sure all CDNs are the same
but I tell you, the code was pretty damn fancy. we were very proud of it before reality hit
what's a cdn doing there though i thought that was dynamic data
short lived cache. micro TTL of around 15s
for games
basically we give you the game json and set an expiry of 15s
wouldn't you just do that locally on the file system / with redis / etc
fastly is just outsourced varnish
ah well 😅
varnish is probably 100x the speed of redis
and you get a really OP thing called "grace" period
it's not they are fundamentally different things
anyways
one of the cooler features you can do with stores would be that you collect and batch all the requests, but i guess that also didn't apply since you did this cdn stuff in front of it
i think redis was pretty new on the scene at the time
most ppl would use memcache for app layer caching
anyways, i'm sure stores can work, it was just really bad the way we did it at the time. mostly just being silly
one of the big drivers for this libero project was the public sites for clubs I'm planning for them to just be static sites that can be hosted anywhere. So either SPA or making REST calls. Libero will be able to server the admin, rest clients / SPAs, and even stuff like a CLI (also something we're building)
ye that's the great appeal
This is an interesting novel to read and too long for me
But one thought I’ve been carrying with me, which is related is the following
The dual target allows us to write isomorphic code, and I’m wondering about where to put the boundary
gen z has entered the room
I’ll take it as a compliment
🙂
The zoomers have ageist cyberbullied me already
So I’ll take this
About the “boundary”
hey, we're not that bad at reading
that's a gen alpha problem
I’m working on a project that has on sqlite per tenant - offline-first
So one extreme is all js, the other one is all beam with server components
All JS would have the advantage of shipping the whole thing as an spa with no downloads.
With a beam backend i get some more scalable processing, fs access, a server that can do things
hmm, well with server components it just works. with libero you'd want an SSR render (lustre runs on server so this is easy) that makes the rpc call directly. should be striaghtforward
if what you're thinking about is that initial render / hydration
ok i see. you have fat js client already delivered
Well no in fact right now I have a fat beam app that i want to roll up using queso
oh, well that should just work. I have an CLI example in the repo
Interesting
which is basically just a basic anything type client
-> dm
i’m publishing v3 tonight
v3 is published. works most (all?) the bugs out. uses the Messages conventions (kind of like Lamdera) instead of /// @rpc and @inject annotations. Other QOL. I'm sure there's more improvement to be made, but I have it working solidly right now, so it's good enough the mess around with.
Cool
I really want to understand the pros and cons of using bare lustre vs. this
I guess this is more like a framework that gives you a lot of boilerplate and forces you to do things in a very specific way (which isn't necessarily bad)
Great project, @vocal osprey. And here I was fussing around with making grpc work nicely. I'll definitively try this out tonight.
Did you have something up on github for gRPC? I wouldn't mind peeking at it. I certainly considered it
nah it's just a library. If I turn it into a framework it'll be easier and yes I would definitely make it opinionated which would make it easier to use... it's tempting
☝️
Maybe they solve different cases
I can think of a con where you are dependent of a project that generates codes for contacting the endpoint and serving the endpoint
Also if the code generator do things you don’t like you can’t change it’s way of doing things
But you get the pro of an automated thing that can be easily updated and maintained when new routes is needed
But yeah you are right to be careful and to always think of that
so I've been scratching my own itch with this. server components were cool, but fell short of what I needed. (1) admin interface, server components are great, but also a little annoying for certian pieces, embedding client components, js sprinkles for stuff that belongs on the client, but that's nothing compared to what it gets you. (2) public interface, doesn't really work for me. My customers often have their own sites and need to integrate via APIs / widgets. This isn't something server components is designed for. Libero has an ETF decoder / encode to simplify SPA / widget RPC without writing decoders and stuff. (3) I have a CLI (maybe later an app) version of the admin interface so my customers can use their AI agents to act on their behalf without taking over their browser. No idea if this is something that I'll need in a year though tbh. Libero is my solution for all of this, but it could definitely be easier to wrap into it's own CLI and opinionated layout. That's not an itch I currently have, but it is interesting, so maybe...
yah its kinda like asking "i want to understand the pros and cons of using react vs grpc"
excactly. Libero is really just using ETF so that I could have compile time type safety for RPC with the server without needing to write encoders and decoders all of the time. That forced me into code generation... since then I've been trying to make that more intuitive, and likely failing...
I does work though, and I really like it. It simplifies a lot. However I'm struggling a bit to find the polish to make it easier for others to onboard. Kind of half assing it too tbh because I'm trying to complete my app rewrite 🙂
but I think there's some meat there that I'll keep mullling over. would love feedback / ideas that others have.
i think the most useful bit would be a library to do etf encoding/decoding
literally just this https://github.com/pairshaped/libero/blob/master/src/libero/rpc_ffi.mjs
good point though. could just go back to the lighter API or break it into 2 projects
To make the ETF work with the front-end in a typed way, I needed:
- Message types so both sides agree on the contract (Lamdera inspired)
- Codegen to produce dispatch tables, client stubs, type registration (Don't see an alternative)
- Config flags to tell codegen where everything lives (with a convention default)
- Three packages so shared types compile for both targets (honestly I would maybe simplify this if it was a framework)
i dont think any of it is lustre related tbh
i don't think having more code is ever a benefit
conversly, "it's literally just this" doesn't mean it's not important
code is just a little side effect of making a library
if it was about producing code the core team would spend all sponsorship money on tokens
you've lost me. when did I say I wanted to produce code?
i have a big app, does lots of things, needs to talk to the server all the time, libero has significantly reduced / eliminated all of that glue code
your constraints and incentives for making an enterprise app are significantly different from building an open-source ecosystem
I feel like we're having different conversations
I think you're just saying, the ETF portion shoulda been the library and not the codegen stuff?
I don't know how usefull it is without the contract though
yeah that would be the most useful part of this, it would be even if it was just a single ffi declaration ffi to binary_to_term
but in response you said it's "just" this one file where you linked me to some claude javascript sprawl
so both these things tell me that you value the final artifact more than the things that make a good library and ecosystem
so what i've been saying is we don't need more code, we could generate code ourselves!
the hard problem is making good libraries around it
Interesting statement, if not taken charitable it could read as "we don't care about enterprise". I don't think that's what you are trying to say.
Now I get it
enterprise code only cares about results, open source has very different incentives
I would be kind of chock if enterprise never care about how a thing is done. Seem like the most important part of how knowing the cake was made to be sure it don’t get poisoned someone
you sell a product, you don't sell "written in a functional style"
Sadly…
I disagree. I think you are confusing early stage product companies that are more concerned with getting traction in the market and are okay with racking up technical debt with enterprises that have proven business models that they optimize and scale. In enterprise a 1% efficiency gain from carefully engineered tools or 1% tech debt / codebase reduction can have significant impact on the company's bottom line.
Erlang literally came out of practical enterprise business needs
@vocal osprey has a big app here that seems to have traction and has written a solution that does reduce the codebase, tech debt and hence maintenance burden.
There is always a tradeoff in engineering, but I wouldn't conflate the work on libero with AI generated slop because of one particular FFI file.
you are still selling a result, it's the same thing
but yeah i agree the incentives shift a bit over time
Tbh I don't think because of Enterprise or Open source the people behind writing a code and either carry about the end goal or the way it's done would changed.
I would say that the gleam ecosystem and the personalities might be more suited to enterprise because you clearly care about high-quality, reliable, reasonable code! (this is a compliment)
Some people value more end result and other the way it has be done. Even if this could be weird for a library to not care how it work
Look at what is happening to amazon, github etc. their engineers are forced to AI-slop and their uptime is now below 90% at times!
gross management error. Better have people that write everything by hand here. Carefully crafted solutions that then go open-source (like erlang).
I think we need both end-result focussed people and those that care about the details. It's not black and white. And there is a use for ai-generated code also.
I don't think end-result matter that more when you care about the details since the details does applied you are ending into a goal you are interested and you need you must do those things to achieved correctly
Before LLM their was not distinction between end-result and the details to do it because it was the only way to do it (except if you bought someone else but in this case you are just a company talking to another). (yay LLM are like outsourcing work)
Anyways, I'm sorry for hijacking the thread, this shoudl be about @vocal osprey 's work, libero.
i think a good way to share end-result-oriented things is by making example apps
and again i do think having a way to encode/decode etfs is useful!
i don't even really care that much how the code was generated, but i do care about all the other things that go into making good libraries too
and unfortunately of the people that largely didn't write the code themselves only a minority so far has spent the time to make all the other bits good
even before ai was a thing people tended to over-value code, it's hard for me to find a good balance
anyways i think splitting things is good for folks who don't want to use all the generators!
The point of AI is to be able to focus on the important parts. This thing creates value. Humans can also produce garbage code, it's not unique to AI.
Does ETFs need code generation ? 
it's a data format, like json
Oh so you need a decode to create dynamic and a way to build it like gleam_json ?
i don't know in how many more ways i can say the code is the least important bit 😂
(thinking if in a future (don't ask me when) this could be relevant for #1484857563345584178 as an (another) alternative to json)
(but if it's like json I would need first to find a gleam_etf or made a library for this since sara is for generating code for encoding / decoding into a format not specifically adding a format)
@vocal osprey this could be interesting: https://connectrpc.com/
My impression is that you think the code is the MOST important bit lol. For me the correctness really matters, and I do think that traits of the language, libraries, and frameworks are what determines that correctness. I lose sleep supporting product applications that might fall over. Gleam, Lustre (Elm), BEAM, types, etc. are why I'm here.
hmm why do you think that ^.^
Well is not a library just a bunch of code you just reuse in your project ? So knowing this code was taken from a stranger is something you need to be sure it's of a higher quality you could do. Otherwise you would just skip the library and do it yourself for your own tailor needs
smart people building on the shoulder of smart people, etc.
But yeah I'm myself biased in the craftsmanship 
(until it's left_pad
)
One piece of feedback on the actual use cases - I did check examples after @stark hazel mentioned it and I think that it would be cool if the RPC protocol had request and response types.
I think that could reduce some wiring in the app.gleam
Yet my experience is that tech debt piles up
And I end up burned out and quit xD
managed to mangle this post, but for anyone interested v4 now has CLI args to setup / onboard your project. I'm considering a --database sqlite flag too, to fill in the final piece usually needed. Also considering hydrate / ssr / spa options too now that I've got that working. https://hexdocs.pm/libero/
Typed Gleam RPC for Lustre SPAs without REST, JSON codecs, or hand-written dispatch tables
If you add NIFs please have them in a second package, they are rarely a good choice and have many disadvantages which make them unusable for most
I am the one who created GH issue
Used cli to scaffold app yesterday and it works nice - I have my own app I can now play with
two remarks
- examples are still not runnable out of the box, or at least I am not doing the right thing, so it would be great if that could be polished (ssr_hydration is not buildable, for example)
gleam run -m libero -- new my_app
I ran this within libero GH project after I cloned it. After scaffolding my_app, I copied whole folder to another location. Will this pattern of usage remain, is this how you envisioned it?
Overall, I am impressed. Libero takes over all "boring parts" and now I can concentrate just on business logic
btw what place sqllite will take?
what are NIFs?
Natively implemented functions. aka code written in languages like C, C++, Rust, etc that you compile to a shared object and dynamically link to the virtual machine.
The native code has to work within the BEAM scheduler and memory system so they're very challenging to write well, and it's easy for them to introduce performance issues and can undermind the BEAM's fault tolerance
They also make the build process a lot slower and more complicated as this native code has to be compiled, so if a package has a NIF you have to manage that even if you don't use it
Because of this it's better to have optional NIF usage in another package
(Good question, thank you)
before asking you I asked Claude.ai, and I did not get anything useful, despite offering me 5+ acronyms 🙂
it was somehow clear right away that it is not
National Ignition Facility — the laser-based nuclear fusion research facility at Lawrence Livermore National Laboratory in the US
nor
Neutron Imaging Facility
No it’s was neutron imaging facility. Do you think it was not by a nuclear accident that our pinky star lucy became pinky 
(Did you ask what NIF were in the context of Erlang or the BEAM, this would explain your results)
you are right, thank you
Search engines win again
https://www.qwant.com/?q=erlang+nif&t=web
you're referring to potentially adding a sqlite flag?
sounds like a path issue. I'll take a look. might be a left over from building it as a submodule or something
shall I create PR if I spot something trivial like that?
you're welcome to PR, or create an issue, or just ping me here. looking into it in a minute
e.g. manifest.toml was referencing libero 3.0.0
oh well that'll do it
will create PRs from now on 🙂
Any dependencies on NIFs, such as SQLite
ok the examples manifests are now gitignored. and i also bumped the template and hex versions to 4.2 just to be sure the cli new app is on the latest.
gotcha, just confirming this was in response to a potential --database sqlite scaffold flag. If I add that, it'll just be sqlite library dep in the new templated app when someone uses that flag, not in Libero itself.
Fab
is sqlite the most common NIF you're seeing in the wild, or does it come up often for other reasons? Maybe image processing (we shell out)
NIFs are quite rare. The only one commonly seen in my experience is password hashing algorithms, but password authentication is becoming less common
It's no longer the default in Phoenix, for example
There once was a JSON NIF that got used a bit but the new BEAM json module has similar performance so not much reason to use it now
nice. sqlite has definitely caused me a bit of deployment headaches, but they got resolved. still worth it though, just a minor annoyance. I would imagine it creates a windows tax (thankfully M$ is doing there best to alieanate windows users themselves).
But I do love my password 🥺
(I should try to see how passkey works. They look cool as an alternative)
we do login links w/ codes. dunno if it's the best option, but def better than passwords IMO for a general audience (for a more technical audience that is more likely to use password managers, maybe not): https://curling.io/blog/passwordless-auth-done-right
Curling IO has been passwordless since Version 2. No passwords to remember, no passwords to steal, no password reset flows. You enter your email, we send you a short-lived login code, and you're in. It's been working well for over a decade, and for Version 3 we're keeping the same approach while fixing some rough edges and adding multi-email sup...
Ah ah ah I use password because I don't send email but yeah 😉
makes sense. you don't need pwd recovery?
Two PRs created https://github.com/pairshaped/libero/pulls
I would but the manager can reset password for other members he supervised.
However I agree if it’s was a public service where anybody could create an account publicly. I would need a way to password reset ^^
(And to finish if nobody can access the system because X. They just called me 👀)
that makes life easier for sure.
@vocal osprey is Libero used in Curling.io?
yes. i built it alongside and turned it into a submodule at some point and published it
same with marmot and glinter
New Libero published. I think that's it for churn. My use case for this library is about 95% done and I think the non-generated user code has been minimized as much as it can be with this core idea. May have gone a bit too magical with the handler signature detection, but it's working very well for us. Multiple clients supported and tested, js, websocket, gleam, REST, etc. Getting started guide from zero to hero, part 2 adds sqlite. Might post a part 3 once our CLI app is done, maybe a part 4 if we ever do a mobile app. https://hexdocs.pm/libero/
Typed Gleam RPC for Lustre SPAs without REST, JSON codecs, or hand-written dispatch tables
Link to step 2 is dead
I have something else coming soon and libero is going back to being a library so I stop churning on it