My Notes



Do not optimise for something we do not need. Especially the “not ever” ones.

The “not yet” ones are trickier, because we will be temped to “might as well optimise for it now”. But what if eventually we learn that we do “not ever” really need it?

It depends case-by-case when to postpone and when to do it now. Understand the trade-off. And decide purposefully.

#design #learningorg

Misleading preview

I used Flutter in the past to develop an iOS app. But I want to try SwiftUI for a new project, so I am now learning SwiftUI development with XCode.

XCode has this nice Preview feature. It is slower than I expected given I have an M2 processor in my laptop. (Okay it is a complex and powerful IDE, so maybe as fast as Sublime Text is not realistic. But it should not feel slower than VS Code.)

The Preview helps give useful feedback loop. Most of the time.

Today, I spent a lot of time trying to debug a “Preview Crashed” error and went nowhere. Out of ideas, I decided to just build it and run the app on the Simulator. I wanted to know if I would get a different error message than the one I got in XCode.

Guess what? It runs without any problem in the Simulator. 🤔

Oh well, I will take any small win I can.


Privacy-preserving email image loading

Proton Mail now can load image in privacy-preserving manner. “Senders will not know if, where, or when you opened their emails.” This is a great feature!


NodeJS installs a lot of files

I just re-installed NodeJS. And here's what I got.

🍺 /opt/homebrew/Cellar/node/19.0.1: 1,991 files, 50.9MB

That is a lot of files.


Static site: old way vs new way

The popular new way for hosting “static site” is using the JAMStack platform. I have used others in the past, but currently I have been using Cloudflare Pages for two years exclusively.

It is good, but it has its drawbacks.

Every new post / page that I push (via git) will trigger a new build. Sometimes the build fails.

I found it bizarre that even pure static hand-coded HTML still requires a build. And when a build fails, by default, I got no alert, so I was sometimes surprised when I happen to go to the website and saw that the morning's push did not show up.

Maybe there is a way to get an alert somewhere along the workflow.

Each build takes time.

It's gotten faster, but still time to spend waiting, since I need to check that the build succeeds.

Compare to the old way

The new way is not always better than the old way. Just a different set of trade offs.

The “old” way, which is still popularly used today, that I did was using an HTTP server (Caddy, Apache, NGINX, Lighttpd, etc) + static files.

To deploy, all we need to do is upload the static files to the server and the new content is instantly up. It is actually very convenient, but it has its drawbacks too.

Security is on us.

If we misconfigure the HTTP server or late in patching the OS, then that opens up risk. So we need to have the process to keep them always updated.

On a JAMStack platform-as-a-service / PaaS, we focus on our app's / website's security only. The rest is taken care of by the platform security experts.

Load balancing is on us.

It is up to us to set load balancing up front and this costs extra. Plus it requires additional skill.

And I think this is the allure of the new PaaS, someone will take care of the auto-scaling for us.

It is a choice

I am in the beginning stage of setting up a new project. For some reason, I was drawn to retry the old way of doing things and rented myself a server.

There are inconveniences. But it is not rocket science. And there is something in the familiarity of the process and the simplicity of it that made me think: this might be good for me in the long run.

Or maybe it was just nostalgia.


Tech stack decision making

Photo: unsplash

At the start of building my previous startup attempt, I made bleeding-edge decisions (at least bleeding-edge to me personally, since I “bled” in the process).

You probably are familiar with “tech debt” and “choose boring technology”, but this post is not about those. I am happy with the technical stack that I ended up shipping and this post is about the journey and the decision making process.

A common thread is this: I prioritised business goal over technical familiarity.

Old history

In 2011/2012 period, I tried building a startup on the side. Go language was pre-1.0, but I chose Go over the languages that I already knew at the time: Python and Ruby.

My business goal was to have a product that would not cost prohibitively to run with fast performance. Server cost back then was not as affordable as now, so Go ticked the boxes for me, although that meant I had to learn a new language. Fortunately, Go was really easy to pick up and be productive in.

Recent history

Fast forward to end of 2021 / early 2022 – a different startup attempt. I wanted to use Go again and this time my business goal was to minimise operations and this led me to 'serverless'.

There were several options for serverless + Go and Google Cloud Functions gave me a fairly balanced trade-off. Initial trial worked well, but then I found out that the networking side of thing added operational friction to get going.

At around the same time, I was experimenting with Cloudflare Workers and Pages. They worked beautifully and simple to set up. But I was not comfortable with Javascript (JS). It was possible to use another language in Workers and transpile it, but that would not work too well for me either.

Another consideration was that for the functionality that I wanted to build on the client side, the product would have better interactivity if I used a lot of JS on the browser. And to build that, I had to upgrade my rudimentary JS skill.

So if I had to use a lot of JS anyway, I might as well switched to JS and Cloudflare. And with that, I focused backend development in JS for Cloudflare Workers and frontend development in JS + React for Cloudflare Pages.

