I actually always tought of web frontend to be the easiest to start with. But that only applies to starting a very simple project from scratch without external dependencies. Afterwards the complexity grows very, very steeply.
Starting new fully featured web project takes me whole day. And if I want to use recent version of the stack, everytime I have to forget everything I knew and start again, because everything changed totally since I did it last time.
I'd say it's lack of barriers to entry, boot camp ninjas that maintain dozens of packages.
The fact that some newbie would upload is-odd[1] to npm doesn't surprise me. The fact that it has half a million weekly downloads - it's blind leading the blind.
And framework complexity - I find that consistent with mid level programmers being fascinated by complex solutions and top scale teams needing to deal with the pile of shit they are building on (DOM/JS)
Been a front end dev on and off for nearly 15 years. The DX is as good as it’s ever been now. JS/TS have become nice languages and deployments on platforms like Vercel are an absolute breeze and Tailwind means I don’t have to decipher anyone’s CSS class naming convention.
Whenever I see people say things like “we are back where we started with file based routing” I see it more that we’ve remembered what was good about the old days and cherry-picked that good stuff.
Tailwind is great, but I consider it an outlier. They went and made a stand-alone compiler so you don't have to use NPM build processes. It works very well.
It's less that people take issue with JS/TS itself and more the frameworks that use it and the associated dependencies and tooling. The complaints in the article are very representative of my experience.
you know what really bothers me? i want to build airplanes, but the people who make the parts have made it so, so complicated. all i want to do is fly around - but because some moron wants job security, they've made it needlessly complex. wings, body, engines: that's all it takes.
I'm not a pilot, but from my understanding, small Cesna type planes haven't changed much over the last few decades. Contrast with the rapid churn of front end development.
> The number of broken packages that don’t adapt to newer versions of other packages or that don’t work anymore by doing nothing is absolutely unbelievable.
No it's not. It costs nothing to not write defensively, especially in an untyped language. This can easily be an article about Python as well.
I'd say its less about writing defensively (protecting yourself against libraries who don't deliver what they promised) and more about users making stronger assumptions than what the library promised (eg assuming json string literals contain no escaped characters so that a simple ". *?" to match the value is fine, that some value is always defined or generally that a behavior observed two out of two times must be the rule).
While the author isn't wrong, is it just me or does this article come off as the author just whining that they used a bunch of libraries that they didn't research well enough first and they went out of support?
This is the price you pay for the convenience of not having to write all the stuff. Yeah updates suck and it sucks people don't maintain their libraries better or write them better to begin with but people have lives and may be doing this stuff on their own isn't sustainable beyond a point.
The solution could be "less people make libraries" or it could be "more people make libraries and more people help maintain them" or it could be that people who make apps stop using libraries and write the code themselves.
You can't force people to maintain every piece of code they put online just in case someone uses them in one of their apps then a year later wants to update their app. What if the end user wanted a different specific version?
This stuff annoys me as much as anybody but whining and posting it to hackernews is just self-flagellation.
It's a problem you can't really evade if you're on the modern JS stack train. A lot of that has to do with frameworks running into the same issue. Some part of the build stack retires an old version unannounced, and now you have an entire cascade of rushed out updates.
this is the price of development convenience. if you don't like modern web dev then... don't do it? plain html and css still work just fine. jquery works just fine.
Right, but, you don't always works alone, or you need to maintain choices of other dev. Really, in js echo system there are always a huge cascading update when you update one component.
Pretty much. Just stop adding shit to your package list and you won't have this problem. If some major framework like React has this happen to one of their dependencies, it's at least not your problem as they will fix it for you.
And stable APIs, and large integrated product suites that solved the whole problem, and that vendor was incentivized to stick around and maintain the product even if it wasn't cool anymore.
Unfortunately the way dev compensation works (i.e. mostly salaried with big jumps possible from job hopping), we're all very incentivized to go with free stuff today even if it actually turns into a major source of tech debt tomorrow. After all, if you're paid by the hour does it really matter if you spend days or weeks fighting with abandoned dependencies? It matters to the company but to the individual it can even be a benefit, because you get experience with things that look good on the CV. That in turn damages the market for developer tools, creating a self-fulfilling prophecy where not many people try to compete against free, so people conclude it's just the natural state of things and can't be any better.
I see this problem with my own product: our customers mostly come to us in a sort of shell-shocked state where they've lost a lot of time and hair trying to make the available open source tooling work for them, and decide to buy ours as a sort of last resort. Then they get it all working, we help them fix any issues, they have a good experience in the end and are happy. Unfortunately people have to go through that bad experience first because everyone's initial instinct is always to go with the free stuff, and indeed they probably won't even find out about the alternatives because there's a culture in which open source projects only want to advertise or integrate with other open source projects.
So the author asks, how did we get here? That's how.
Are you upset that free (as in beer) software isn't being actively maintained over a long time frame? Or is it annoyance that Semver doesn't deliver on its promise?
slowmovintarget is right. The default expectation was that things didn't break. Version numbers increased on release.
Semantic versioning said to stop basing version numbers on what version of the software you're talking about, and instead use them to indicate that you just broke everything. This only makes sense if it becomes OK to break things. That was an assumption that semantic versioning brought us.
That was very much not the default expectation; expecting that things wouldn't break would mean you could update with no oversight, and I don't know a time when that was ever expected.
Things broke all the time, the default expectation was that _something_ would need work, it was just a matter of how much. Semantic Versioning just gives us a framework to (try) to know in advance how much work it would be.
I assume the parent's point is that without an agreement similar to SemVer, you never have permission to break things, but of course people break things anyway because APIs must evolve. Something like SemVer allows you to clearly separate things that are and are not "broken", thus in a sense giving you permission to break things.
One of the problems here is recursive cross dependencies--libfoo switches to a major upgrade of libacme 2.x, while libbar remains with 1.x. Even in a language or environment where 1.x and 2.x could in theory coexist, the potential for bugs is often significantly increased.
Ideally, before someone decides to inflict their open source code upon the world, they should at least nominally commit to 100% backwards API compatibility. That sets the correct frame of mind, both as a maintainer but also wrt designing and implementing your API. For example, these days all new syscalls on Linux are expected to have a flags argument and strictly reject undefined combinations of flags and arguments. There are exceptions, but that's the baseline expectation; even when excepted, those expectations help steer the conversation to expose potential compatibility traps. And they do this because Linux nominally promises 100% backward compatibility, regardless of versioning; though it took them many years to appreciate the need for those particular technical guard rails.
If and when you need to break your promise of 100% backward compatibility (as even Linux occasionally does), then use Semantic Versioning to help smooth the way and set expectations. (I'm agnostic, but certainly semantic versioning was normative long before "Semantic Versioning" existed.) But if your answer to API compatibility starts with Semantic Versioning, then I wouldn't want to have anything to do with your library. It's like asking a bank what their approach to risk management will be and they answer, "following regulatory guidelines". It's not actually a substantive answer to the question, and suggests that one should avoid that bank.
You'd be insane to rely on this. A major number bump is only a heads up about something that has broken, but every single change has the possibility of breakages.
I'm not sure why you would ever watch a tutorial for web development. Just read the project docs/wiki. They will contain a guide which is perfectly up to date.
I'm trying to help update a Drupal site from 7 to 9. There are 95 installed plugins that need to be replaced due to not being updated for new versions of Drupal. That's just what happens when you rely on community maintenance over years and major version changes.
Are you using TypeScript, Babel, etc. or do you have to create code to check if the browser supports fat arrows, template literals, const, etc.? What's the size of your team and how many older browsers and old phone browsers do you have to support? If you have to support many browsers, want to use modern language features and you don't want to write code to check that the browser supports modern syntaxes then you do need a build system.
We got here by making it so easy to use 3rd party libraries and also making it easy to create and publish them regardless of quality. I do not think it is a bad thing. But if it's easy and fast people will do it more often and we end up with projects with ton of dependencies that are ever evolving.
I also think "not invented here syndrome" is not (always) bad. A piece of your own codebase instead of a 3rd party library can have less maintenance cost even if it's a often reused piece of functionality. I always deliberate on adding just another library even if it's just one npm install away.
Because nobody got around to fixing it yet. Infrastructure can be built to keep these packages' dependencies up-to-date by default. If they break on dependency update, the maintainer should be alerted, and the package should no longer be recommended until it is fixed. Relying on individual maintainers to do everything correctly themselves has never worked.
Note that it's been edited from the original submission, at my request, which was simply "How the fuck did we get here". I'd suggested the subtitle alone ("A small rant..."), which is at least fucking descriptive.
According to Algolia, at this writing, the words "how did we get here" appear in HN submissions (net of flags and edits) 363 times. That's exceeded by the even more tiresome "this changes everything" (571 results). Both should be hellbanned IMO. I'm having an email exchange with dang over this presently.
Context has something to do with it, though the title's a poor one regardless IMO.
On your own blog, to readers familiar with your topics and post history, "how the fuck did we get here" might be an acceptable / excusable title, though even there, I'd argue that it's a rather poor pick. It's a bit like dropping a URL or video link with the comment "lol" on an HN or Metaverse thread, say. There's not much to go on.
Even pretty good bloggers often have ... depressingly unilluminating titles. Brad DeLong, for example, leans very heavily on "Why Oh Why Can't We Have a Better Press Corps" (you'll find a few examples perusing <https://braddelong.substack.com/archive?sort=new>). Several people on the Fediverse post frequent themed items, with a repetitive title leading the description, e.g., "Plucked from the archives <description>". My suggestion is to invert that order, have the description first, and probably hashtag the topic as, say, #FromTheArchives.
(I do something similar with "#OccasionalEtymology" and "#DredsDictionary", see:
There's a reason why article authoring and headline writing are often distinct roles at traditional serial publications. What it takes to write copy and to sell it (via the headline) really are separate skills.
I like vanilla JS with web components. Coming from a desktop app development background it’s so incredibly simple. I don’t really want fancy “reactive” data flow when plain old MVC or MVVM works perfectly fine without any magic.
> How did we unlearn how to build stable software/dependencies that can actually integrate with each other?
Ah yes, the old days of C and C++!
Where if you were lucky enough to get the sources to a library (hah!) you spent a lot of time adapting it to your platform and build system and then you never ever touched it ever again.
Granted things used to be easier when the only code relied upon was the OS Platform UI library, which had the benefit of being well tested, and any flaws in it well documented, since new releases only came out when a new version of the OS shipped to actual physical stores.
Now granted, the JS ecosystem and the dramatic changes in modules and exports and stuff has been particularly bad. I was trying to import a library from NPM that was ~5 years old and I gave up and just... copied the code into my source tree and imported it that way.
Now, to address the question of how we've reached a point where software dependencies often seem unstable or difficult to manage, I believe there are several factors contributing to this situation:
Rapid pace of technology and innovation: The web and software development landscape has evolved rapidly over the years, with new tools, frameworks, and libraries being introduced constantly. This rapid pace of innovation sometimes leads to a lack of focus on long-term stability, as developers may prioritize adding new features or keeping up with trends over ensuring backward compatibility.
Increased complexity: The web has become increasingly complex, with new technologies and standards being introduced regularly. This has led to a more complex ecosystem of dependencies and interdependencies between packages, making it harder for developers to maintain and update them.
Fragmentation of the ecosystem: The JavaScript ecosystem, in particular, is highly fragmented, with many different libraries and frameworks available for similar tasks. This fragmentation can make it difficult for developers to select the most stable or well-maintained option, and it can also contribute to the "cascading effect" you mentioned when updating one package leads to the need to update many others.
Shorter project lifecycles: In the fast-paced world of software development, projects often have shorter lifecycles than in the past. This can lead to less emphasis on long-term stability and more focus on delivering features quickly, even if that means introducing breaking changes more frequently.
Open source community dynamics: Open source projects are often maintained by volunteers who may not have the time or resources to ensure long-term stability. Maintainers may also change over time, leading to different priorities or approaches to stability within the project.
I used to write GUIs with Delphi and occasionally VB in the 90s. It was so much simpler than what we have now. I was hoping by now we'd have a tool as powerful but despite all the expansion of the industry still nothing. I was hoping WASM would result in something similar. Anyone have a good platform for writing basic crud apps?
Delphi's pretty good for making cross platform apps. Run on Windows, Mac, Android, iOS, (and a bit of linux) nice 3rd party components for pretty well everything. You can now use Skia as the graphics engine so looks just like the web browser.
It can live again! Next week I'll be giving a talk at KotlinConf in Amsterdam on how to write CRUD DB apps using Jetpack Compose ... for Desktop. Come along or watch when the talks are uploaded. I'll be demoing:
• A simple Compose CRUD app that connects directly to Postgres using its native protocol. Users log in to the DB as themselves.
No web servers, no HTML, JS, CSS, REST, JSON or even HTTP. Just Kotlin and a bit of SQL to setup the schemas and object security. jOOQ auto-generates language bindings and type safe SQL API by reflecting the database.
• A drop-dead simple workflow for deploying the app and updating users.
Just like a web app the entire release process (bundling, packaging for each OS, uploading, icon generation, even making a download page) is done with one command. Users update to the latest version every time the app launches, like a web app would update. I'll be demoing how quickly this can be set up and done with Conveyor (my own product, natch), and you can do it all from your laptop.
• Visual layout design.
Just like React, Jetpack Compose doesn't have a visual UI designer. But there's a cunning trick. Using the JavaFX Scene Builder and GPT-4 you can convert FXML to Jetpack Compose Kotlin code, giving you a nice designer that helps you quickly rough out a layout visually and then use it even from a totally different toolkit. I used it to help develop the demo - mind blowing stuff!
Obviously nothing about any of that is Kotlin specific, you could do the same with any language that runs well on the desktop. At some point I hope to make a similar demo with Python using GraalPython (why jvm - because it has mature portable UI toolkits, very mature SQL libraries+db drivers, is easy to deploy to every OS from your laptop and has the best language interop).
I wouldn't try to make the next Instagram this way but for the apps that fit the advantages are numerous. The code for this demo is simple because leaning in to your RDBMS gives you so much functionality for free that you'd end up duplicating in an ad-hoc and often bug-prone manner on the web. Almost all the code is UI logic.
Historically distribution was the sticking point and something Delphi/VB never really solved once you got beyond "stick an exe in an SMB shared folder". Conveyor solves that which is why I'm doing the demo, to advertise how resolving a developer usability bottleneck in one area allows you to increase usability in other areas too.
We got here because JS devs for some reason feel a compulsion to release an entire package for something that should be a 5-line snippet.
And then other devs feel the need to use the package rather than copy a code snippet.
The fact that "is-odd" exists is just silliness. It's a joke. The fact that it has nearly half a million WEEKLY downloads should absolutely horrify you. Any developer that uses the "is-odd" package is wholly unqualified to be coding and needs to get a refund from boot camp that "trained" them.
We got here because JS got really good at abstractions, but people have no interest in long term maintenance.
Using is-odd is fine, the same as developers using the "+" is fine in languages that support it. Where JS is weird is in not having a full standard library along with very arbitrary data, leading to folks seeing that they use the is-odd functionality regularly enough to where it's useful to have a dedicated operator
I'd use an is-odd library if I need to figure out if something is odd across 20 different data types depending on how somebody inputted data in a UI
tbf this has happened to me several times with Linux kernel updates. see also: updating glibc and then updating anything else that depends on the older version of glibc that is no longer there.
"Duplication is less expensive than bad abstraction" I think describes just a metric ton of waste I see not just in modern languages but in tons of other applications. Some of this is that abstraction is a very hard thing to falsify, or test. How do you know you have a bad abstraction? There's a few bespoke quantifiable tests, but it remains largely an artisanal question, so far as I can see from my humble trench.
75 comments
[ 2.9 ms ] story [ 116 ms ] threadI actually always tought of web frontend to be the easiest to start with. But that only applies to starting a very simple project from scratch without external dependencies. Afterwards the complexity grows very, very steeply.
Starting new fully featured web project takes me whole day. And if I want to use recent version of the stack, everytime I have to forget everything I knew and start again, because everything changed totally since I did it last time.
The fact that some newbie would upload is-odd[1] to npm doesn't surprise me. The fact that it has half a million weekly downloads - it's blind leading the blind.
And framework complexity - I find that consistent with mid level programmers being fascinated by complex solutions and top scale teams needing to deal with the pile of shit they are building on (DOM/JS)
[1] https://www.npmjs.com/package/is-odd
https://www.npmjs.com/package/is-is-odd
Whenever I see people say things like “we are back where we started with file based routing” I see it more that we’ve remembered what was good about the old days and cherry-picked that good stuff.
It's less that people take issue with JS/TS itself and more the frameworks that use it and the associated dependencies and tooling. The complaints in the article are very representative of my experience.
No it's not. It costs nothing to not write defensively, especially in an untyped language. This can easily be an article about Python as well.
This is the price you pay for the convenience of not having to write all the stuff. Yeah updates suck and it sucks people don't maintain their libraries better or write them better to begin with but people have lives and may be doing this stuff on their own isn't sustainable beyond a point.
The solution could be "less people make libraries" or it could be "more people make libraries and more people help maintain them" or it could be that people who make apps stop using libraries and write the code themselves.
You can't force people to maintain every piece of code they put online just in case someone uses them in one of their apps then a year later wants to update their app. What if the end user wanted a different specific version?
This stuff annoys me as much as anybody but whining and posting it to hackernews is just self-flagellation.
>Oh no, this free stuff I got wasn't good enough
There's other ecosystems like Java+Springboot where you can go 2-3 years only doing minor/patch upgrades without too many changes.
React is on version 18, released in 2011. Springboot is on version 2, released in 2014.
Its the difference of not paying for the stuff.
In the past you would pay a vendor and they would give you libraries and provide bug fixes and vulnerability patches.
Unfortunately the way dev compensation works (i.e. mostly salaried with big jumps possible from job hopping), we're all very incentivized to go with free stuff today even if it actually turns into a major source of tech debt tomorrow. After all, if you're paid by the hour does it really matter if you spend days or weeks fighting with abandoned dependencies? It matters to the company but to the individual it can even be a benefit, because you get experience with things that look good on the CV. That in turn damages the market for developer tools, creating a self-fulfilling prophecy where not many people try to compete against free, so people conclude it's just the natural state of things and can't be any better.
I see this problem with my own product: our customers mostly come to us in a sort of shell-shocked state where they've lost a lot of time and hair trying to make the available open source tooling work for them, and decide to buy ours as a sort of last resort. Then they get it all working, we help them fix any issues, they have a good experience in the end and are happy. Unfortunately people have to go through that bad experience first because everyone's initial instinct is always to go with the free stuff, and indeed they probably won't even find out about the alternatives because there's a culture in which open source projects only want to advertise or integrate with other open source projects.
So the author asks, how did we get here? That's how.
Semantic Versioning is permission to break things. As Rich Hickey would say, just use a new name [1].
[1] Rich Hickey - Spec-ulation: https://www.youtube.com/watch?v=oyLBGkS5ICk
Semantic versioning said to stop basing version numbers on what version of the software you're talking about, and instead use them to indicate that you just broke everything. This only makes sense if it becomes OK to break things. That was an assumption that semantic versioning brought us.
What it actually delivers:
- 1.2.changed -> don't care
- 1.changed.0 -> don't care (at least I'm not supposed to have to care)
- changed.0.0 -> you're screwed (maybe, on you to check)
SemVer is an agreed upon way to ship breakage.
Things broke all the time, the default expectation was that _something_ would need work, it was just a matter of how much. Semantic Versioning just gives us a framework to (try) to know in advance how much work it would be.
Ideally, before someone decides to inflict their open source code upon the world, they should at least nominally commit to 100% backwards API compatibility. That sets the correct frame of mind, both as a maintainer but also wrt designing and implementing your API. For example, these days all new syscalls on Linux are expected to have a flags argument and strictly reject undefined combinations of flags and arguments. There are exceptions, but that's the baseline expectation; even when excepted, those expectations help steer the conversation to expose potential compatibility traps. And they do this because Linux nominally promises 100% backward compatibility, regardless of versioning; though it took them many years to appreciate the need for those particular technical guard rails.
If and when you need to break your promise of 100% backward compatibility (as even Linux occasionally does), then use Semantic Versioning to help smooth the way and set expectations. (I'm agnostic, but certainly semantic versioning was normative long before "Semantic Versioning" existed.) But if your answer to API compatibility starts with Semantic Versioning, then I wouldn't want to have anything to do with your library. It's like asking a bank what their approach to risk management will be and they answer, "following regulatory guidelines". It's not actually a substantive answer to the question, and suggests that one should avoid that bank.
By not paying people to maintain critical infrastructure?
Maintainablity? Sustainability? Fergetaboutit.
Vanilla JS have been perfectly tenable for a while now. No, you don't need to use React.
Archive Today: <https://archive.is/QZ3AO> (I'd submitted that, which suggests that the problem is in my own Web configs...)
Wayback / IA: <https://web.archive.org/web/20230407211857/https://fagnerbra...>
Google Cache: <https://webcache.googleusercontent.com/search?q=cache:https:...>
I also think "not invented here syndrome" is not (always) bad. A piece of your own codebase instead of a 3rd party library can have less maintenance cost even if it's a often reused piece of functionality. I always deliberate on adding just another library even if it's just one npm install away.
According to Algolia, at this writing, the words "how did we get here" appear in HN submissions (net of flags and edits) 363 times. That's exceeded by the even more tiresome "this changes everything" (571 results). Both should be hellbanned IMO. I'm having an email exchange with dang over this presently.
<https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...>
<https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...>
Your encouragement, however, changes everything!
;-)
On your own blog, to readers familiar with your topics and post history, "how the fuck did we get here" might be an acceptable / excusable title, though even there, I'd argue that it's a rather poor pick. It's a bit like dropping a URL or video link with the comment "lol" on an HN or Metaverse thread, say. There's not much to go on.
Even pretty good bloggers often have ... depressingly unilluminating titles. Brad DeLong, for example, leans very heavily on "Why Oh Why Can't We Have a Better Press Corps" (you'll find a few examples perusing <https://braddelong.substack.com/archive?sort=new>). Several people on the Fediverse post frequent themed items, with a repetitive title leading the description, e.g., "Plucked from the archives <description>". My suggestion is to invert that order, have the description first, and probably hashtag the topic as, say, #FromTheArchives.
(I do something similar with "#OccasionalEtymology" and "#DredsDictionary", see:
- <https://toot.cat/@dredmorbius/tagged/OccasionalEtymology>
- <https://toot.cat/@dredmorbius/tagged/DredsDictionary>
There's a reason why article authoring and headline writing are often distinct roles at traditional serial publications. What it takes to write copy and to sell it (via the headline) really are separate skills.
Nielsen's microcontent guidelines: "Microcontent: A Few Small Words Have a Mega Impact on Business" <https://www.nngroup.com/articles/microcontent-how-to-write-h...> (2017) (Based on a 1998 original.)
https://bundlephobia.com/package/htmx.org
roll safe, kids
Ah yes, the old days of C and C++!
Where if you were lucky enough to get the sources to a library (hah!) you spent a lot of time adapting it to your platform and build system and then you never ever touched it ever again.
Granted things used to be easier when the only code relied upon was the OS Platform UI library, which had the benefit of being well tested, and any flaws in it well documented, since new releases only came out when a new version of the OS shipped to actual physical stores.
Now granted, the JS ecosystem and the dramatic changes in modules and exports and stuff has been particularly bad. I was trying to import a library from NPM that was ~5 years old and I gave up and just... copied the code into my source tree and imported it that way.
More things change and all that.
Now, to address the question of how we've reached a point where software dependencies often seem unstable or difficult to manage, I believe there are several factors contributing to this situation:
Rapid pace of technology and innovation: The web and software development landscape has evolved rapidly over the years, with new tools, frameworks, and libraries being introduced constantly. This rapid pace of innovation sometimes leads to a lack of focus on long-term stability, as developers may prioritize adding new features or keeping up with trends over ensuring backward compatibility.
Increased complexity: The web has become increasingly complex, with new technologies and standards being introduced regularly. This has led to a more complex ecosystem of dependencies and interdependencies between packages, making it harder for developers to maintain and update them.
Fragmentation of the ecosystem: The JavaScript ecosystem, in particular, is highly fragmented, with many different libraries and frameworks available for similar tasks. This fragmentation can make it difficult for developers to select the most stable or well-maintained option, and it can also contribute to the "cascading effect" you mentioned when updating one package leads to the need to update many others.
Shorter project lifecycles: In the fast-paced world of software development, projects often have shorter lifecycles than in the past. This can lead to less emphasis on long-term stability and more focus on delivering features quickly, even if that means introducing breaking changes more frequently.
Open source community dynamics: Open source projects are often maintained by volunteers who may not have the time or resources to ensure long-term stability. Maintainers may also change over time, leading to different priorities or approaches to stability within the project.
Rails is very fast to get started with but I find it unmaintainable for anything that lasts longer than a few years due to being untyped.
AdonisJS seems like a much better option to go with today as it picks up a lot of the conveniences of Rails while being TypeScript.
• A simple Compose CRUD app that connects directly to Postgres using its native protocol. Users log in to the DB as themselves.
No web servers, no HTML, JS, CSS, REST, JSON or even HTTP. Just Kotlin and a bit of SQL to setup the schemas and object security. jOOQ auto-generates language bindings and type safe SQL API by reflecting the database.
• A drop-dead simple workflow for deploying the app and updating users.
Just like a web app the entire release process (bundling, packaging for each OS, uploading, icon generation, even making a download page) is done with one command. Users update to the latest version every time the app launches, like a web app would update. I'll be demoing how quickly this can be set up and done with Conveyor (my own product, natch), and you can do it all from your laptop.
• Visual layout design.
Just like React, Jetpack Compose doesn't have a visual UI designer. But there's a cunning trick. Using the JavaFX Scene Builder and GPT-4 you can convert FXML to Jetpack Compose Kotlin code, giving you a nice designer that helps you quickly rough out a layout visually and then use it even from a totally different toolkit. I used it to help develop the demo - mind blowing stuff!
Obviously nothing about any of that is Kotlin specific, you could do the same with any language that runs well on the desktop. At some point I hope to make a similar demo with Python using GraalPython (why jvm - because it has mature portable UI toolkits, very mature SQL libraries+db drivers, is easy to deploy to every OS from your laptop and has the best language interop).
I wouldn't try to make the next Instagram this way but for the apps that fit the advantages are numerous. The code for this demo is simple because leaning in to your RDBMS gives you so much functionality for free that you'd end up duplicating in an ad-hoc and often bug-prone manner on the web. Almost all the code is UI logic.
Historically distribution was the sticking point and something Delphi/VB never really solved once you got beyond "stick an exe in an SMB shared folder". Conveyor solves that which is why I'm doing the demo, to advertise how resolving a developer usability bottleneck in one area allows you to increase usability in other areas too.
And then other devs feel the need to use the package rather than copy a code snippet.
The fact that "is-odd" exists is just silliness. It's a joke. The fact that it has nearly half a million WEEKLY downloads should absolutely horrify you. Any developer that uses the "is-odd" package is wholly unqualified to be coding and needs to get a refund from boot camp that "trained" them.
Separation of code and packaging/distribution
Using is-odd is fine, the same as developers using the "+" is fine in languages that support it. Where JS is weird is in not having a full standard library along with very arbitrary data, leading to folks seeing that they use the is-odd functionality regularly enough to where it's useful to have a dedicated operator
I'd use an is-odd library if I need to figure out if something is odd across 20 different data types depending on how somebody inputted data in a UI
dependency management is hard