RSSAmplifier

Blog

BinHong Lee's Blog

Recent content on BinHong Lee's Blog

binhong.meRSS feed ↗48 posts

Latest posts

Quick Fix for a Dangerous Session Pattern

With the recent announcement of Meta Account , I wanted to share a small incident on how I helped mitigate one of the more glaring privacy issues that came up during development. As you might know, this is a brand new account type (different from the existing one), so internally there’s a simple function (something like session.isNewAccountType() ) attached to your session for easy reference…

Shifting from Code Writing to Reviewing

When I built GlobeTrotte last year, vibe-coding had just begun gaining traction but I was the “weird guy” who coded everything by hand. I spent a little over 4 weeks building the backend service (Go), iOS app (SwiftUI), Android app (Jetpack Compose), and web (TanStack) all by myself. I like to think that’s pretty fast for an app of that level of complexity. The tradeoff here…

Mentorship

I’ve done quite a bit of mentorship from short term (one session) to long term (multi-year), from high school kids to university grads or even senior engineers, so I like to think I know a thing or two about mentorship. This piece is specifically geared more towards how one should approach a longer term mentorship as a mentor. This is part of a series (The Opinionated Engineer) where I share…

Securing Logged Out Internal Settings

I proposed, built, and maintained the only logged out accessible tooling suite in Meta - which I’ve conveniently called “Logged Out Internal Settings” (hereafter as LOIS). This toolset is still used daily today by employees though it’s no longer as well maintained since I left the company earlier last year. This is part of a series (Project Presentation) where I share…

The Peak Bias

One of the most interesting examples is to look at any average person debating whether Jordan or LeBron is the GOAT. They will inevitably bring up Jordan’s 6-0 finals record as if Jordan only played in the NBA for 6 years. LeBron’s 4-8 record on the other hand is somehow worse than if he never made it to the finals at all (which frankly doesn’t make sense lol). This isn’t…

You Can Be Both

I recently saw a post arguing that exceptional people are rare because they’re so focused on their craft that they skip “bureaucratic bullshit” and “often left other skills to rot”. I left a comment explaining that it’s a 50/50 situation. In this piece, I’ll expand my take on this more in depth. Exceptional people comes in different shapes and forms.…

FB accounts created without Messenger

This was one of my first experience at causing a SEV. I’ve broken production before 🫣 but not bad enough for it to be a SEV. In this situation, millions of new FB accounts were created (over the duration of the outage) without proper messaging inbox thus unable to use Messenger. I’ll dive more into how this happens below. This is part of a series (Project Presentation) where I share…

Incident Review Process

In the previous runbook , I mostly focused on things to do during an incident as it happens. This week, we will focus more on what to do after the incident is resolved. This is an opportunity to look back at what went well, what went wrong, and how we can best prepare ourselves or prevent something similar from happening again in the future. This is part of a series (The Opinionated Engineer)…

Leaked `FakeIncorrectPassword`

It was Thanksgiving day and I was mostly chilling at home scrolling Threads while watching YouTube. I then came across this post: @justinamphlett Found a pretty horrific dark pattern with Instagram. If you try to log in on mobile web, it fails with ‘incorrect password’. I double check… it’s right, it’s just not working. Gave up, installed the app, password is fine. Tried again today just to see……

The Myth of Technical Complexity

I’ve seen multiple different people fail their promotions due to “lack of technical complexity” in their work. While some of this rings true, more often than not, the underlying technical complexity of their work is not properly understood because - ironically - they cut through it smoothly as strong technical engineers. Unless you were doing code / design reviews for them, you…

Shipping a project with -2M MAP

There’s a saying in Meta that ‘Nothing is somebody else’s problem’ but sometimes, it really is. At this point in time, I was working on a growth team whose top-line goal was to grow Facebook MAP (monthly active people). So naturally, it’s surprising for me to have shipped something that directly regressed the very metric the team should be growing. This is part of a…

Communicating Effectively

It’s a common problem at work where you see a problem but you’re having a hard time trying to convince people to support your attempt at fixing it. Worse still, they might not even see it as a problem (or they don’t think it’s something that warrants any attention from anyone). I’m approaching this piece mostly from an “I need my leadership / partners to understand what I do is important”…

