My Last Learning Project: Technicality (+0%), Attitude (+1000%)
Earlier this month, I spent 2 WHOLE WEEKS on a toy learning project that I expected to finish in a few days. Spending such a long time on such an ordinary project affected my confidence more than a little bit, and so I’ve spent a lot of time since then thinking about what went wrong. Now I feel like I finally know why — I was bored.
Context
I’ve been at NGriid — an energy distribution infrastructure startup — as a frontend engineer for the last 10 months. I became a frontend engineer following my 2+ year career as a Software Engineer in game development. I spent the first few weeks learning JavaScript and React, then the next few months making and breaking several NGriid product prototypes in React. Thankfully, it worked. Our prototypes got investors interested and so it is now time to build an actual product. I’m the solo frontend engineer at NGriid and so far in my 10-month long web engineering journey, I have built just one fully functional web app: Spindr (you can read about it here). NGriid’s primary software product is a web application that allows energy distribution companies to monitor and manage their distribution network. It is a complex application, and so I decided that I would use Next.js (a React framework that significantly simplifies web app development). I did not know how to use Next.js though, so the team decided that I should build a tiny single page Next.js app before getting started.
Griffon
I chose to build Griffon, a data structure visualizer that runs a piece of code and visualizes all the runtime changes to some data being mutated by the code. Okay, at first this may seem like a complex thing to build but I made two great simplifications that in theory were supposed to make it easy to build in a few days:
- Griffon would only run JavaScript code.
- Griffon will only be capable of visualizing arrays.
Everything seemed well planned out, but it turned out that I missed a very important detail — Griffon was going to be incredibly boring to build.
You can play around with the live deployment of Griffon here: Griffon (griffon-sigma.vercel.app).
Okay, It Wasn’t Actually 100% Boring
Up until Griffon, I had not implemented a light mode/dark mode feature before in a web app; not even in Spindr! The Next.js template project gets the active theme from the user’s browser preferences and uses that to set its own theme. This is fine, but I wanted a toggle that the user had control over in the app itself. I ended up spending an entire workday on this. After trying many different solutions, I finally opted to have a theme file that was written in TypeScript but was responsible for dynamically inserting and removing some CSS from the head of the page, based on the state of the theme toggle. It was at this stage that I got my first taste of a Next.js idiosyncrasy.
A toggle like this needs to be user controlled. User controlled components in React need to run JavaScript on the client for them to work. Next.js wants to avoid running JavaScript on the client as much as possible because it prioritizes Server-side Rendering and in newer versions, an even more restrictive Server Components architecture. The theme system has to apply to the whole app and at first glance, it looked like I had to opt out the entire application from using Server Components optimization in order to use a theme system such as this. It turned out that I did not actually have to do this. I could cleverly build it in a way such that only components that had to directly read or toggle the theme needed to run client-side JavaScript and all other components that simply displayed content according to the selected theme needed no information about the theme system and so could remain Server Components. This part was almost fun, but that was it.
Everything Else Sucked
At this point I was comfortable with Next.js. I had read a big chunk of the Next.js documentation, most of which I didn’t even need for such a tiny project. I’ve been very comfortable with React since January this year when I read the entire React documentation so that I could build Spindr properly — if you don’t believe me, check out Spindr’s source code here and give it a star if you like it :).
Griffon did not have anything more to teach me about React or Next.js, but I had never written a code editor before, and I was looking forward to it. A quick conversation with ChatGPT and I found a JavaScript package called CodeMirror that gives you a fully functional code editor in the browser without you having to really do anything. No fun there.
How about actually running the user supplied JavaScript code? That has to be fun right? Maybe we’ll have to find a way to talk to the V8 engine or run some kind of portable VM to execute the code on the client side. Nope! Sorry to disappoint you but JavaScript has an “eval()” function that accepts JavaScript code as a string and executes it. Even worse, you can simply append valid JavaScript (wrapped in a script html tag) to the document body and the browser will just execute it, which is what I ended up doing.
const script = iframeDocument.createElement("script");
script.textContent = editor.current?.state.doc.toString() || "";
iframeDocument.body.appendChild(script);
console.log("Executed code successfully.");
Okay, but printing errors to the user has to be at least a little bit challenging, right? Wrong again. JavaScript allows you to overwrite the console.error() API with your own implementation to intercept errors and do whatever you want with them, including displaying them to a user of your web app.
In all fairness, all the things that I’ve said were “too easy” can be a lot improved. I could have spent a lot more time styling the code editor or getting the stack trace to display the correct line number (in the user’s editor) for errors. It just didn’t feel like the experience gained by putting in the effort would be of any value outside the context of the Griffon project because the tools already had opinionated approaches to do these things. Perhaps I chose the wrong project.
Being armed with all this knowledge BEFORE STARTING made me weary of actually writing the code. I say it took me 2 weeks, but it was really just 5 days of grumbling and doing nothing and then the other 5 days doing a tiny bit at a time till I was done. And that brings me to the best part, actually getting myself to do it.
Doing It Anyway
The work was not engaging enough to make me want to do it out of interest. On the day I actually started writing code, I woke up with the same lethargic energy I had all week, not wanting to do anything. But I knew I had to do it. I just needed to figure out how, and the answer was to Project Manage Myself.
The idea was this — since the tasks themselves are not compelling, outlining them, doing them, and marking them as done will create a reward system for my brain to simply want to do the tasks, not because I enjoy them, but because I enjoy finishing them and marking them as finished.
I had previously used the same approach for Spindr. After finishing all the interesting parts with the backend and the frontend infrastructure, I had to do the final HTML/CSS layout and styling of the app. I got bored, and so I Project Managed Myself till it was completed.
In The End, Work Is Work
I became a Software Engineer because I genuinely enjoy it. However, over the years (3 years to be specific), it feels like my biggest lesson so far has been to stop seeing engineering as this beautiful, interesting and challenging thing that doesn’t even feel like a job. Sure, sometimes it may feel like that, but you can’t count on it. Earlier in my career, I used to get borderline depressed during periods when I wasn’t enjoying my job. Now I’m grateful to have developed a much more sustainable perspective on my career as a Sofware Engineer. It is a job. My next projects for NGriid are to simulate energy grid data with GO and to build the DisCo web application with Next.js. Hopefully, those are more engaging :).
Griffon Open-Source Project on GitHub: https://github.com/timi-ty/Griffon.git
Griffon Web App: Griffon (griffon-sigma.vercel.app)
Spindr Open-Source Frontend Project on GitHub: https://github.com/timi-ty/spinder-frontend.git
Spindr Web App: Spindr — Find music you love (*NB: you can now use Spindr anonymously without requesting access or signing up. Just click the link!)
Footnote
If you reached this point, thanks for reading! I’m still making posts following my series on Data Structures and Algorithms that I started here. Please subscribe if you’re interested in what I write!