Feb 26, 2026

DevStorage - Chrome Webstore (simple quick tool for web dev)

DevStorage Is Live

Short announcement post

I am excited to share that my new Chrome extension, DevStorage, is officially live.

This started as a small side project. Not a startup idea. Not a big launch plan. Just a tool I built because I kept running into the same annoying workflow issue during local development.

If you have worked on modern web apps for a while, you probably know the feeling. You are testing authentication. You are toggling feature flags. You are simulating user states. And at some point, you end up deep inside Chrome DevTools trying to inspect or edit localStorage.

It works, technically. But it is not smooth.

You switch tabs. You open Application. You expand Storage. You scroll through keys. You copy and paste JSON. You clear everything when you only meant to delete one item. Then you start over.

After repeating that cycle enough times, I decided to fix it for myself. That is how DevStorage was born.

Chrome Web Store listing: DevStorage

What DevStorage does

DevStorage is a lightweight Chrome extension that makes working with localStorage faster and less frustrating.

It lets you view keys clearly, edit values quickly, remove specific entries without wiping everything, and clean up storage without digging through DevTools every time.

The goal was simple: reduce friction.

I did not want to replace DevTools. I just wanted something that feels more direct when you are in the middle of debugging and need to adjust storage quickly.

When we are building SPAs, storage becomes part of the debugging loop. Tokens live there. Feature flags live there. Temporary state lives there. Having fast access to that data saves time, especially when you are jumping between environments or testing edge cases.

Why I decided to ship it publicly

Originally, this was just a small internal helper. I built it to make my own workflow cleaner.

But after using it for a while, a teammate asked how I was managing storage so quickly. That is when I realized it might actually help other developers too.

Shipping it publicly forced me to polish things properly. Clean up the UI. Double-check permissions. Make sure performance stayed tight. Write clearer descriptions. Remove things that only made sense to me.

That process alone was valuable. It reminded me that even small tools deserve thoughtful design.

What I focused on while building it

I kept the scope intentionally narrow.

The first version does one thing well: it gives developers clean, fast control over localStorage.

I avoided adding too many features. No analytics. No cloud sync. No complicated dashboards. Just a focused interface that shows your storage clearly and lets you manage it without noise.

One thing I learned is that simplicity takes effort. My early versions had more buttons and more UI states. It looked powerful, but it felt heavy.

So I asked myself a basic question: what do I actually use every day? Anything that did not serve that answer got removed. That decision made the extension better.

What building this taught me

Even though this is a relatively small extension, it reinforced a few lessons for me.

Chrome extension architecture matters more than you think. Understanding permissions, background scripts, and storage APIs early saved me from messy refactors later.

UI clarity is harder than writing logic. The functionality worked early on. Making it intuitive took longer.

And most importantly, developer tools should feel invisible. When you click the extension icon, you should not have to think. You should just see what you need and move on.

That was the benchmark I kept testing against.

Who this is for

DevStorage is useful if you regularly work with localStorage during development.

If you debug login flows, test feature flags, simulate user states, or often need to reset specific keys without clearing everything, this will probably save you time.

If you rarely touch browser storage, you might not need it. And that is fine. I would rather build something focused that genuinely helps a specific group of developers than something broad and generic.

What is next

Now that it is live, the real work begins.

I am paying attention to feedback and watching how people actually use it. There are ideas I am considering, like adding search, supporting sessionStorage, or allowing export and import of storage snapshots.

But I do not want to guess what developers need. I would rather improve it based on real workflows.

If something feels awkward or unnecessary, that is exactly the kind of feedback I want.

Final thoughts

DevStorage started as a small fix for a daily annoyance. It turned into a public Chrome extension that I am genuinely proud of.

It solves a real problem in my workflow. That alone makes it worth building.

If you spend time debugging browser storage, give it a try. And if you are building small tools of your own, I would encourage you to ship them. You do not need a huge idea to create something useful. Sometimes removing a tiny bit of friction is enough.

If you try DevStorage, let me know what you think. I am always open to improving it.

Feb 3, 2026

Simple systems just survive longer

Why simple systems survive longer

Simple systems tend to last because they're easier to maintain, explain, test, and recover. Complexity can create short-term speed, but simplicity builds long-term trust.

  • When a system grows, break it into smaller chunks (modules/services) so changes stay local and safer.
  • Give each chunk a single purpose and clear boundaries, so it can be understood and evolved independently. (Not "isolated forever" - just intentionally scoped.)
  • Keeping chunks small and maintainable is one of the most reliable strategies in system design - not a universal law, but a principle that keeps paying rent.

Keep it small. Keep it clear. Keep it alive.

Jan 20, 2026

