Home
Software
Writings
Tech note: speed of iteration in programming
in: Diary of a solo dev building a web app
💡
This is a dev diary of implementing Filerion, a web-based file manager for online storage (Dropbox, OneDrive, Google Drive, s3 and more). A tech note is a deeper description of some technical problem I’ve encountered and solved.
If you’re working on software, do you think you’ll complete it faster if:
Obviously, the faster your iteration cycle, the faster you’ll make progress.
Here’s a few tactical examples of how to achieve faster iteration cycle, based on what I do working on Filerion.

The tooling

The tooling can make a big difference.
For front-end JavaScript I use Svelte + vite + Tailwind CSS.
They all contribute to faster iteration cycle.
Vite is a big improvement over previous generation of tools like webpack. It’s several times faster to the point of being mostly instantaneous. It has great HMR (Hot Module Reload) which in some cases allows to refresh the page without loosing the state immediately after saving source file in the text editor.
Svelte allows for faster iteration because there’s less typing than in React or Vue. Less code also allows for faster reading the code.
Tailwind saves time because you don’t have switch back and forth between CSS and HTML file. Once you experience the benefits of using Tailwind classes directly in HTML, it gets very annoying to go back to the old ways.

Seamless deployments

Deploying a new version of your code to production should be a single command and deploy should happen quickly.
I use render.com for Filerion, which makes fast deployments very easy.
I’ve added a -deploy cmd-line argument to server code which triggers a deploy by doing HTTP GET request to my project’s deployment webhook.
Render makes deployments very easy but I had fast deployments even when I was deploying to bare metal servers. It took a few hours to write deployment scripts but it’s very doable.

Debugging helpers

Web browsers have powerful JavaScript debuggers, html, css and JavaScript inspectors but they are manual.
From dev tools JavaScript console we can run arbitrary JavaScript code.
I take advantage of that by exposing functions and variables via window.debug object. I expose them via separate object to take advantage of command completion in dev tools console. window object has so many properties that
What can this be used for?
Imagine you’re storing data in IndexedDB and want to inspect the state of the database. Built-in tools are kind of clunky. You can write window.debug.dumpDB() function that will display the state of the database in the console. Unlike inspecting the db via generic UI, you are flexible to skip some values, have custom display logic for other values etc.
Or you can use it to trigger error code paths. Testing error handling is hard because, by nature, errors happen rarely. If you want to test what happens when e.g. an API call fails, you can add a flag that will artificially introduce an error and expose that flag via window.debg.

Structuring the code for fast iteration

It’s a broad category because of its case by case nature.
The important thing is to always ask yourself: can I do something to increase speed of iteration?
In Filerion I needed a backend API call that would return a listing of files in S3 storage.
Making changes to the backend is slow because:
I made the iteration loop slightly faster by adding a cmd-line argument that would invoke the functionality. I hard-coded S3 configuration for a test bucket. With those changes my iteration cycle was:
No need to start / stop the server. No need to do anything in the frontend.
Another example.
I wanted to test how well my file list would handle lots of files. Instead of creating a test bucket with lots of files and manually navigating there, I created a mocked file system I could mount instantly. In that file system I had a folder with lots of files.
Another example.
I need to create a fair number of dialogs. For example, for file rename operation I need a file rename dialog where the user enters the new name of the file.
In normal operation to trigger rename dialog you have to right-click on a file and pick a context menu item.
When I’m working on a new dialog, that slows me down. Instead I can unconditionally show the dialog, work on the UI until I’m satisfied. Small but meaningful improvement to iteration cycle.
Another example.
Sometimes there’s a bit of upfront work needed but it pays dividends in the future.
I worked on a Go library to extract information from Notion. Thankfully Notion has an internal API that the client uses to fetch data from the server and render HTML in the browser.
To reproduce them in Go code I could spy on those network calls in dev tools but it wasn’t very convenient.
I used Puppeteer ****Node library that programmatically drives browser session and wrote a script that dumps the relevant traffic to files. That allowed me a better, faster way to inspect the structure of network API calls.
I’m confident that If you start asking yourself: how can I achieve faster iteration cycle? you’ll find ways to speed up your programming and ship faster.
Written on Jul 16 2022.
home
Found a mistake, have a comment? Let me know.

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you: