Previous startup I was at had a stack like this:
- Frontend: Vue + Typescript
- Android/iOS App: Vue (NativeScript/Capacitor) + Typescript
- Backend: Node + Typescript
- Database: Postgres
- Deployment: Everything in Docker containers
I know of a lot of places taking similar stances where the frontend and mobile apps are done in this way (IE React and React Native) and then you get Javascript/Typescript on the backend as well, so the entire stack is just JS/TS the whole way through with a single UI/design language.
It was really easy to hire developers this way and the transferable skills were high.
However you look at it, this is sort of the deal with JS these days. From a productivity and development velocity perspective, it's really difficult to rationalize using other technologies when you can just holistically build your entire stack in one JS/TS UI framework for the clients (or Flutter, nowadays) and then JS/TS on the backend too.
This is why I'm mentally shoehorned into using Typescript for everything. I enjoy it a lot, but there are other languages I enjoy too, it just doesn't make as much sense to throw them in the mix because then you've increased technical complexity and made it that much more difficult to source talent.
However, at some point you will have a look into your myriad of nodejs dependencies and see with horror that they rely on C++ extensions. Then you learn that your precious stack is just a GCC upgrade away from not building anymore. And noone in your company even remembers what that is, a C++ compiler flag.
I do not trust a random npm package with C++. C++ is way too level and insecure and it's not worth it.
All of my node projects have had rather tidy dependency trees. It’s also been quite easy for me to use popular packages. If something breaks and hundreds of thousands of devs are impacted by it, it’s going to get fixed pretty quick. Which has been my experience in the rare occasions that in of my dependencies has broken, it’s been fixed before it even had a chance to impact me.
It's almost certainly not, as R has plenty of batteries, and young nitwits in the Hadleyverse are writing preposterous node-like dependency graphs. It's fashion, and it should be curb-stomped.
I do completely agree otherwise, but those people will learn through bitter, bitter experience that those dependencies will break over time and will see the light that is base R.
It's as far a way from a general-purpose language as it can get while technically still being one, in both scope and intended use/audience.
This is a big selling point of the most boring languages of all, Java and C#. Performance is close enough to C, and FFI is painful enough, that its rare to see any native code in a project. Other languages that are slower or have better FFI have a much bigger risk of bitrot if you're going to keep a backend around for decades.
Where I work we deploy the exact same pre-built artifact to our Mac dev machines, Linux servers, and Windows QA guys. With Go, Python, JS, Ruby, etc we would have to have it built specifically for the platform. They all use enough native libraries that you can't share a zip file. And its a huge pain to cross-compile for anything except Linux.
My reasons are:
- I don't need to share type definitions between the frontend and backend; the frontend can generate TS type defs using GraphQL introspection regardless of which language the backend is implemented in.
- The backend is doing a lot of data manipulation, which TS is not very good at. For example, there's no built-in group-by function, and group keys must be primitives since TS doesn't have value equality for objects or arrays.
- Static typing doesn't help much with setting up GraphQL resolvers correctly, and overall feels much less useful than on the frontend where it's absolutely stellar to type check all GraphQL queries, React calls, 3rd party component props, and so on.
- I miss clojure.spec for validating calls to external services.
Plus a few more situational reasons:
- I work in a team that's already familiar with Clojure. I don't think it's a huge barrier to hiring either; I didn't know Clojure before I joined, they just recommended me a book.
- I personally don't find that using the same language everywhere helps much in reducing context switching costs. Using different languages actually feels more engaging, especially when one is as pleasant as Clojure.
Put all these together and I'm seeing real benefits in using different languages.
I think the more powerful benefits are definitely hiring and having a team that can work on both sides (and in that regard I think your points are perfectly reasonable), but there are definitely some more direct benefits in our case.
[0]https://support.stripe.com/questions/passing-the-stripe-fee-...
So the frontend can actually do SSR to render PDFs or emails. However, it would definitely be much harder to to ensure that any phone formatting or fee calculation done directly in the user's browser matches what the API returns. So yeah, definite benefits in sharing a language there. Thanks for the examples!
Certainly not a showstopper though, passing a URI is easy enough!
You can use something like https://github.com/vriad/zod to get both runtime validation and static types (via inference) at the same time. The downside is defining your types in a DSL instead of plain TS, but I think it's worth it for the runtime validation.
It probably depends on your project, but I find type checking to be at least as crucial on the backend as the frontend (probably moreso), and being able to share types/have editor auto-complete across the whole stack is a godsend. While node isn't my favorite backend environment, it's not too bad (async/await are fantastic for io), and code sharing/type sharing makes it the most productive choice overall imho, all things considered.
Clojure's a lot of fun though, and it has taught me a lot, so I do see where you're coming from!
We found @nexus/schema to be excellent for this particular problem, but only after you set it up correctly to feed in type information via its typegenAutoconfig options.
I agree it is less frequently helpful at catching type errors, but the errors it does catch tend to be more important to get correct than the frontend errors!
The non existent standard library and pretty nutty dependency management makes JS a bad choice for back-ends. There was a article a few days ago on how Deno is aiming to fix most of this and other issues, but I wouldn't use it for a couple years.
Back ends tend to stick around far long than front ends. Every company I've worked at is still running their original back ends, some decades old. Front ends are easier to replace because it tends to be just UI stuff, not a lot of business logic. I apt to take a lot less risk on the backend. It's probably going to be around forever and customers don't have to see how crusty it is :)
I shun the unnecessary - completely with you on that. But I'd prefer gaining relative mastery over _1 decent tool_ in each of the areas that you pointed out so that I have enough tools in my toolkit which prevent me from using the wrong tool for the wrong job. For example, I'd hate to use shell scripts to do something that ansible does really well.
A modern solution, fortunately or unfortunately, is built up of multiple smaller tool sets as you pointed out - and, if used correctly, each enhance productivity tremendously. Writing a frontend app (something that I've only recently started doing since I'm on my own) is immensely more productive if working with something like react rather than with a relatively old framework based on the jvm.
What I'm trying to say is - tech we use is ultimately a tool - we should optimise for productivity. In that case, Boring Technology helps being more productive since we know a lot more about it which makes it easier for us to bend it to our will as well as debug/diagnose the unknowns.
But it also doesn't mean we continue to use `grep` when silversearcher/ripgrep is out there in the world :)
That's the lens that I look with when I come across new tools/technologies (regardless of how long they've been around) - do they have the potential to be net-productivity enhancers over a long-ish period of time && by how much (0.5x? 5x?).
I gave in because they are having fun and it looks good, but it could have been done in static html (maybe using a generator) way more easily.
It hurts me everytime I‘m thinking about it.
Works well for static pages, this is what I did so II could use next/react and deploy to a boring LAMP server we have for our landing pages.
Especially long term wrt security
The amount of stuff you can ram into a front-end code base is truly insane.