Choose Boring Technology (2015)
mcfunley.com
mcfunley.com
Choose the technology you know in and out, and are immediately productive with.
Choose the technology which is sure to be around in 5-7 years, preferably 10-15.
Choose the technology for which you are comfortable hiring the next 15 engineers.
This does not mean that you need to choose something unpleasant, unergonomic, or ancient. Neither does it mean that you need to choose exclusively among the top 5 most used in the field.
The key thing here is to avoid surprises, unknown unknowns. You won't have the time to learn from a novice level while building a new company.
A number of wildly successful MVPs were implemented with obscure (or then-obscure) technology which authors knew very well, and which boosted their productivity. ViaWeb was written in Lisp. YouTube was (and still largely is) written in Python, way before it was cool and well-known. The initial Rust compiler was written in OCaml.
I agree with you on just about everything, but python was well-known well before YT. Django was a staple of the early web.
Perl wasn't the only CGI in the early days - a large internal web application I encountered as late as 2004 had it's CGIs written in C, running on IRIX
PHP is certainly the newcomer as far as I'm concerned
But seriously, the dynamically generated content of the early web was cgi, perl, later some python (as in scripts, not in django)
YouTube founded February 14, 2005
I was an early Python adopter (1995/1996) and could not for the life of me find anybody who would consider letting me use it in 'mainstream' commercial software projects. Then all the sudden about 10 years ago it exploded in popularity big time.
But I'd moved on to working on other things by then, I no longer enjoy writing in Python.
Wow, this sounds like the classic "I was into that band before they popular" indie snob, hah!
ASP was also a favorite of the early web.
http://www.paulgraham.com/pypar.html
Seems like Python is now in the camp of Java now given the current trends.
The key value is indeed to avoid surprises.
When I read WhatsApp used Erlang back in the day, I was pretty impressed. Not only the obvious things like Erlang was the forgotten secret weapon for massive concurrent apps, but also details like they used FreeBSD back in the day when there was no preemptive scheduling but Erlang has preemptive scheduling so it was okay. Those details reflect they were very confident and they know perfectly what they were doing.
* Choose boring technology
* Choose well-known technology
More people will click on the first one because it comes with a paradox suggestion. Why should I intentionally choose something unpleasant? That poses an interesting question. The second title sounds boring (how ironic). Why would I click that?
For most developers it seems to work the other way around - big names and marketed heavily => it has buzz => it must be good.
Under boring there are two types - PHP and postgres. Boring tedious and annoying and boring reliable workhorse.
The 2nd type is my favorite type of tech.
Simple C-ish syntax that's relatively familiar to most programmers, write once and compile to/from anywhere without arcane flags, easy to understand and use concurrency model with message passing, reference development tooling that can enforce standards out of the box.
I don't think there is much new here other than removal of cruft.
The tech was "exciting" because Google released it. Pretty much anything Google releases is coated in magic pixie fairy dust (perhaps slightly less so these days).
Tech like postgres doesn't get that kind of hype.
Dart didn't make any impact till flutter was launched.
They bolted on two principal new features: channels and garbage collection. They also added a few hacks, like the two-value return.
And lo, we have a winner based on tech form 1970s and 1980s, with only a small bit of pixie dust from 21st century proper, the advanced GC. Anybody can become productive in a weekend. (Then the productivty ceiling is hit soon, and copy-paste programming ensues, but the initial high is strong.)
Also, It's basically impossible to hire someone who is an erlang expert, meaning everyone has new to erlang.
Because of these and similar issues the company constantly had outages, despite using Erlang which is supposedly highly reliable.
It's pretty risky for most teams. Despite Erlang was old, those ideas are both alien and novel to most people. The idioms, the patterns, and the architectures are not well explored as mainstream languages. In my personal experiences, there are also many rough edges.
With that being said, the example I raised just to illustrate that the WhatsApp founders had deep understandings of Erlang despite it was a niche technology. The same applies to FreeBSD. Those are the so-called 'boring' technologies for them.
It's even biased the wrong way, tech does become outdated at some point and best avoided, but "mature" only increases with time.
In my past job I was ColdFusion programmer for 15 years. ColdFusion ticks all the other boxes.
* Created in 1995 and is a very mature platform
* Easy to learn and productive
* I was very comfortable hiring multiple ColdFusion engineers over the years
But, the community moved on and the tooling is now nonexistent compared to other programming languages. ColdFusion will live on, but as a shadow of what it once was. Which is unfortunate because I actually enjoyed the language and platform.
[0] https://lucee.org/Maybe in 15-20 years ColdFusion will become like COBOL or ADA, where there's a bunch of code running some necessary systems and nobody knows how to maintain them. But it's a long bet for a payoff that would be much higher if you spent your time somewhere else.
About Lucee ...
I actually helped the company migrate away from Adobe ColdFusion to Lucee due to a chance in Adobe's licensing. We migrated a large, 10yr old, application and all clients over to Lucee in about 1 year.
Lucee is a nice platform but I'll warn that it's not as polished as Adobe CF and there's some difference in features. You'll run into rough edges in their documentation and language implementation (especially the scripting languages). One nice thing I really enjoyed was being able to download the source and figure out how my CF code was actually being compiled into Java. It took me a few days to understand the parts I needed but I actually figured out some issues I was having. I also was able to build Lucee from source, just for learning, which was really nice.
What I see is Go pushing it out from the DevOps space and Python is more popular as a general-purpose language. Tools that were written in Ruby(eg.: Puppet) are outdated and new tools are written in Go. I still think Ruby is a superior language compared to Python, but because mathematicians used Python and the recent ML/big data hype it got more popular and got better libraries which caused an upward spiral.
While Ruby is the language I most comfortable whit and I don't see it going away in the next 10 years. I have to accept that first-party integrations will come later and later and there will be less third party libraries. That is why I'm currently learning Go and if anyone asks me what language should they learn first I point them to Python.
All these companies you listed using it with Rails and that part of the ecosystem is alive and well, but I'm not interested in it.
A few years ago Ruby ruled the DevOps/Cloud space(which I working in), a lot of tools was written in it, but with the dawn of containerization, its former glory starting to fade. Docker, k8s, or even the new GitHub CLI is written in Go. While I am happy to write Ruby code, I can't expect the same from my colleagues.
While professionally I don't think I will continue to use it much longer, I still planning to keep up with it. Before the lockdown, I started teaching Ruby at a local meetup group, and I can't wait for Ruby 3.
I am thinking someday Crystal post 1.0 would be able to put up a fight in that space.
HTTP/2 is essential if you want good SEO which makes Rails a non-starter for many projects already
And sooner rather than later you are going to need a load balancer anyway.
If you know you need to cut a hundred trees to foot-long logs in a certain time-frame, you don't pick the new fancy gadget you just got from Kickstarter. You know, the one with a WiFi notification system and a cloud SaaS service etc.
You go with a regular hand-saw, axe and a proper chainsaw. You'll get your stuff done - on time and on budget. You might not get the thrill of using the latest and greatest tools, but you'll get paid.
After that you can grab the Solar/Hydrogen-powered Indiegogo-funded whizbang and go test in on a tree or two on your own time.
Please don't take it the wrong way, but the days of XML for everything are long gone, and for years in Java it's been XML for nothing as a counter reaction.
You must judge Java by the developments of the last decade at the very least. Otherwise you're ignoring the practitioners.
Java hasn't used XML in ages and you cannot fault it for legacy apps. You could similarly complain about the horror of EJBs -- sure, but the industry has moved on and acknowledged they were a mistake.
I think plurality of situations it's actually used for currently would be a better standard than what you're advocating for.
This has the advantage that the merits people judge things on, and the experience they will most likely have using it will line up.
The downside is that, the merits used may differ a bit between markets or industries, but I'm personally ok with that.
Imagine if I complained about Linux and all I used as an argument was the Unix Haters Handbook.
Imagine if I complained about Windows and the most recent version I had used was Windows 95.
If you want to be able to know the theoretical things you could do with the language, I think your definition is right.
If you want to know the most likely experience you would have using the language, I think mine is right.
I think it also depends on what circumstances you're using the language. Spinning up a new project probably lends itself more towards your definition. If you're looking to join an existing project, mine is probably more useful.
Java is a pretty solid tech and the JVM is one of the best runtimes in the world. But it does offer you infinite possibilities to write awful code and that made me less interested in it with time.
I am saying that when I was contracting with Java some years ago it was a complete crapshoot: you could get an almost brand new project with a lot of thought put in that made it a pleasure to work on, or you could get an ancient EJB mastodon that made you want to slit your wrists.
And that gamble still exists if you want to contract with Java. A lot of preliminary negotiations have to be done in order not to find yourself in a situation where you should have charged $30k a month due to the insane amount of digging you have to do just to make the thing accept one new feature.
It's much less annoying than "exciting" episodes and habits:
- let's see if our SSL certificate has been actually updated on all servers in the cluster
- let's find out what I need to restart after deploying my web app update
- who knows what the classpath loading order will be this time; if it's broken you can try a restart
- finish the test quickly before the sysadmin committee begins an application server upgrade and everything goes offline for as long as it takes, hopefully only a few hoursFor me, part of "boring" is being like a 2x4 or a claw hammer: simple, solid, reliable, well understood. A lot of the Java world is nothing like that.
If you start creating something called AbstractMonthlyBillingReportAggregatorFactory that inherits from AbstractBillingReportFactory that inherits from AbstractReportFactory all of which implement a Report interface, things have gone unsalvageably far off the rails to be useful any more.
It’s fair to say you could do this same thing in C++ or Python etc., and sometimes that does happen. But just anecdotally observing this in many companies, it happens _on purpose_ with Java all the time, but much less so in other ecosystems. In other systems it’s just much easier to get things done without resorting to tons of inheritance misdirection, and many great common libraries already solve problems in those ecosystems with minimal inheritance bloat, giving lots of easy to follow examples.
These are fashions in the software engineering world. Had Ruby dominated the development world at the time Java did, you would have seen the same enterprisey patterns.
For an article about "stick to boring and reliable" there seems to be too much push back against Java. I understand the psychological processes involved: stick to boring unless it's the one technology one personally finds unpalatable -- for me that would be COBOL or ColdFusion (and yes, I'm aware Java has been compared to COBOL by proponents of trendier technologies! :P )
If a language supports what I would call “lightweight OO” - extremely low boiler plate, zero required OO constructs (purely optional), and language features that render the concept of dependency injection intrinsically obsolete (because mocking can be done purely through introspection at no cost), then that flavor of OO is well suited for business problems.
It has less to do with things like JVM or GC oddities, because those can be straightforwardly engineered around. It’s more about what non-negotiable commitments to specific patterns or strategies come along with the language choice.
Pure functional languages are the worst offenders in this area, which is why their benefits aren’t actually benefits and they are poorly suited for business software. Of the core “industry standard languages” Java would be the next worst offender.
Conversely, I think C# is an ecosystem that suffered the same limitations as Java but found ways to extend and reinvent that make it more attractive now, though still far behind Python, C and C++.
and
> Pure functional languages are the worst offenders in this area, which is why their benefits aren’t actually benefits and they are poorly suited for business software. Of the core “industry standard languages” Java would be the next worst offender.
You seem to be talking out of principle instead of actually having hands-on experience developing large systems in Java. To be honest, it doesn't seem you're familiar with the language or the platform.
I'm not interested in debating your theoretical preconceptions.
You seem likewise uninformed about functional programming and how it has been used to write extremely high-performance fintech systems.
In any case, that Java's OOP cannot be successfully deployed for business software is counterfactual. Anyone insisting on that point is unfamiliar with Java.
Is the reason a mystery? Java is the language that got a multibillion dollar marketing pitch at its inception. It was designed to be in "the enterprise" from day 1.
Strong disagree. This is exactly what most of the Java world is like: well understood and reliable. I wonder if people who say things like you did actually use it for their day jobs, or rely on things people using other technologies claim in their blogs.
TBH, this is exactly what the Java world is like. There are not many surprises in Java land. The language isn't getting fantasy land changes on a daily basis. There are libraries that haven't been updated in years because there hasn't been a need to update them - they just work. People want to leave Java because it's boring.
Is Java perfect? Of course not, no language is perfect. But, Java is the closest thing to a boring 2x4 the programming world has ever invented.
That's a good point. I wonder how many successful apps used tech that only appeared boring after the fact. Rails is a fairly boring stack today but back when GitHub started, it probably wasn't.
How could you have known that right when it came out?
I also agree that the better measurement of good software is that which is unsurprising. Code should be easy to follow, and the decisions for the software tools that are used should be given the same treatment. You should be able to explain your code or infra to most developers without any raised eyebrows. That doesn't make it boring. In fact, it's very interesting when a problem that looks complex on the surface can be solved by relatable means.
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.
In the past I have been told that I "don't trust developers" (despite being one myself), and it has nothing to do with that. It's that some of us are left with the consequences of those decisions and having to maintain those NIH-riddled skeletons in the closet when those individuals leave - and the next person comes along, finds the skeletons and we end up having to rewrite/reimplement that whole part of the system.
Creating an environment where we can thrive and be creative is really challenging. We've implemented the 20% time now where everyone in the company has 1 day a week to just experiment and do whatever they want, just to give the breathing room to be creative and try some of these new technologies. We finally got there. But for years, we just couldn't afford to do it as we were in survival mode.
But the retention issue is still a big one. I feel the tension between having to empower people to make decisions that are for the greater good of the business, while balancing that those people can (and will) leave at any time and not face the consequences of those decisions.
Curious to hear thoughts.
If you are mid-size company, I will assume that you can afford giving some breathing space for everyone to explore but still focus on the goal. You should ideally retain them with the culture.
These are the suggestions based on my experience. I may be wrong.
In these companies you still have to hire developers for reasons beyond excitement for The Idea.
I realised that having people who love your culture will always have your back irrespective of what they do.
Also, Being a niche software shop, one could potentially become contributors to that technology which is exciting in itself.
That's fine, let them go. There are plenty of great developers out there who just want to come to work, build the product to spec in some 'boring' reliable tech, and go home. The stack doesn't really matter. The "mission" doesn't really matter. Even the product barely matters. I've found that people who are leaving a job for the new shiny thing are either very early career, or the dilettantes who leave behind messes to be cleaned up by professionals.
Massive companies have been built around a Spring/Rails/Zend monolith with a few jQuery plugins on the frontend. Anyone who thinks they need more than that is probably wrong.
No there aren't, in fact there aren't plenty of "great" (or pick any adjective related to competent) devs in general, so if you're a small shop and can't compete on wages, work conditions (tech stack included) is your only competitive edge. Because you know what there is plenty of ? Enterprise gigs that need competent people to maintain a legacy cash cow or business backbone - and working in those environments has competitive advantages compared to working in small companies - corporate pace is usually 1/2, company stability, climbing the corporate ladder - if you're a 9-5 guy these things mean a lot. Even those places need to mix in flavour of the day tech to keep their devs from leaving the mind numbing work they feed them.
Yes, there are. Such a ridiculous statement to think people can't be great at something just because they don't tick some arbitrary box you came up with for evaluation.
If that's the case, then there are no great 9-5 anything... but the odd thing is, I've met plenty of them.
Just like your argument, which pulls claims out of thin air. You haven't made any points at all, simply rambled about competence without backing anything up.
I've learned more often than not, that when someone claims "competence" what they're really saying is "I'm not finding the exact skills I'm looking for, which are hyper-contextualized around the problem I'm currently facing, at the exact moment I need them at the cost I think is best. Which will change in six months, at which point a different cohort of people will be labeled incompetent."
I think introducing new tech is fine as long as it solves a new problem for your business. If you haven’t yet used a cache, but have a need for one, introducing Redis or Memcached makes sense. If you have a new need for pub/sub workflows, introducing Kafka or a webhook dispatcher makes sense. Same with Elasticsearch or whatever if you’re building out your first search feature, etc.
What rarely makes sense is introducing new tech that heavily overlaps with existing tech. You don’t wanna end up on MySQL and Postgres and Mongo. Python and PHP and Go. Django and Flask. EC2 autoscaling and Mesos and Kubernetes. Even worse, you definitely don’t wanna start building your own versions of tech that there’s a good off the shelf solution for. If someone tries to build their own UI framework, ORM, service discovery system, etc., kill that IMMEDIATELY.
Introducing new tech that overlaps with existing tech should only be done if you’re going to migrate OFF the existing tech. Obviously this is often a major effort, so the new tech has to be a HUGE win.
My current company was pretty immature for a long time in terms of tech decisions, and the costs are massive. For service-to-service communication we use REST, gRPC and this terrible in-house re-implementation of HTTP over ZeroMQ, complete with hand written clients and server frameworks in multiple languages. We’ve been trying to migrate off that for ages, at massive cost. We’re almost done, but even then will still be stuck with both HTTP and gRPC, when we only need one. Similarly, we use PHP, Scala, Go and Python on the backend. With multiple server frameworks for each. We use MongoDB and MySQL. Redis and Memcached.
The cost of all this is massive. Developers have to learn SO much to be productive in our stack(s). Every time we want to write some middleware, tooling, etc., we have to write like 15 versions of it, because we have about 15 unique combos of backend language/network protocol/framework. Losing a few immature devs who care more about using shiny new tech than solving business problems is a very, very small cost to pay to avoid this situation.
I've seen an internal tool at a previous company that seemed to be built similarly by developers who wanted to try new tech. A pretty fancy RoR with a lot of custom changes and integrations. I am sure they had a ton of fun building it, but again, guess what, they were all already gone by the time I started there. And those who stayed hated that code base with a passion because it was near impossible to upgrade, so now we were stuck on an ancient RoR version, and since it was integrated with a lot of other systems it blocked those upgrades as well. Cautionary tale I guess.
Did he ask if his tech choises were ok before he started?
Or informed you what was on his mind, although maybe didn't ask explicitly?
(I suppose maybe it's not so easy to say no, if one is worried that he'll then leave)
Fuck the latest thing. Fuck resume driven development. Fuck magpies. Choose the boring path. Fuck developers!
The worst thing we do is obsess over the latest, coolest tech. Everyone is stepping on their brothers and sisters in this field because they want to be the loser that invented ${NEW_TECH}. We spend so much time optimizing for 'developer happiness' (a.k.a. the new shiny thing) that we forget about architecture.
I am so sick of this field.
Developers may be the least humble type of engineers. There are many great things that we do, but we need to be taken down a peg every once in a while. Many developers are forced into this mindset out of fear of our marketable skills being made obsolete so I understand why many do this, and it is a compounding problem. Developers seek out jobs with the shiny new technology or push for their company to adopt it to be able to show that technology on their portfolio, then there are fewer positions with the boring but reliable technology and even more are forced to adopt the new technology.
I think our problem (and my our, I mean American) is that we are too obsessed with tech. This is coming from someone who grew up obsessed with computers, and not just writing code. You can tell this is true from looking at our ads, which are always touting the shiniest newest technological marvels. Even beauty products -- they sound so sciency without actually saying anything. Tech is our dogwhistle.
Personally speaking I spent far too much time working on a certain technology for four years and I felt trapped because getting a new job was difficult in new technologies.
There are clearly some Evergreen Technologies such as C/C++, but there are a lot of Technology switch don't land in that category and they evolved fast (js ecosystem for instance).
I'm a new developer looking for my first job and so I'm making side project to learn in the meantime and what I primarily want from a job is the ability to increase my skills, to get better and to improve, I feel like the kinds of places that are willing and able to experiment will not only have more of a learning culture but will attract others like that as well, so they are more attractive to me as a developer. I imagine this could be countered by things like proper mentor-ship programs or side project time like you've already implemented.
Technology selection is a very underappreciated and largely unreported skill set.
I think it relates to the Principle of Least Surprise. You can pick tech that has a lot of upside and isn't riddled with gotchas or demanding of eternal vigilance, or you can pick stuff that makes you feel like you're alive all the time.
The latter is risk-taking behavior. It's thrill-seeking. Several other replies exhibit disdain for this behavior, as I think we all should. These people are risking your company for cheap thrills. As one responder puts it, fuck 'em.
Let's say you decided to write a webapp a few years back when RoR and AngularJS/CoffeScript was the popular stack. You wanted to write it in Clojure but you though "I can't hire Clojure devs reliably and RoR is popular so let's go with that". You are a small business/not high growth - you grow your app steadily - you now have a sizeable codebase on a legacy code stack that nobody really wants to touch or learn, there are plenty of job openings on that stack you have to compete with. Meanwhile people enthusiastic about Clojure were probably above average developers who would be happy to take below market rates just to work on a stack they enjoy and you could easily find people even today.
In a market where demand outpaces supply I'd say the "safe stack" is not a correct choice for small companies - if you have the know-how to pull off something more cutting edge. If you don't then ofc. use what you can to get the job done.
Looking back, the best technical decisions were:
- using an SQL database with lots of constraints and foreign keys and indexes. It's like typing for data.
- emphasis on shell scripts and leaning on UNIX features (since these continue working in ten years rather than being abandoned)
- deleting as many libraries and dependencies as practical (over a ten-year time frame, 80% will disappear or change in ways that require huge mental RAM on your behalf)
- a preference for paying for hardware to solve performance issues (vs. complicating the code with fancy solutions)
For anyone interested, I go into more detail in this video https://www.youtube.com/watch?v=rQegYUsU7ec
It will still work in 10 years if your toolchain hasn't changed much.
The SPA is a gateway drug to spending lots and lots of innovation tokens, more, really, than almost any dev team can afford. For example, I would consider each of Webpack, PostCSS, TypeScript, React, Redux, RxJS, to be rather exciting, and that's only a few of the exciting parts of a mature SPA project. And of course this doesn't touch REST, GraphQL, CI/CD, testing, metrics, telemetry and all the other excitement.
So, yeah, I would say that if you take the article seriously for a webapp, you'd limit yourself to a really boring Java (8) server-side architecture using Jetty, JSP, Spring, a service layer, over Postgres. Maybe an nginx proxy if you want to get a little spicy and have good SSL and static serving performance, and an option for simple load balancing later. Oh and the only provisioning you get to do is individual VPSs or even better, bare metal on prem servers! Git and Jenkins is probably boring enough to use, though.
But yeah, no Docker, K8s, OpenShift, no AWS other than EC2 and maybe S3. Probably no CloudFlare. Google Analytics, sure, but only if you don't care about your users privacy. Sentry is too exciting.
And then on the HTML side I'd argue that your templates should produce plain old HTML5, CSS3 and ES6. No transpilation, no source maps. No official support for IE 11. And even for those languages you can cut out the most exciting features. Do you really need the "class" or "new" keywords in ES6? For JS modules, use the boring, built in browser module system (you knew it had one, right?![1])
React has become the de facto lingua franca for front end development. Could you imagine some CTO or technical lead saying, "We're not going to use React because it's too new and unproven." React has proven itself. Facebooks has 100K+ components. There are no unknowns there. Using jQuery or vanilla JS instead would be way more problematic and have more overhead than using something more experimental like Elm or ReasonML.
You should almost never use classes in JS, but when you do, they're much easier to work with and understand than defining properties on the prototype. The "new" keyword has been around since almost JS's inceptions (it's available in IE 3, which came out in 1996).
Some of your technologies require no learning to start using (PostCSS). Some can require a whole new mental model/programming paradigm, but can be incredibly useful if used sparingly and in the right places (RxJS). And some things you just need to do to not have a garbage application (testing).
Look, just make assessments as to what your needs are, what are common practices, what your current team is capable of being productive with, and what you're going to be able to hire from.
is this still a valid concern as of today ?
There... that's the problem.
That's a totally optional component that now needs to be updated, used in your build pipeline and Lord help you if you install it with npm and it isn't updated for a couple of years.
I'd add boring really means boring, yes that kind of boring (zzz) ;)
That said, with recent and planned advances in CSS3 (and free of the IE shackles :) ), CSS preprocessors surely are slowly going the way of JQuery.
Despite having a couple years more experience in React than SSRs, I can knock out a 10 page web app with an SSR framework from scratch in a day (security, frontend, backend, data schema, deployment) but it takes me a couple more to knock out the same app in React. (Crud/Search/Reporting app)
*Not counting certain types of highly interactive apps (like a Word Processor) which React excels at.
One key feature is that JSX works on both the frontend and the backend.
However, I find it hard to justify choosing SSR for new projects anymore because:
- React makes certain basic things (eg, fetching data, auth) more complex than in SSR, but the overall experience is weirdly addictive and exhilarating at times, especially component reusability on a well set up project.
- My clients love it. I am 100% in the camp of “users don’t give a shit how the sausage is made”, but I constantly get praise on how “smooth” the UX feels. I know there are SSR technologies (eg Turbolinks) that can emulate this, but at this point I’m having a hard time justifying learning them properly and risking missing out on that maybe superficial, but addictive, customer praise.
- It is indeed what I know best, so what the hell...
I believe a competent web developer should know both SPA and SSR and apply what best fits the requirements at hand, but I can also appreciate why devs form biases one way or the other and how this has become a hotly contested topic, and I think we may still be in the same spot in three to five years.
There's certainly answers which seem promising for all of those areas, but it seems to me that in every React project I work in, "use React" is the easy part - it's the 50 other decisions that need to be made as a consequence of that first easy decision that waste a lot of time and energy.
I would like React to get more boring. Because I'll never focus mainly on the front-end, I can't devote a lot of cycles keeping up with the latest trends. If I have to make 50 (or even 5) informed decisions every time I want to throw a little interface on something, I'll never get anything done.
In a way React suffers from it's own popularity. For example Next/Gatsby can be confusing for new developers but they only exist because React is popular enough to have popular meta-frameworks focused on solving specific use cases.
However, if you have React devs in your team, then this is NOT spending an innovation point at all. The same would hold true for even MongoDB here.
That said I am always of the opinion of don't SPA if you don't need to. (also don't spar if you don't need to!).
Is routing in react as mature and boring as a UINavigationController whose API has barely changed since 2009, for example? Is animation? Accessibility? Styling? Are the material-ui and ant-ui kits as boring and mature as the platform’s UIKit?
And I’m not even going to bother going into development environments, or the effects of all these different approaches & API changes on documentation and support!
Set aside the GitHub stars, contribution graphs and HN reviews, and boil the tech down to its fundamental principles. Then ask yourself how a perfect implementation of that design would solve your problems. It it solves them well, you're golden as long as the project is reasonably healthy. If it doesn't solve them well, you might be setting yourself up for serious pain down the line, and need to make a very conscious choice about whether the short-term benefits of that technology choice are worth it, and how an eventual migration to a better-fitting design would look like.
It is time consuming process to become expert of one thing, requires couple of years of continuous focus.
I don't know How many people are actually expert of all these and how they are going to perform when some issue pop up in production. Try that judging it 30-to-60 minutes of interview.
You can still make something that works on your own, but not using all the new tech. You have to compromise somewhere. The notion of "full stack" devs is long gone. Making modern web apps is a team sport. You literally can't be an expert in everything you need to build a robust, scalable, fast, accessible web app anymore.
They read lot of 'buzzword' on the internet or heard them from their tech friend and ask for everything i.e. Microservice Architecture and cloud and all and etc. since beginning. Resulting in unnecessary huge team and tech complexity. An idea or poc which could had been easily done and tested in market with small techstack/small team. No wonder lot of these products fail.
Anecdotally, in my 20+ years of working for website and web app companies, I have never had a client who has even suggested a specific way of implementing an app. The closest has been when a client has asked for a tech proposal and had it sanity checked by a third party. These days I mostly work on "rescuing" apps that a client has had built by one company, found it hasn't gone well, and has come to the company I work for to make it work properly. All of the crazy tech stack implementations I've seen have come from developers who think they're clever, and never the client demanding something trendy.
Wasn’t any Ansible then, either, you had to write your own damn scripts.
In contrast, competing technologies started out with, "OK, learn computer science. Now learn how HTTP works. And then learn CGI. And some Unix. And then you can do 'Hello, World.'"
The funny part for me is that a lot of us in the latter camp didn't learn computers that way at all. We started out with BASIC:
10 PRINT "Onion2K is cool!"
20 GOTO 10
It had the same immediacy as PHP. The ease of making something happen was what drew us in. But somehow we forgot that. While also saying, "Here's something that will touch everybody on the planet. Let's all use it!"How many people had rented servers for games? A lot. Now video game companies have turned game servers into a SaaS, whereas then they just released Linux server binaries. In the early 2000s there was a bare metal server rental company on every other street corner.
How many people had Linux/BSD network appliances? Also a lot. There was such a time when all you got from the cable or telco for your broadband service was a modem, and you had to roll your own router/switch. There were a multitude of run-from-a-floppy (or USB stick) BSD and Linux router distros back then.
Also, you're not correct on PHP. The entire reason PHP grew so wildly was because it was server side rendered, and both AOL and Microsoft intentionally hindered their browsers' javascript capabilities in lame attempts to monopolize the internet.
If you want to be effective as a small team, choose tools built for small teams. Rails is a great example.
And if a person with 5 years of experience sais he is an expert in a,b,c,d,e you don't need an interview do understand that this person doesn't even know what it takes to be an expert in one of these, because he obviously can't evaluate his skillset properly.
Nowadays you need very little to qualify to be "expert" or "senior".Sure there are exceptions, but in most cases, all you need is be able to use the technology. In most cases, people don't even understand how it works under the hood.
Just like with full-stack developers. Most of those whom I have seen know some front-end, some back end, and very basic database knowledge. And considering that in these cases both front-end and back-end are written in js mostly, "full-stack" here is a huge overstretch.
https://news.ycombinator.com/item?id=9291215
A related page I recall seeing on HN last summer:
There are a lot of people who confuse “boring” with “well-known”, and they’re not the same thing.
Example: you decide to write C++, but the C++ you write looks a lot like C99. You rationalize it as though you’re avoiding the overhead of all that nonsensical modern C++ and doing the simpler and thus more-boring thing. In reality: you’re writing shitty C++.
For the technology you choose, you should buy into it. Full stop. Don’t half-ass it.
Lots of us are motivated by learning things, and some are motivated by investigating and solving problems when things don't go the way they supposed to.
If you pick a 'boring' technology, you have less of those two things, and you are stuck with boring process of developing one feature after the other with boring technology until sufficient number is developed and you can go do something more interesting.
That can easily be seen as unprofessional from the outside and I'd agree you shouldn't conduct yourself like that when there are money involved but that also leaves something to be said about the productivity of the tools we work with.
> Lots of us are motivated by learning things, and some are motivated by investigating and solving problems when things don't go the way they supposed to.
I kinda realized this about myself recently, and now I'm wondering if I need to leave the field.
But in all seriousness. Software development does not only need builders. Builders build stuff well but at some point they make mistakes or overestimate their knowledge of technology. Then obsessive learners and investigators are godsend.
Just know your limits and don't hope to do well at solo projects when you are in it for learning or bug hunting.
Too many changes for each version, The bundle size was too big. Angular SPAs were not great for SEOs etc. We ended up missing the shipping deadline by a couple of months.
When you really want/have to `ship it`, pick any technology you and your team have delivered something before.
When you have time to explore, pick any new shiny technology, and concentrate on learnings.
300kb is a lot, but it's also a huge framework.
And if you search their forums on how to do something (like take a video in mobile and then showing it on the ui) it depends on each version and there are no clear answer.
It might help if you stick to one version until shipping something meaningful
Edit: Oh, it needs a (2015)
Boring in this context doesn't necessarily mean 'old' technology. It means technology that is so stable & reliable that you forget it's there.
I can go weeks on end before being tangentially reminded that we use SQLite to store business entities. I am usually in the arena of business logic working with our various customers. This is what boring technology means to me. Stuff that "just works" and never causes you to spend any time worrying about it.
I'll take ye old PostgreSQL (with JSONB if I need unstructured data) or even mariadb.
I get it, in the end everything is disposable but I like to minimize that churn and polish what I have that works for me. It isn't as fashionable or as cool but I try to avoid those circles if I can.
Think it this way. You join a company and get two choices. One is to use a reliable albeit old system, read tons of legacy code and figure out how to do things other guys' way. The other is to build new things from ground up when you have a much bigger feeling of ownership, but risk breaking things up.
Which one do you choose? Note that you are a junior engineer, not a lead, not an architect.
Somewhat this is more like a class struggle instead of choosing the right tech.
Non-tech co-founder was worried from what he read on PHP etc.... Non-tech co-founder is not worried today.
The specific drivers of this tend to be a mix of problem-solving pattern matching ie “Hey, we know what the usual suspects are know when things are slow/crash”, and ecosystem robustness — what is the probability of you being the first to trip a bug in a dependency / has a library been used to solve 10000 problems or just 3 — It’s more likely that APIs have been sorted out, bugs have been closed, etc. or that your team knows the quirks.
As an example, OCaml might be a relatively boring choice for writing a theorem prover, but for something like a RDBMS-backed web application, things are a lot more “interesting” as you go off the map much sooner.
The company I worked at previously used Erlang. It caused a lot of headache in terms of finding well-supported database drivers and things like that.
Edit: Just an hour ago I was learning Heroku (having primarily worked with AWS, Linode and bare-metal) and I found that they call a collection of Linux containers a dyno. So we have droplets (confession: never used these), pods, clusters and now dynos. If nothing else, should we not at least standardize the vocabulary?
I still stand by everything I said in that comment, and it has served me incredibly well on every project I've worked on since. At least in the cases where I followed my own advice :-\
tl;dr: if you're trying to build and ship something quickly, don't use any new technology. If you want to use your project as an excuse to learn a new technology, limit yourself to only one technology so you can better isolate issues when they crop up.
There are three classes of companies: ones who haven't tried having a buffet of technologies, ones who already have and ones who are recovering.
https://boards.greenhouse.io/spacex/jobs/4747757002?gh_jid=4...
https://expatsoftware.com/articles/happiness-is-a-boring-sta...
If it’s Somebody Else’s Money paying for the development, go nuts with whatever crazy tech their 19 year old CTO wants to roll with. Hopefully they have a VC holding the bag to subsidise the ride.
But when it’s your stuff, and it’s your weekends you’ll lose when it breaks, use something solid to build it.
There is some impunity going on where the people making these kind of decisions in some companies when things fall down they just blame it on something else and switch jobs, and now you're stuck with mongodb or a django where somebody thought using sqlalchemy instead of the ORM was a good idea or a monorepo with all company's frontend code and its 14Gb of source code for scripts to make the tooling work in such monstrosity.
By the time new languages become the new industry standard, most developers will have had plenty of time to learn them. I've never heard of an industry change that happened so fast that it made the majority of working programmers obsolete in 18 months.
In this light, PHP coders are real commodities. They are paid lowly, treated as expendable, and get no respect by peers. I think they're going down the same path of "HTML experts" which were once lucrative business in early 1990s.
Java/C++ programmers fare better because (I guess) there is some fundamental difficulty to be proficient at them. So, despite being old and boring, being good at Java or C(++) is still a good business.
Learning Go/Rust is another way to avoid being a commodity. Although they have a smaller job market, employers need to treat you with respect, because they can't easily find another worker with a matched skill in the market.
He cited "known knowns", "known unknowns", and "unknown unknowns", but completely missed the biggie, unknown knowns -- things you are convinced are true, but in fact are not.
"It ain't what you don't know that gets you. It's the things you think you know that just aren't so." (Often mis-attributed to Mark Twain, but Josh Billings is a better choice.)
To use/apply any tech or workflow depends on execution.
So many new technologies seem like something new just for the sake of it. By the time they mature into something as practical as 'boring tech' they have many of the same pitfalls if not more.
Perhaps many engineers lack agency in choosing the problems they solve, so they seek to change the tools they use instead?
Restricting the number of different technologies in your toolbox gets you most of the benefits described in TFA. But contrary to "boring", it's actually preferable for some of those tools to be bleeding edge. That way you also get to enjoy the benefits of the Python Paradox.
Of course, you need to have good enough taste to pick new techs, and sometimes the bleeding edge will cut you. But because you amortize that cut over the whole org it doesn't hurt much.
So you see tech as you see fashion, i.e it requires good taste?!
When you choose a new tech, perhaps you should consider what problems it solves and whether its costs are worthwhile for you, not whether its a hot new fashionable thing to "wear" in parties (conferences).
"I'm not interested in learning Go because it doesn't have many compelling features"
"That IS the feature"
It's SO boring, but also very efficient. Yes, you type more words, but that's why you got the fancy clicky keyboard.
You get stuff done and other people can actually understand your code, because there are no hidden gotchas, everything is just as you typed it out. Even the boring and repetitive if err != nil stuff just fades away, but you DO notice if it's missing somewhere.
Now I value my time more and I prefer to focus on programming what gives value to the business I am building to.
There are less abstractions to hide the costly operations.
Don't insist upon the latest new treatment, unless you fully accept the rôle of guinea pig - for better or worse!
And I've seen it happen a couple of times.
Unproven technology has all that in spades.
TypeScript and Go and Rust are the hot ones now and they were barely on the radar a year ago.
Ofc I am inserting them into work projects as I need to learn them.
On the other hand, if a place needs Typescript, or GO, they'll mention it.
Every job I take, whatever the oldest crappiest technology mentioned in the footnotes is, ends up being 90% of my job.
[edit] oh and the small/startup space is overwhelmingly Node + some front end framework + a bunch of cloud shit they probably don’t need and have mis-used and mis-configured. Take out Node, .net, and Java and hell, the next biggest segment I see is probably low-paid PHP (Wordpress mostly) work followed distantly by Ruby (mostly Rails, ugh), Python, and native mobile. Go, Rust, Haskell, Clojure, all that, rare as can be.
Listed as "boring":
- Postgres 1986
- Python 1989
- MySQL 1995
- PHP 1995
Relatively "hot":
- Go 2007
- Rust 2010
- TypeScript 2012
- GraphQL 2012
- React 2013
But even though he talks about "boring" tech, he did go on to have a startup, Skyliner, which was written in Clojure and subsequently acquired by Mailchimp.
So I guess, you can't be using the borking stack all the time...