Lat/Lon vs Lon/Lat in GIS: Why the world wants to keep them so confusing?

Every time I touch GIS coordinates, I hit the same trap: sometimes coordinates are written as latitude then longitude, and sometimes they are longitude then latitude. Both look valid, both are common, and the mistake often does not throw an error. Instead, the point quietly lands in the wrong country, or worse, in the ocean.

This post is my quick reference: first the mental model (why the order differs), then the technique I used in my own project to stop the confusion from spreading.

A picture of the classic bug

When lat and lon get swapped, a real point often ends up "somewhere in the ocean." (If you are adding an image here, upload it to Blogspot first, then insert it into this section.)


A red GPS map pin floating alone in the ocean, representing swapped latitude and longitude coordinates.
A swapped coordinate pair often becomes a pin in the ocean, with no error messages.

The two worlds that collide

There are two different coordinate traditions that keep clashing:

1) Human geography tradition: (latitude, longitude)

Most people learn latitude and longitude in school as:

  • Latitude: north or south (up and down)
  • Longitude: east or west (left and right)

So a location is commonly written as:

  • (lat, lon)

Example for Kuala Lumpur (approx):

  • (3.1390, 101.6869)

This feels natural because we say "latitude and longitude" in that order.

2) Mapping and GIS tradition: (x, y) which becomes (longitude, latitude)

Most mapping engines and GIS systems think in Cartesian terms:

  • X axis is horizontal
  • Y axis is vertical

When coordinates are mapped into (x, y):

  • X corresponds to longitude
  • Y corresponds to latitude

So in GIS engine terms the same point becomes:

  • (lon, lat)

Same Kuala Lumpur example:

  • (101.6869, 3.1390)

This is not random. It is the consistent "x first, y second" rule.

The most important practical rule: GeoJSON is strict

If I am dealing with GeoJSON, there is almost no debate:

  • GeoJSON Point coordinates are always [longitude, latitude]

Example:

{
  "type": "Point",
  "coordinates": [101.6869, 3.1390]
}

If I swap them to [lat, lon], the data is still valid JSON, but the point ends up in the wrong place. That is why this bug can be so annoying.

Databases and spatial functions usually follow x, y too

Many spatial databases and geometry constructors follow:

  • (x, y) = (lon, lat)

Even if a library accepts different input types, the underlying geometry model is still "x then y."

Why this confusion keeps happening

  1. People say "lat/long" in that order for decades, so apps and UIs follow it.
  2. GIS engines and geometry models prefer "x/y," which becomes lon/lat.
  3. Some libraries try to be helpful and auto-swap depending on context.
  4. Some standards define axis order, but older systems may ignore it, so behavior varies.

The technique that stopped it in my codebase

The conceptual explanation is useful, but it does not prevent bugs. What actually helped was enforcing one simple rule: never manually swap coordinate order scattered around the code.

Instead, I introduced a single conversion layer that acts as the boundary between:

  • Frontend map UI (Leaflet), which naturally works with (lat, lng)
  • Storage and backend models, which I keep aligned to (lng, lat) / (x, y)

Concept: "Coordinate conversion layer"

In my project I called it CoordinateConversionService, but the important part is not the name. The idea is: create one dedicated place that converts between formats, and make every other part of the app call into it. This turns a messy convention problem into a controlled interface.

Typical responsibilities of this conversion layer:

  • Convert Leaflet coordinates (lat,lng) to GeoJSON coordinates (lng,lat) for saving.
  • Convert GeoJSON (lng,lat) back to Leaflet (lat,lng) for rendering.
  • If the backend stores GPS as x,y, keep x=lng and y=lat consistently.

Quick example

// Leaflet UI (lat, lng)
[2.765207, 102.904707]

// GeoJSON storage (lng, lat)
[102.904707, 2.765207]

// Backend GPS model (x=lng, y=lat)
{x: 102.904707, y: 2.765207}

Concept: "Update direction guard" (to avoid feedback loops)

A second practical issue appears in map editors: there are two ways a coordinate can change.

  1. User drags a marker on the map, and the form fields must update.
  2. User edits the coordinate fields, and the marker must move.

If both directions trigger each other, the app can end up in a loop or jittery updates. The simplest fix is to track the source of the current update.

In my project I used a flag named isUpdatingFromMapDrag. Again, the name is not the point. The concept is: when the map drag handler is actively pushing values into the form, temporarily ignore form-driven map updates (or vice versa).

This guard makes the editor stable and prevents accidental recursion.

A small but important rendering detail

