Everybody has at least one horror story about a renovation project that spiraled out of control because of dependencies. You know, when you just want to repaint the bedroom, but it turns out that you also could change the windows, and then redo the electric wiring too… and before you know it, your entire house turns into a construction site for months on end.
Just like in our daily life, in web development you can also get lost in details that may give you short term satisfaction, but on the long term they prove to be a pain.
The frameworks mirage
Web development is filled with trends. Nowadays, most web applications use front-end frameworks like React, Angular, Vue or Ember. The communities for these frameworks are huge, and there might be a chance you could find a small library out there that already satisfies your needs. But that library might contain a vulnerability, or it might not be suitable for one desired platform.
In time, instead of advancing with your project, you’ll end up patching and solving problems that weren’t planned.
The self-poisoning waterfall
Here’s a bit of my experience: last year, my team and I were working on a software solution that was intended to be a cross-platform, crypto-wallet app. We wanted to build an app that worked on web, but also on devices with iOS and Android, and we were also thinking about a desktop app.
After a bit of research, we decided that using React-native will fit our needs. We started to make the first Hello World screen and everything worked smoothly. In only one month, we had a prototype working on 3 different platforms. Also, the React-native was working just fine for mobile device platforms.
But soon we hit the first issue, when developing the web screens using React-native.
To solve this, we found a React-native-web library that allowed us to use React-native components for web. Still, we were happy we were able to write single code that would work on all platforms, even though we had a lot of compatibility problems between react-native, react-native-web and the building tool called expo.
As we advanced with implementing the app functionalities, we started having big issues with vulnerabilities. On one hand, the React-native was trying to keep up with the reactJs, but on the other hand, the react-native-web was almost abandoned.
Some problems came from unexpected areas, like excessive use of NPM modules.
It is known that in software development you don’t need to reinvent the wheel when it was already invented, tested and the carbon footprint was already minimized. You can use these open-source libraries (exported as modules through NPM) and publish your work as an offering to NPM. That’s why open-source is so cool. And yet, if you are building more than a faculty project, things are not so <3ly. (Funny fact, did you know that there’s a NPM module wrapping your text with hearts? Check-out the npm-in-love module.)
Mind you, we were building an app to keep user’s secrets better than conventional cloud storage services. We had the idea, we had the motivation, but yet, with no proper infrastructure, we ended with build messages like the following:
So that’s what dependency hell looked like. And that is the point we turned around for alternatives.
The frameworkless movement
After this experience, as a team leader, I was ashamed and felt guilty that I fell into the trap of using well marketed, yet, beta version frameworks and libraries. After some research, I found out that I wasn’t the only one in the universe who had this pain in the ass. There were many others and they suggestively titled themselves the frameworklessmovement.org.
They even created a manifest of their movement, where they defined four principles that should be rigorously debated before starting a web project:
- The why: The value of a software is not the code itself but in the reasons behind the existence of that code.
- The context: Every decision should be made considering the context. A good choice in a given context could be a bad choice in another one.
- The choice: The mindful choice of a framework is a technical one and should be made by technical people, taking business needs into account.
- The transparency: The decision-making criteria that led to the choice of a framework should be known to all members in the team.
Looking back, it wasn’t the first time I used frameworks. In the past I successfully used AngularJs for developing some awesome apps. But the current experience disappointed me and made me realize that I violated the first 2 principles:
- I put the value of code first, even though I wanted to develop a cross platform app where data security was crucial.
- I didn’t think too much about the context of making a cross platform app.
Tackling web components
When I realized the bad choices I made, I tried to find new alternatives. This time I knew that I had to develop an application that first of all is a secure digital wallet and second, is a cross platform app.
Don’t get me wrong. We liked writing react components. We liked JSX templates and we really found Redux useful. And while all these seemed to be convenient to our needs, we didn’t want to hear about dependencies anymore.
While we were fixing dependencies, we started to look around for better solutions and observed an increasing interest for native web components.
You must know writing web components can be exhausting, because you have to write the style, the HTML and the JavaScript code in one single file. But surviving dependency hell had somewhat shed a softer light on these shortcomings, and made us embrace the future of web development: Native Web Components.
Alchemy exists
We dug further for more resources to overcome this. After a while I found StencilJs, a self-proclaimed powerful tool for building web components, and at the same time maintaining the concepts of the popular frameworks such as reactive data-binding, virtual DOM, async rendering and JSX. And, as I said, JSX templating is so useful and I really didn’t want to give up on it.
That put sparks in our eyes because we had a background with other frameworks and it was easy to adapt and code using Stencil and everything was accomplished with almost no direct dependencies.
What followed from there was a continuous achievement using web components without any dependencies. The project is not completed yet, but we’re close to a first release and I’m really satisfied with the results so far.
Final note
In case you’re wondering, I don’t regret the bad decisions I took in the first place. I think it’s important to learn from professional mistakes as well as admitting that we’re humans and we’re vulnerable to bad choices and well-marketed illusions.
As programmers, sometimes we can’t see the forest from the trees. We may be novices in the field, or we may be led to the wrong path, or we just may be too stubborn to accept that we made some bad decisions. The key is to avoid repeating the same mistakes and to find other paths closer to the solution.
Share your thoughts
What would you have done, in my place? Would you have worked harder to find a solution using react-native and react-native-web? Or, like me, you’d have chosen native web components, especially that modern browsers now support them? We can all learn from your experience, too.