GitHub Action Runner Alternatives

Update: This article is now outdated. Check out this newer article instead ! A few months ago, I wrote about my attempt and reasoning behind managing my own fleet of self-hosted GitHub Action Runners . I’ve since learnt that there are quite a few hosted alternative runners that are both faster and cheaper than GitHub’s default runners. This article is just a quick summary of what…

Hidden Privacy / Security Pitfalls

Most software engineers think of this as “someone else’s problem” (usually a privacy engineer or security engineer), but realistically, there’s only so much stuff (bad code lol) they can catch. Especially if you work in some of the more sensitive areas, it’s not realistic to have them do code audits for every change. This means that you as the code author (or…

Sync git submodules with GitHub Action

I needed to share some object code across multiple repos (to ensure the consistency of the RESTful API JSON serialization and deserialization). So I created a dedicated repository where all the shared code lives, then imported it across other repos as a submodule. In this case, I used a library I made - wings - but usually you’d probably use something like Thrift or Protocol Buffers. Another…

Firefighting Heroes

We love celebrating heroes in general. So when a hero shows up to save the day, it’s only natural that we make sure to recognize their contribution. While it might feel counterintuitive, we should strive to not need heroes entirely instead of hoping that next time when tragedy strikes, a hero will turn up once again. This is not to diminish the value of heroes. They still play a very…

Major Incident Runbook

I wrote a similar version of this internally at Meta a few years ago for my org after finding myself in the middle of a few SEV1s in a row – and being consulted / asked for support in other similar situations. I thought this might be something useful to share (as a public version) as well. This won’t be perfectly fitting for all use cases, but having a runbook works as an anchor in the…

Understanding the Value of Dev Tools

I’m largely approaching this from the perspective of building an internal dev tool (since this is mostly where my personal experiences are coming from), especially if you’re someone who wants to build an internal tool but is having trouble framing it in a way where its value can be understood by the decision makers. I’m also excluding situations where you “have to”…

Internal Tooling Ideas

For years, I built and maintained the only logged-out accessible dev tool set / platform at Meta. That earned me some reputation (in a certain circle) of being “the idea guy on internal tools”. Whenever I’m asked about how I keep coming up with good ideas for valuable tools to build, my go-to answer has been “I build tools when I get annoyed while doing my job”.…

Early takes on vibe-coding

I keep hearing about vibe-coding and I’ve always written the majority of code myself. While at Meta, I got a chance to try out CodeCompose. It worked really well as an autocomplete but when it tried to do anything more than 5 lines at a time, it would - on many occasions - commit bugs that aren’t immediately obvious at first sight. Generally, I’ve caught them by looking at the…

Experiment Review Process

Mature growth teams would organize a centralized experiment review meeting as a way to share learnings to a wider audience, consult for feedback / next step recommendations, while also holding engineers accountable for the changes they are attempting to ship. The review sessions should be open to anyone to sign up (presenting their experiments) or to participate in general. However, key decision…

Growth Engineer

While I’ve shipped a lot of growth wins (literally the first line on my resume), I’m actually very far from a prototypical growth engineer. That said, in this piece, I want to explore a bit more into what it’s like being a growth engineer and what makes you good at being one. Growth engineers are generally 1 -> 100 experts instead of 0 -> 1. They fine-tune every little detail by…

Product Growth Opportunities

It’s never easy to come up with new ideas that help with growth, but identifying the problem makes it easier. You’ll notice that for the most part in this piece, I’ll talk about “where” the opportunities are instead of “what” because that’s usually very domain specific and highly depends on the type of problem you ended up needing to solve. This is…

A/B Testing

This is a basic introduction on how to run a good A/B test. A/B testing is a method where your user pool is segmented into multiple groups, allowing you to test different product interactions and understand how these changes affect user behavior. For any metric / data driven team, A/B testing serves as a critical tool in measuring success. This is part of a series (The Opinionated Engineer) where…

No Blame SEV (Incident) Culture

Every time there’s a major outage at Meta, the first question I get from friends and family is usually “did they fire the person who caused it?” which is where I have to explain this concept of No Blame SEV Culture . Especially for an outage so big that a significant number of users are affected, the individual causing it likely does not have ill intent and there are likely…

Code Review Culture

Ask a programmer to review 10 lines of code, he’ll find 10 issues. Ask him to do 500 lines and he’ll say it looks good. - @girayozil Code review is a really subjective thing where each team or even individual runs things very differently. However, a bad code review process can lead to bad code smells and unnecessary tech debt (just ask all the vibe coders out there 🫣). I will try my…

Building a Simple Newsletter Service

When I had the idea on the series about The Opinionated Engineer , I figured maybe that’s something worth setting up a newsletter service over. That said, after some consideration, I just thought that I didn’t need anything too complex and decided to roll my own because “how hard could it be?”. As far as I can tell, I think it’s working fine so far(?) and took me…

The Art of Posting

This piece is specifically more about Meta’s unique culture of “posting” about things but I imagine it can be a useful reference on communication in general. Many people loathe this process and complain about how it’s just a lot of “self-promotion” and while there’s definitely some truth to it, it’s also a valuable communication avenue that you can…

Push Fearlessly with Automated Testing

Conventional wisdom is that writing tests slows you down, because the alternative is that you don’t need to write tests. In fact, Meta (then Facebook) was famously lacking of automated test inline with it’s famous “move fast and break things” mantra. However, from what I’ve seen, I beg to differ. This is part of a series (The Opinionated Engineer) where I share my…

Self-Hosted GitHub Actions Runners

This post will focus more on the “why” and some of the quirks around doing so instead of the “how” since GitHub already have a very comprehensive guide around it. Just wanted to take a bit of time to acknowledge that it’s been almost 3 years since I last wrote a blog post. It’s been a busy 3 years for sure but hopefully I’ll be writing more consistently…

Automated Link Preview Image Card

A while ago, I saw this tweet thread from Simon Willison about how he added social media preview cards to his TILs. He detailed how he did this through a combination of Puppeteer, Vercel, SQLite, and some other stuff I didn’t understand 😅. At that time, I was manually taking these screenshots by hand to be included as part of the commit, which is to say it’s not very efficient.…

Rebuilding Personal Site from Scratch

As time goes on in my journey of experimenting with different technologies on building a web interface, I figured it’s time for my personal site to return to the fundamentals. So I decided to build it with only HTML + CSS with one of the goals being that it should work perfectly fine with JavaScript disabled. Before this, it’s built with Vue. You can still find the source here . Design…

Upgrading Vue TS Project (2.x -> 3.x)

While Vue 3 has been out of beta for quite a while, ( as noted on their website ) a migration build is still a work in progress so the current advice is to stay with Vue 2 if it’s a non-trivial project. I procrastinated on this article for so long that a migration build has since been released. Feel free to check it out here . That said, as Parcel v1 is no longer maintained (and with v2…

PostgreSQL on Azure Pipeline with OSX

While the defacto way of running postgres on Azure Pipeline according to this guide seems to be using the docker image, the MacOS image on Azure Pipeline does not have docker support due to some licensing issue . So instead, this has to be setup and handled manually. We’d use brew here since it comes installed in the OS image and is the easiest way to deal with it as far as I’m aware.…

Ava with Vue (2.x) + TypeScript (and NYC)

When working on a project with Vue (TypeScript), I faced a lot of roadblocks trying to get code coverage to work. The issue is largely covered in this issue thread . Most solutions / workarounds for that seems to revolve around changing the bundling flow with webpack. Considering my lack of familiarity with webpack (on top of my use of scss and pug in Vue files), putting together a webpack config…

Cross Language Object Parsing

I was working on a side project where I had the backend and frontend setup to run on different programming languages. As I was working on it, it started to bug me a little that I have to write the same object / struct and enum for each language in use everytime I introduce a new enum or struct. It can also be confusing / dangerous if I updated one side and forget to update the other. At first, I…

Multi-language Support Build Tool

I recently started learning about Go to find out what’s all the hype about. So I figured what’s a better way than to build a project out of it? As I was setting up my machine and going through tutorials step-by-step, I was slightly annoyed by the fact that the development of Go projects are limited to inside the $GOPATH . Personally, I have all my side projects stored at the top level of the…

Functional and flexible shell scripting tricks

Its 2019 now, who writes shell scripts anymore? Am I right? Well, apparently I do. ¯\_(ツ)_/¯ Shell scripts vs python or perl # There are some good arguments for that here and here which mainly revolve around 2 things: Shell exists in all Unix systems and makes use of system default features. Shell is an “interactive command function” designed to get user inputs during the process of…

Test Driven Development with Alexa SDK

What is Test Driven Development? # According to Wikipedia , it means “Requirements are turned into very specific test cases , then the software is improved to pass the new tests, only.” Basically, you would first have to write the test of the software/feature you are developing before you start working on the developing the software/feature itself. Here are a few more articles on the benefits and…

How to host multiple domain names and projects on one server

I own multiple domain names, and each one hosts a different side project. For the longest time, everything that required ‘hosting’ was hosted on Heroku. But their free tier can be quite limited, it can also get costly quickly if you are paying for each separate project. So instead, I decided to explore putting all of them together using NGINX (recommended to me by Jane Manchun Wong ). Required…

Hosting your own Git server with Gitea

Most people (including myself) host their personal projects on a third-party free Git hosting websites like GitHub, GitLab, Bitbucket etc. While that is sufficient for most people, it is also pretty fun to have your own Git service hosted on your own domain name of choice. While I trust my fellow engineers at these companies, I am using this as a personally backup to those services if anything…

Building a side project over the weekend

Few months ago during my job search, I decided that I want to add some new skills to my arsenal (resume) so I went ahead to build a bill splitting webapp (and the month before, an Alexa skill ). Granted, the backend was built weeks before during a hackathon (shoutout to HackISU ), I’m just focusing on building the UI that makes post requests to the backend. In the process, I also ended up fixing…

Getting started with Travis-CI

What is CI and why should I care about it? # CI stands for Continuous Integration which as the name suggests, is an integrated tests that runs continuously on every time when someone pushes a commit (or mostly when opening a Pull Request ). As for why is it important, it automates the whole testing modules. Ideally, you would still want to test your changes locally before pushing them to remote…

RESTful API with Spark Kotlin

When speaking of building a backend API, the most common tools is either Spring Boot for Java or ExpressJS for JavaScript. Even for Kotlin, Spring Boot and JetBrain’s own ktor is the usual option to go with. But today I’ll explore into the less popular option of spark-kotlin. Disclaimer : I am not in anyway affiliated nor do I work at the project. I just simply stumbled upon it and started using…

Being lucky

Ah, you’ve graduated. Now what? Oh right, still no job offer! *panics* As an international student, I have come across hundreds of guides on “how to land an interview”, “how to get a job”, “how to solve DSA questions” etc but almost none of them were specifically written with an international student in mind. I’m not here to dismiss the quality of such guides but rather, to be an add-on (or plugin…

I could become you tomorrow and no one will know

Backstory # I lied, but maybe someone else could. If you didn’t know already, Malaysia just suffered possibly its largest data breach ever with personal data of millions of Malaysians (including your full name, IC number, phone number and home address) up for grabs as long as the price is right. If you are not freaked out yet, you should be and I’ll tell you why. I don’t think many people…

Use Terminal in Windows with Style

When the Linux Shell in Windows was first released, I used it and didn’t quite like it. Fast forward a year later, I heard it is a lot better now (also the fact that my familiarity with terminal commands improved helped) so I decided to give it another try. It is a really fun experience so far. In case you haven’t install the Windows Subsystem for Linux (WSL), follow this step-by-step guide by…

GitHub Action Runner Alternatives

Last Updated: Apr 25th 2026 A while ago, I wrote about my attempt and reasoning behind managing my own fleet of self-hosted GitHub Action Runners . I’ve since learnt that there are quite a few hosted alternative runners that are both faster and cheaper than GitHub’s default runners. This article is just a quick summary of what I’ve found. Hosted Runners # These are essentially…