Done Avoiding the Inevitable
So this has been sitting in the back of my mind for a while. There are certain trends I have been vehemently avoiding for a while and need to just realize that these trends aren’t fads. They’re permanent fixtures that I should include as part of the coding I do.
Javascript is Inevitable
For the longest time, I avoiding doing javascript other than what was strictly necessary. I would turn my nose up at the fact of using javascript for something other than basic interactivity. Of course there were plenty of web frameworks I saw taking off over the years. None more so than React, but I always considered them “un-optimal” for projection software.
But then there’s VSCode, the popular editor (I use Codium), written as an Electron app. Yes, a bit bloated for memory performance and install size, but it’s getting the job done more effectively than other IDEs like Visual Studio.
Nothing exemplifies this more than my choice to use Flutter for my personal project.
The Framework Decision for Reckoner
Back in the day, I had just left a job where I was burned out for a more chill job. What I quickly found was that I blazed through the work quickly and was told by to chill out by friends and coworkers. I was still replicating the bad behaviors. Instead of chilling, I found a personal project to work on.
I’m a bit of a finance, open source, and data privacy nerd. I couldn’t find a good financial tracker that was device local first and supported device synchronization. Thus I decided to build my own.
I spent weeks evaluating frameworks and deliberating. I wanted a single codebase which was cross platform and had good Linux support. The only three that were under consideration where C# based (Xamerin at the time), a Javascript Framework (Dual React Native and Electron), or Flutter. At the time Flutter seemed to be the clear winner. Xamerin had no Linux support and was thus ruled out. Javascript would require two different build targets with radically different code to make it work.
At the time I was smitten with the way Flutter worked. The reactivity system and component based system seemed to click for me.
Flutter Cracks
I’d say the first cracks were when I found out that the SQL ORM I was using, Drift, supported the web as a build target. However, it was always a bit compromised. It didn’t have the same performance as the native builds and the codebase had to have conditional importing and handling with the web target.
The bigger issue though, came when I started to increase the release cadence. I had a complex build system to release the app for Android, iOS, Mac, Linux (x86 and ARM) via Flatpak, and web. The Linux distribution was a complex affair that required me to build the Linux bundle, publish the release, and then create a PR to release to Flatpak.
Finally, I made a decision for my sanity. I dropped support for the desktop build targets and designated the web build as the default for desktop users. At the same time, I had been improving tooling on web to support building web workers and WASM based OPFS SQLite handling which drastically improved the web performance. There is still the issue of Flutter’s heavy web renderer, but the backend performance issues have all been addressed.
JS at Work
Finally, I headed up an evaluation of frontend frameworks for use with building a new desktop application. We had previously used PySide6 to create a desktop app. However, security concerns required us to build it into a standalone executable. We eventually found Nuitka, but builds are fragile and often are flagged by Windows Defender as malware.
I evaluated several different frameworks. I settled again looking at C# (Avalonia and Uno), Flutter, and Electron. C# would’ve been feasible, but the group had basically no experience with C#. Same for Flutter and I would’ve pushed it harder, but many Flutter dependencies rely on symlinks which is only available in developer mode on Windows which IT wouldn’t grant me. Thus Electron was chosen for the framework.
The result? We were able to ship more code with more stable changes quickly using React in Electron. Again, many decisions for this UI were made using the most popular frameworks available since those have the largest community support.
Actually using a JS framework at work has convinced me that this can be used for anything. Additionally, when looking at the runtime performance, JS is generally the most performance dynamic language and can come close to some VM based languages (Dart, C#, Java).
AI is Inevitable
For the longest time, I had considered AI a toy which burned energy in exchange for making poor programmers marginally better. I still think the current use is unsustainable, but I see how this is going to be a practically required tool in the future.
My First Experience with AI
My opinions of AI were before this year were largely formed ~2 years ago. At that time I tried running a local model and trying the code completion tooling. At the time I only use local AI since every AI tool at the time would train on the code and prompts you sent to it. I found the experience underwhelming, actively hindering, and burned through my laptop battery.
First Useful AI
It was after CodeMash this year that I was able to see the utility of AI. I visited the AWS booth and they were touting their AI editor, Kiro. As part of attending the conference, I was given 10K free credits to try the editor out. I waited a little bit and then found out I could turn off telemetry and prompt learning and decided to try it out.
Similar to my first experience with Flutter state management, this tool just clicked with me. In particular Kiro has a strong spec driven workflow that helped me guid the AI tool. It was able to help me figure out how to incorporate the Android Workmanager into Reckoner. I had been beating my head against the wall with this change, and was able to figure it out in days with AI. I then started to use it as much as possible before my free credits expired and was able to additionally incorporate the change to add web worker parallelism into the web build.
Current AI Use
I have moved away from Kiro and am using Ollama Cloud. I just trust the service more than Amazon when they claim to not train against your prompts. Ollama Cloud is just paying for using the open source models, they don’t have a model of their own as a conflict of interest.
I have settled on OpenCode as the primary AI tool I am using to use tools with AI. I’ve also been experimenting with spec driven developer with open source guided tools like OpenSpec. However, I will try to build my own agents and tools in OpenCode as well. The AI coding sphere seems pretty split on whether spec driven dev is worth it or not (pro is that it guides AI better, the con being it might just be unnecessarily burning through tokens).
I have additionally been pushing AI use at work. The nature of my job means that we don’t have access to public models, but we have been allowed to run local models off a small selection of our server GPUs. I’ve been learning about the different character and utility of different models in the process.
So What?
All of this is to say, I am re-evaluating how I am doing development and the tools I am using for my personal projects. Over this year, I plan to do the following.
The New Reckoner
I plan to rebuild Reckoner as a PWA first with a JS framework. I am using a bit of a stronger ideological stack in that I want a JS framework that isn’t backed by big tech. Thus my options are (in order of popularity) Vue, Svelte, and Solid. There are, of course, other frameworks. These are just the select few I’ve decided to consider. Vue has been ruled out as the Virtual DOM removal is still in alpha. Svelte is better optimized for static sites instead of dynamic apps like Reckoner. Thus Solid is the clear choice here. It doesn’t hurt that is uses JSX like React that I have been using.
Additionally, I will program a lot of this using agentic coding in OpenCode. I want to use this rebuild to focus on making sure the codebase is more tested than OG Reckoner was. This will allow me to hone in my agentic coding workflow.
Lessons Learned
I think it’s important to take stock of the lessoned I learned from this. I waited waaay too long before embracing JS as a frontend framework. Part of it was just the nature of my jobs where I became more backend focused just when JS frameworks were taking over the world.
I think it’s good to have a health skepticism of a new piece of technology. People tend to hype up and jump on trends well before they are ready or proven. With AI, I think we’re at the point where it is going to be a permanent fixture. It’s not going to be as good as hyped, but it provides real value. Pretending it doesn’t and being a proud “anti-AI” person may give you a good ideological feeling, but there are ways to use this without continuing to feed the big tech players.
In my experience local models trail behind frontier models by 1-2 years or so. You’ll be better off and have more money using those models instead of the exorbitant prices that Anthroic and OpenAI (what a misnomer) are charging. I’m waiting for the shoe to drop when the investor money runs out. Then people will need to figure out how to be productive with the local models. We already see hints of that happening with newer models rapidly increasing cost with minimal improvement or sometimes worse performance.