When only a marker position changes, I update the existing marker in place (for example, Leaflet's setLatLng) instead of clearing and re-adding layers. This avoids flicker and "marker disappeared" bugs.

My cheat sheet

  • Human-friendly display: often (lat, lon)
  • GIS engine, GeoJSON, storage: usually (lon, lat)
  • Practical rule: keep one conversion boundary and forbid manual swapping elsewhere
  • Editor stability: use an update-direction guard to avoid feedback loops

Final note to future me

If a point suddenly appears in a completely wrong place and there are no errors, check coordinate order first. If the codebase has a conversion layer, the bug is usually that some new code bypassed it.

Jul 30, 2025

Fixing WSL2 "Access Denied" Error on Windows After Reboot

If your WSL2 suddenly throws an error like:

Failed to attach disk 'F:\ext4.vhdx' to WSL2: Access is denied.
Error code: Wsl/Service/CreateInstance/MountDisk/HCS/E_ACCESSDENIED

This usually happens because Windows lost permissions to access your WSL2 disk image (ext4.vhdx). Here's a quick fix:

Step-by-Step Solution

  1. Open PowerShell as Administrator.
  2. Run these commands (replace F:\ext4.vhdx with your actual VHDX file location):
    $VhdPath = "F:\ext4.vhdx"
    wsl --shutdown
    icacls $VhdPath /grant:r 'SYSTEM:(F)' 'Administrators:(F)' /inheritance:e
    icacls $VhdPath /grant '*S-1-5-83-0:(M)'
    attrib +R $VhdPath
  • This sets permissions properly for SYSTEM, Administrators, and WSL2 Virtual Machines.
  • The attrib +R command makes the file read-only, preventing antivirus or backup software from interfering with permissions.
  1. Restart WSL2 by simply running:
    wsl

Confirm the Fix

To double-check permissions:

icacls $VhdPath

You should see entries for SYSTEM, Administrators, and a group SID starting with S-1-5-83-0.

That's it! Your WSL2 environment should now work smoothly after reboots or updates.

Jul 9, 2025

Update: Newly Sold Unit Indicators in Teduh Unit Counter

Back in May, I introduced a Chrome extension called Teduh Unit Counter, built to help users track property unit availability more efficiently while browsing the Teduh housing platform.

After receiving helpful feedback from users monitoring multiple projects, I've added a new enhancement that makes it easier to identify recently sold units, without needing to manually compare listings each time.

What's New: Highlighting Newly Sold Units

The latest update introduces the Newly Sold Unit Indicators feature. It flags units that have recently been marked as "Telah Dijual" (sold) since your last visit. This makes it faster to identify changes, especially for users keeping an eye on specific buildings or units.

Newly sold unit indicator


How It Works

1. Automatic Comparison

When you load a property page, the extension checks for any units that have changed from "available" to "sold" by comparing the current page data with previously stored unit status.

2. Data Storage

The newly sold unit data is saved in Chrome's localStorage under the newlySoldUnits key (in short, what it means is that the data persists even after the browser is closed, and no data is being sent to external servers, no privacy concerns). Each entry contains:

  • unitNumber: The unique identifier of the unit
  • dateMarkedSold: The timestamp when the unit was marked as sold (stored in ISO format)

3. Visual Highlight

To make changes easier to spot, units newly marked as sold are styled with:

  • A light yellow background
  • Red text and a yellow border

4. UI Panel Updates

The extension popup now includes a dedicated section showing:

  • The total number of newly sold units
  • A list of unit numbers
  • The most recent sold timestamp, e.g., "July 2, 2025, 14:30"
  • A "Mark as Read" button to clear these highlights after reviewing

5. Persistent Across Sessions

All data remains intact across browser sessions. When you revisit the same project, you'll still see what was previously marked as sold, until you manually clear it.

Why This Matters

Tracking changes in property listings can be tedious, especially when revisiting projects to check what's been taken. With this new feature, users can:

  • Save time by focusing only on new changes
  • Improve clarity with color-coded visual indicators
  • Make informed decisions with real-time updates

What's Next

This update is part of a larger plan to make the extension more intelligent and intuitive. Some upcoming ideas:

  • Optional desktop notifications for sold updates
  • A unit history tracker
  • Multi-project summaries

If you're using the extension and have ideas to improve it, feel free to reach out, feedback is always welcome.

Recap: Key Features in This Update

  • New Newly Sold Unit Indicators feature
  • Tracks changes in unit status between visits
  • Stores sold data in localStorage with timestamps
  • Visual highlight with yellow background and red text
  • Extension UI shows sold unit summary with clear date/time
  • Data remains available until manually cleared

You can install or update the extension from your Chrome browser as usual. Stay tuned for more updates in the future. If you have already installed the extension, it should automatically update to the latest version.