DevIdiot!
I built a browser-only NOC request letter generator for UAE telecom (du & e& formats)
In the UAE, things like cancelling a phone contract or requesting a plan change are not done with a phone call alone - the operator wants a formal written request letter, in a specific format, with specific lines. Get the format wrong and the request quietly bounces.I kept rewriting the same letter for friends and family, so I turned it into a small tool.https://telecomdeskuae.com/noc.html How it worksThe core is a small template engine, not a form-to-PDF converter:Audience template (person
Local-first photo editing in the browser: what the pipeline split actually looks like
If you build anything in the browser that touches user photos, you eventually run into the same wall: the cheap operations want to be local, and the expensive ones cannot be.Here is how I ended up splitting the pipeline, and the constraints that forced each decision. The cost asymmetry nobody mentions in the docsA brightness slider is a loop over pixels. A crop is a coordinate transform. A JPEG re-encode is a codec call. None of these need a server, and if you put them behind one you have a
How We Built a 100% Client-Side C2PA Metadata Scrubber, Invisible Unicode Cleaner & NotebookLM Bundler in the Browser
As AI workflows matured in 2026, three technical bottlenecks hit developers, creators, and enterprise teams simultaneously:Binary C2PA & JUMBF Provenance Flags: Even minor edits using Photoshop Generative Fill or Lightroom AI Denoise embed a cryptographic urn:c2pa JUMBF box and IPTC trainedAlgorithmicMedia tag—causing LinkedIn, Instagram, and TikTok to slap an automatic "Made with AI" badge on brand assets.Hidden Zero-Width Unicode Characters (U+200B, U+202F): Copying text from LLM chat inte
The DELETE Route Checked Ownership. GET Didn't. (BOLA Write-up)
A BOLA vulnerability in OopsSec Store's wishlist API lets any logged-in user read anyone else's private wishlist, including an admin one that contains the flag.The wishlist API on OopsSec Store authenticates users but never checks whether they actually own the wishlist they're requesting. Any logged-in user can read any wishlist by changing the ID in the URL. Table of contents Lab setupFrom an empty directory:npx create-oss-store oss-storecd oss-storenpm startOr with Docker (no Node.js
Build a Voice-Powered Accessibility Tool
Why Voice‑Powered Accessibility MattersIf you’ve ever watched a video with no subtitles, tried to read an article on a mobile screen, or used a screen reader that sounded robotic, you’ll understand how frustrating it can be when the technology that should help falls short. Voice‑powered accessibility tools—think screen readers, text‑to‑speech (TTS) assistants, and voice‑controlled navigation—can make a world of difference for people with visual impairments, reading difficulties, or motor c
I deleted my Rust helper and moved zip extraction into the browser. Here's what it cost.
A couple of weeks ago I wrote about LinkUnzip, a Chrome extension that pulls files out of a zip on the internet without downloading the zip. It reads the zip's table of contents with an HTTP Range request, then downloads only the bytes of the files you want and writes them straight into a folder.The idea worked. The install didn't.To write files into a real folder, version 1.0 needed a small helper program on your PC. I wrote it in Rust and the extension talked to it through Chrome's native mess
How to Build a Pronunciation Guide App with AI Voice
Why a Pronunciation Guide App?If you’ve ever tried to learn a new language, you know how frustrating it can be to hear a word in a textbook and have no clue how it actually sounds. A pronunciation guide app solves that problem by turning any piece of text into a clear, natural‑sounding voice—ideally one that matches the learner’s target accent. With today’s AI‑powered text‑to‑speech (TTS) services, building such an app is easier than ever.In this article you’ll get a step‑by‑step walkthrou
Two .npmrc Lines That Stop npm Supply Chain Worms (Tested on npm 10, 11 and 12)
Every npm install trusts hundreds of strangers at once, and the worms going around npm this year exploit two things in particular: lifecycle scripts that run during the install, and versions published minutes before you pull them.So the defense is two settings. Refuse dependency install scripts, and refuse any version younger than one day. npm 12 does the first by default. On the npm bundled with Node.js today, add this to the project .npmrc:ignore-scripts=truemin-release-age=1Either line alone
Cannot Read Properties of Undefined (Reading 'bind'): The Fix
Originally published on CoreMesh.Cannot read properties of undefined (reading 'bind') means your code ran something.bind(...) and something was undefined at that moment. The word in quotes is the property the engine tried to read, and bind is a method that only exists on functions. So the real bug is one step to the left of .bind: the function you expected to be there isn't. Usually it's a typo in a method name, a method defined on the wrong object, or a handler that hasn't been assigned yet whe
Playwright recorded my 25 fps animation at about 9. The fix was to stop recording.
I needed a short video of my portfolio for LinkedIn: the opening animation, a swordsman who cuts the screen in two, then a fast scroll through every section. Playwright records video in one option, so I started there. The first video looked fine in stillsrecordVideo on a browser context gave me a 25 fps WebM. Every frame I pulled out of it looked right. I had only checked stills. Played back, it stuttered, and the first person who watched it saw it at once.Measuring it frame by frame told t
React, deeply · 1. Rendering and reconciliation: what React does on a state change
React, deeply · Chapter 1 of 12 · Web · new chapter every Monday nightBy the end of this chapter: Describe the render, reconcile and commit phases precisely enough to predict behaviour. The problemEmma is a front‑end engineer on a two‑month sprint for a real‑time analytics dashboard. The UI pulls live metrics from a WebSocket and updates a table every second. After merging a new “filter by region” feature, the dashboard starts missing updates: the table lags by up to three seconds, the CPU
How I Built a Receipt Scanning PWA for French Freelancers (and What I Learned)
How I Built a Receipt Scanning PWA for French Freelancers (and What I Learned)A few months ago, I launched ScanCompta — a Progressive Web App that lets French freelancers and small business owners scan their receipts and manage expense reports, directly from their phone or browser.Here's what I learned building it. The Problem I Was SolvingFrance has around 4 million self-employed workers — freelancers, tradespeople, VTC drivers, consultants. Most of them handle their own bookkeeping. And t
Node.js Feature Flags: Backend API Percentage Rollouts for Express and React
Use a server-owned feature flag for a gradual rollout, expose only the evaluated value to React, and compare fixed tenant cohorts rather than whoever happened to see the feature that day. The important constraint is signal quality: a percentage rollout controls exposure, but it does not create a valid experiment or explain a result.Short answer: for a small developer tool, I would assign each tenant to a stable cohort, evaluate the flag in the Node.js backend, and attach the cohort and flag revi
Testing React components against the worst case
I wrote this with AI help and edited it myself. Every example is a real fixture from the Brio UI repo.The demo for a component is always a good day. Three plan names that fit, prices in dollars, an FAQ with six short questions in English. You build to that demo, it looks right, and you ship.Then someone pastes a German product name into the pricing card, or the FAQ grows to 120 entries, or the page gets translated into Arabic. That is the first time the component sees real data, and it's usually
The 83 MB JavaScript bundle was not a dependency problem
I ran ls -lh on a production build last week and got this:-rw-r--r-- 1 user staff 3.8K index-FYxpahNp.css-rw-r--r-- 1 user staff 79M index-RqoFan-G.jsSeventy-nine megabytes of JavaScript. One file. One line, 13,308,122 characters long.The stylesheet, for comparison, is 3.8 KB. The CSS is a rounding error next to the script.This is a React app packaged with Capacitor, so there is no CDN and no lazy route to hide behind. That 79 MB file is inside the app binary, read from local storage
I built a one-question feedback tool because research tools cost more than my app makes
There's a bird that rides around on rhinos, the oxpecker. It eats the ticks, which is the textbook version. But it also likes to keep a wound open and drink from it, so biologists still argue about whether it's a helper or a small parasite. The rhino keeps it around anyway, because the bird calls out when something's coming. In Swahili its name literally means the rhino's guard.I ended up building one of these birds for my app, and I tried quite hard to make it the good kind. The problemI h
IndexNow in CI: notify Bing and Yandex on every deploy
IndexNow is a small protocol with one job: tell search engines that a URL was added, changed or deleted, right when it happens. You host a key file, send a POST with a list of URLs, and the engines that take part share the notice with each other.This post sets it up the way most developers want it: once, inside the deploy pipeline, submitting only the URLs that actually changed. Everything below follows the spec at indexnow.org. Who receives IndexNow pingsThe FAQ at indexnow.org lists these
Your Amortization Loop Never Reaches Zero: 4 Bugs in Loan Math Code
If you've ever generated an amortization schedule by hand, you've probably hit this: you loop 360 times and the balance lands on... -$3.07. Or +$0.84. Never exactly zero.Here are four bugs I keep running into, with numbers you can check yourself. 1. The loop's last step is a lie$300,000 at 7% over 360 months. The exact payment is 1,995.9074..., which you round to 1,995.91. Run balance = balance + balance*r - payment 360 times and the balance ends at -$3.07 - you overpaid by three dollars be
How to Measure Reaction Time Without Counting the Waiting Period
A reaction-time test becomes unfair if it measures how long the screen waited before turning green. I built the test as a small state machine: idle, waiting, ready, result, and early. The timer starts only when the ready state begins, so the result represents the click-to-signal interval rather than the random delay. Random delay prevents anticipationStarting a round chooses a delay between 1.2 and 4 seconds:function startWaiting() { phase.value = "waiting"; const delay = 1200 + Math.rand
A Playwright test that catches a contact form pretending to send
A contact form that shows "Message sent!" and sends nothing looks exactly like one that works. Unit tests won't catch it, because there is nothing to unit test: the handler does exactly what it was written to do. You notice when a customer mentions they wrote to you weeks ago.This isn't rare. We tested 105 contact forms on live sites built with AI tools like Lovable and Bolt, and 27 of them showed a success message without sending anything (the study and its data). The handler behind most of the