[HN Gopher] Show HN: libmodulor - An opinionated TS library to b...
___________________________________________________________________
Show HN: libmodulor - An opinionated TS library to build multi-
platform apps
Initially I started building this for my own projects. The main
goal was to define a unified "blueprint" allowing me to develop
multi-platform apps using the same code, without code generation. I
wanted to be able to develop the same functionality on web,
desktop, cli, server, mobile, whatever... I've been able to
achieve this by relying on TypeScript, a 4-layer architecture
(UseCase => App => Product => Target) and dependency injection.
This mechanism allows me to use whatever tech stack I want,
provided the good adapters are developed. For instance, I have pre-
built ones : node express (server), next.js (server), node hono
(server in alpha), node parseArgs (CLI), node stricli (CLI), react-
web-pure (web with no CSS), react-native (mobile), node mcp server
(anthropic MCP in alpha), etc. The same goes with data storage :
Postgres, SQLite, a txt file, whatever. It also comes with auto
testing and auto documentation. Did I reinvent the wheel ?
Probably on some aspects. Is it too much abstraction ? Probably as
well. But I like the idea of modularity and portability. That's
why it's not made for everyone, nor all types of projects. If you
like testing new stuff, give it a try and feel free to ping me if
needed, I'd love to help. I'm aware the documentation is not state
of the art yet. I wanted to focus on the "Getting Started" Guide to
give a quick overview instead of going to deeply into the details.
Best,
Author : pmdfgy
Score : 41 points
Date : 2025-01-23 15:30 UTC (7 hours ago)
(HTM) web link (github.com)
(TXT) w3m dump (github.com)
| tomhallett wrote:
| I enjoy your 4 types on the architecture.
|
| But I'm still a bit confused on what the project actually "is". I
| see you have an architecture and I'm using ts to define the
| interface between those 4 types of components. But let's say I
| have a react-native target: what am I expressing in that
| interface? A cli which can build/deploy that interface? Each ui
| screen in that rn app (rn login, rn add contact)? Or all of the
| api endpoints in the web target which gets called by the rn
| target?
|
| In the readme, I would focus a bit less on the UML part, and a
| bit more on the "if I have a webapp and a mobile app, with auth
| and crud for contacts, here's what you'd need"
| pmdfgy wrote:
| Thank you for your feedback, I really appreciate.
|
| Let's say you want to create a product with auth and crud for
| contacts. You'll have a SignInUCD, a CreateContactUCD, a
| AddPhoneNumberToContactUCD, etc.
|
| As you said, your react-native target will define the UI
| screens. You are free to design them the way you want as the
| library does not make any assumptions about the UI/UX. In every
| screen where you want to "inject" a use case, you'll use the
| `useUC` hook and `<UCPanel uc={uc} />` (see https://github.com/
| c100k/libmodulor/tree/master/dist/esm/tar...). See also https:/
| /github.com/c100k/libmodulor/blob/master/docs/getting.... It
| explains for web, but the mechanics are the same.
|
| Since react-native expects `<View>`, `<Text>` and not `<div>`,
| etc. you'll also need to define your "design system", like it's
| been done here for example : https://github.com/c100k/libmodulo
| r/tree/master/dist/esm/tar.... Basically, you need to define
| how you want a use case form to be displayed, etc. When in web
| we rely on `<input>`, in react-native we'll rely on
| `<TextInput>`. And of course, according to the data type, you
| can display a specific form control.
|
| I realize it's super hard to explain and I'm not clear enough
| but hopefully I'll find the best way to express it.
| joshmarinacci wrote:
| Ah. Thank you. Having examples up front really helps me
| understand it better.
| tomhallett wrote:
| Let's say I'm using shadcn's Dialog [1] on my web target,
| which has many subcomponents (Dialog, DialogTrigger,
| DialogHeader, etc). How many of those am i representing with
| a 1-to-1 `UC`? Is it just the parts that are on the IO seam,
| like a UC for opening the dialog, UC for closing a dialog,
| and UC for submitting a dialog? Or is it also for things the
| user sees like UC for header, UC for content, UC for buttons
| panel?
|
| There is obviously some cost to expressing the interface
| between the product/target/usecase. What exact benefit is
| that cost getting me? do i know that if i expose a certain
| use case in one target then i have to explicitly decide if
| i'm going to expose (or not expose) it in a different target,
| which helps me get consistency/governance between my app as
| it grows? does it help me "integration test" by application
| in isolation, in a "similar" way that pact [2] helps with
| integration testing microservices? (ex: the mobile app relies
| on X input, but from the ts interfaces, the tool can detect
| that the web-api is no longer defining an output for that
| api. if so, is this on the /api/v1/resource level? the
| openapi schema for a json body response level?). do i get a
| mono-build-system, where everything flows together and i just
| say "libmodulor build" and "libmodulor deploy" and I'm good
| to go?
|
| said in another way: many of the people on HN have a backend
| api, a react SPA, and a mobile app. what types of problems do
| i have now which libmodulor solves?
|
| [1] https://ui.shadcn.com/docs/components/dialog [2]
| https://pact.io/
| bjacobso wrote:
| You should check out https://effect.website/
|
| It might help you implement some of these ideas
| yasserf wrote:
| Looks great!
|
| I build something similar (vramework.dev), actually on my way now
| to give a talk on it
|
| Got a presentation for it at presentation.vramework.dev if anyone
| is interested
| sramam wrote:
| vramework looks really well thought out. Is it in use by anyone
| yet?
| yasserf wrote:
| Heya!
|
| It's used in three companies so far, but the new productised
| (via the cli) version is still in development / qa stages
|
| There is one company that has been using it for over four
| years tho! Just checked in and seems to be working solid
| yasserf wrote:
| The difference between the two versions is that we now have
| a cli, whereas before you needed to call scripts to do the
| same things
| pmdfgy wrote:
| Looks great, will have a look at it.
| yasserf wrote:
| Thank you!
| gervwyk wrote:
| interesting, when you say websocket support on aws, does this
| mean ws using lambda? and ws on nextjs (would be a game changer
| if someone made this happen)
| yasserf wrote:
| Yes it's ws using lambda, the worker-starter example shows
| how it works
|
| Also abstracts away the idea of an eventbus which is pretty
| critical in any Websocket deployment.
|
| It doesn't use Websocket directly via Vercel, but would work
| if you use nextjs by providing it a http server and also
| providing that server to ws
|
| Can get this to work, but I'm pretty curious why you think
| this is a game changer? Thanks!
| yasserf wrote:
| Also curious how you would want Websocket servers to talk
| to each other (to broadcast messages). Would you be okay
| having a pub sub layer like redis that nestjs servers run
| on?
|
| Also is running on vercel a requirement?
| gervwyk wrote:
| Nice. I'm going to look into this more. We currently run a
| dedicated server next to our vercel apps just for ws
| support. Adds considerable overhead.
|
| Maybe game changer is an exaggeration but In the vercel
| community, ws has been a top requested feature for years.
| See comments on
| https://x.com/rauchg/status/1872729115595587627
| gr4vityWall wrote:
| Congrats on your project.
|
| I feel like you could describe the abstractions you built in more
| detail. When I read the explanation for what the 'UseCase',
| 'App', 'Product' and 'Target' were, it wasn't clear how each of
| those translates to TypeScript. My guess is that 'UseCase' and
| 'App' would be like Classes, if you're modeling your program in
| an OOP way? The 'Product' seems like it would be the TypeScript
| project itself, with the package.json, source code and all of
| that.
|
| I would rethink how you named the 'App' layer. The examples given
| ('auth', 'accounting', etc.) are not necessarily what I would
| call an 'app'.
|
| As you introduce names and concepts for things in your library, I
| recommend trying to keep the cognitive load as low as possible.
| It seems like there are a very high amount of high-level concepts
| and implementation details like types, functions, etc. that 1.
| are specific/unique to libmodulor and 2. you need to learn before
| you can start actually building your application, from looking at
| the examples. The barrier to give it a try in a side project
| seems really high.
|
| Building things is cool regardless :) I'm happy that you built
| something it's useful to you and that you got to share here.
| 0x20cowboy wrote:
| I find most often people who are opinionated have very little
| knowledge on the subject. They are opinionated in an effort to
| try to keep discussions in a realm they feel they have some sort
| of expertise, but by definition their limited view makes them
| look silly to those with deeper understanding.
|
| I apologise for being off topic, but I really want "an
| opinionated X" to stop having some kind of positive connotation
| to junior devs.
| popalchemist wrote:
| Limited is not intrinsically bad. Even if someone makes
| questionable decisions, the act of limiting the scope by
| defining specific interfaces/patterns has value in and of
| itself.
| 0x20cowboy wrote:
| I agree, but limited isn't the same as opinionated. In these
| types of usage, people seem to think they are opinionated
| because they are right.
|
| I think it's misunderstanding the angst of knowledgeable
| people's frustration with the world, by trying to emulate the
| frustration without having the actual knowledge or
| experience.
| mystified5016 wrote:
| I always read "opinionated program" as "I'm immature, don't
| understand my own opinions, and would rather force my opinions
| on you than examine my beliefs in any capacity"
|
| Extremely immature and "I'm an asshole and I'm making it _your_
| problem " behavior
| johnny22 wrote:
| I'm a big fan of opinionated software. This world is full of
| software that tries to do everything. A lot of the times I just
| want it to do the one thing really well.
___________________________________________________________________
(page generated 2025-01-23 23:01 UTC)