When I had built sufficient functionality for a minimum viable product (MVP), I had my doubts about the sustainability of what I had built. Was it robust enough to meet my goal of minimising operations?

Uh oh

At about the same time, the React library that I depended on switched from JS to Typescript (TS) in its new version. My web app could still work with the old version, but that got me into investigating TS.

Interesting. How hard can it be to rewrite into TS? (*)

I rewrote the code that was relevant to the aforementioned library from JS to TS in roughly a week. Given that I was learning as I stumbled along, I was happy with the one week delay.

And then I sort of “saw the light at the end of the tunnel”: migrating my app from JS to TS would minimise potential operations issue for me.


The business trade off was clear, improving the robustness of the product can pay back for itself in the long run, despite the schedule change.

So I rewrote the MVP in TS while deprioritising the rest of the product backlog. Unexpected benefit was that I was more productive coding in TS than when I was in JS.

A bit later in the project and being more comfortable with TS, I could confidently refactored the codebase into microservice-like model.

Additional tech

Data was at Supabase. Documentation was a bit lacking in a handful of places, but their product served me really well.

Cloudflare had everything else I needed but I added AWS Cloudfront as my image CDN and Imagekit to serve video. I added Cloudfront because Supabase object storage was in AWS and it was simpler to set up than Cloudflare. I used Imagekit, because it was also easier to use than Cloudflare. I wrote about Imagekit here.

That's it for the most part. Happy building!


(*) Related but completely different context: How hard can it be?

The Great Bubble Barrier

The Great Bubble Barrier is a cool idea! Below video gives a brief overview of how it works and its benefits.

Visit their website to learn more:

#reblog #design

Tiny Rocket

Few months ago I was revamping my hand-coded website project and learned of a new framework called Astro. It was still in beta at the time, but it fits my needs well, so I decided to use it.

A few things from Astro's default set up did not suit my liking, so I twiddled with it and shared the template / theme to Astro theme library and called it Tiny Rocket.

Since then, Tiny Rocket has gone through several iterations and has a few useful features to help Astro users get up and running with their website project.

  • Paginated blog
  • Site search
  • RSS feed
  • Web map
  • Self-hosted font

Check it out and please star the GitHub repo to help more people discover it. Thanks.


Goodbye Microsoft OneDrive

I was an early adopter of MS OneDrive and never had any concern with it. Until a few days ago.

It was the first time I needed to download a folder containing files, since I did not have OneDrive synchronised with the machine's storage; it's not my main machine.

And OneDrive had NO option to download a folder as-is when connecting to it via the browser (nor through the app – which I installed to check).

OneDrive would always try to compress the folder into a zip format while downloading. There was no other alternative aside from downloading the file one at a time.

Even on very high broadband speed, the effective download time amounted to 120'something kb/s. This translated to hours for my download.

And nearing the end of the download, it FAILED and I had to redo it. To avoid another fail, I ended up downloading in pieces.

Oddly enough, if using the OneDrive Windows app, it will queue up the downloads, i.e. ONLY one download at a time. It cannot do something as simple as simultaneous downloads. Seriously. Doing it from the browser, it acts like typical browser download, except for the really slow zipping while downloading part.

My take on this is that I cannot rely on Microsoft OneDrive to be my online storage. Goodbye OneDrive.


Learning to add video

I am not a video person. In the past few days I have been working on adding a demo video onto my project's landing page. And I learned a few things.


Initially there was a part of the video where I wanted to obscure the user logging into the system. This led me down the rabbit hole of choosing a video editor that I can understand and use in a short time. I found a couple of video editors that I was able to use: one is commercial and the other is kdenlive.

I got something working in both, but changed my mind about showing the login screen, so I dropped that section.

And without the need to obscure part of the screen, I found out I could just use Quick Time Player. It has only basic editing capability, but it gets the job done for now.


I wanted to get this up and running fast and the fastest way is to use third-party. I tried YouTube and the process was smooth. Nice.

The downside was that I could not figure out how to make the video showing in portrait shape, which is less ideal for my specific purpose. So next I tried Tiktok. Wow, the process is easy with Tiktok. Fantastically easy.

In manual testing, the website felt okay, although the video div was lagging, but everything else was as snappy as usual. So I went into the weekend feeling relieved.


Come Monday, I was working on something unrelated and clicked on Google Page Speed Insights not expecting anything. To my surprise, I found out the landing page performance had dropped by a wide margin.

Aargh. The script tag that came with Tiktok embed seemed to be the main culprit in a landing page that, so far, has zero JS.

I don't think it is a huge deal at this stage of the project, but decided to investigate hosting the video myself.

I thought about Cloudinary – they have a generous free tier which is ideal for a starter. And then I remembered I looked at in the past and it turns out they just started beta offering for video.

I gave imagekit a spin and was able to host the video on imagekit and embed it on my landing page.

I deployed it and then checked Google Page Speed Insights again. And the landing page is back in good standing. 👍🏽