Over-engineering is the curse of the 2020s. Instead of following the good old Silicon Valley mantra of "ship fast and break things," many startups think they need a fully-fledged application from the beginning. That is never the case. Everyone wants to be Google, but no one is. Do they ever stop and ask, "Do I need to use Rust or Go to build this login screen?"
As experienced consultants, we've witnessed numerous projects fall into the trap of over-engineering. Our key insight is that the primary focus should be on testing product market fit. Users are indifferent to the technical intricacies-whether you're using microservices, the best hexagonal architecture, deploying on AWS, or a monolith deployed in your old laptop. As many of you are aware, simplicity reigns supreme.
When a project brief loaded with numerous requirements and quality attributes lands on my desk, the first step is to strip away anything that pertains to anything other than the primary two or three business flows. This paves the way for the adoption of the MONOREPO-MONOLITH architecture. On the DevOps side, we deploy docker containers to reduce environment switch complexity and expedite the delivery process. If we ever need to run long-running tasks or scale a specific section of the app, we can split services or use worker instances and jobs (e.g., leveraging sidekiq in Ruby or celery in Python).
It is crucial to take advantage of all the goodies that programming frameworks gift us. Good examples are Generators, conventions over configuration practices, ORMs, and packages. If someone has already built it, 1k people have reviewed it, and 100k projects are using it, why do you want to make it from scratch? What would 10ms faster responses from using a Go API mean to your users?
I don't advocate for any specific programming language. However, I recommend researching what's available to streamline the journey before jumping too quickly into something you know or a recommendation you read online in a forum.