DevIdiot!
Base64 Is Not Encryption: A Practical Guide for Text and Small Files
Base64 often appears in places that make it look more mysterious than it is: API payloads, email attachments, Data URLs, configuration files, and token segments.It is easy to mistake a long Base64 string for protected data. It is not protected. Base64 is an encoding that represents bytes with printable text characters. Anyone who has the value can decode it.That distinction matters when you are handling text, small files, or values that might contain secrets. What Base64 actually doesComput
Balloon Payments in TypeScript: How to Keep the Final Balance Correct
A balloon loan does not make part of the principal disappear. It moves it to the end of the schedule.That sounds obvious, but it leads to a surprisingly common implementation bug: code calculates a lower regular payment, then treats the balloon as if it were a separate expense that does not affect the amortization math. The result can be a schedule that looks plausible for 35 months and leaves the wrong balance in month 36.This article builds a monthly, fixed-rate balloon schedule in TypeScript.
Stripe webhook timed out? Return a 2xx first, then do the heavy work in a queue
A webhook handler often does everything inside the request: verify the event, update the database, send the email, call another API, and only then answer. On a quiet day that finishes in time. On a busy one, or when a downstream service is slow, the response arrives late and Stripe's delivery log shows a timeout.This post covers what that status means, what Stripe says the handler should do first, how to move the slow part into a queue, and how to catch up on events that failed in the meantime.
JSON-LD for Contractor Websites: Schema Markup That Makes Service Pages Machine-Readable
If you build or maintain websites for trades businesses, such as painters, roofers or flooring installers, you'll get asked to "do the SEO stuff," and these days to "make us show up in ChatGPT." Structured data is one of the few parts of that request that's concrete, testable and fully under your control.This post is a practical reference: which schema.org types fit contractors, a working JSON-LD pattern for a company with several service pages, what to do when the business doesn't publish a str
Building Redaktix: A Zero-Server, Browser-Local PDF & Document Redaction Tool
Last tax season, I needed to redact sensitive details from a W-2 form and a bank statement before sending them to a landlord. I tried several "free online redaction tools," but every single one required uploading my sensitive documents to an external server. That felt completely backwards for documents whose whole point is privacy.So I built Redaktix—a browser-local document redaction tool where your files never touch a server. 🛡️ How It Works (Tech Stack)100% Client-Side: Everything runs l
I run 38 PDF tools with no server. Here is where the work went instead.
When you merge two PDFs on most websites, your files go to someone's server, get processed there, and come back. I built PDFRoll the other way around: 38 tools, static pages, and nothing that processes a file anywhere but in your own browser tab.That sounds like a privacy feature, and it is. But it is mostly an architecture decision, and it moved the hard problems to places I did not expect. This post is about those places. What "no server" means hereThe site is static HTML on a CDN. The PD
Exchange Rate API Unit Testing: Mocks, Fixtures and Contract Tests
Code that depends on live FX is awkward to test. The rate changes every minute, the network may be down in CI, and a test that asserts 0.9215 passes today and fails tomorrow. This guide shows how to test exchange rate API code properly: inject a rate provider, use fixtures with the real response shape, mock HTTP in Vitest or Jest with msw and in Python with responses, cover the 401 and 429 paths, and run one contract test against the real API every night. Rule one: never assert on live valu
Free Exchange Rate API Key: How to Hide It Behind a Proxy
You got a free exchange rate API key, pasted it into your React app, and it works. It also means the key is now public. Anyone who opens your site can copy it and spend your quota, and on a paid plan they spend your money. This guide shows why that happens and how to fix it with a small proxy: first on Cloudflare Workers, then as a Next.js route handler. Why a free exchange rate API key in frontend code is publicThere is no way to hide a secret in code that runs on someone else's device.Bro
FX Rates API Dashboard: Live Watchlist, 30-Day Chart and % Change
This tutorial builds a small FX rates dashboard on top of an FX rates API. It shows current rates for a watchlist of currencies, a 30-day line chart for the selected pair, and the percent change over one day and 30 days. You can start with a free FX rates API key for the live watchlist; the 30-day chart uses historical data, which is on the paid plans.The whole thing is two files: a small Node.js backend that holds the API key and refreshes rates every minute, and one HTML page with Chart.js tha
Exchange Rates API in Production: Fallbacks and Error Handling
An exchange rates API is a dependency your app calls on every price it shows. When it is slow, down or wrong, the problem lands on your checkout page. Most integrations handle the happy path and nothing else. This tutorial builds the production layer around an exchange rates API in JavaScript: timeouts, retries with backoff and jitter, a stale-while-revalidate cache, a staleness threshold, a fallback provider, a circuit breaker, monitoring of the time field, and sanity bounds on each new rate.Th
I Built a State Management Library That Works Like React's useState
I Built a State Management Library That Works Like React's useState — Meet CreateStoreIf you've worked with React, you've probably used useState countless times.It's simple, predictable, and gets the job done.But as an application grows, things get a little more complicated. You have components deeply nested in the component tree that need access to the same state. Suddenly, you're passing props through multiple components, introducing Context Providers, or bringing in a state management l
Next.js opengraph-image in Crawled – currently not indexed: should you fix it?
Search Console's Page indexing report put 14 URLs from this site under "Crawled – currently not indexed". Only 4 of them were pages. The other 10 were files: six per-page opengraph-image routes, feed.xml, favicon.ico, and the root card twice, once with its cache-busting query. None of those should ever be in the index, so the status is harmless for them. I still added X-Robots-Tag: noindex to every one, but the more useful thing I learned is what that header does not do. Why does Google cra
🚀 New React Challenge: Nested Comments
Flattening a comment thread into a single array works until you need to reply to a reply. Then you're faking depth with parent ids, and every edit or delete means rebuilding the whole list. A recursive tree keeps the shape of the conversation and lets you update just the branch that changed. 🧩 OverviewBuild a threaded comments UI: render a recursive thread, then reply, edit, collapse, and delete nodes while every update returns a new tree instead of mutating the seed.👉 https://www.reactchal
Recoloring a Product Photo with an SVG Filter – and Where It Breaks
Short answer: yes, one SVG filter can recolor a transparent-background product photo to any color. A feColorMatrix that desaturates the image, followed by a three-stop feComponentTransfer table, is about twenty lines. It works. But the result depends on the tonal range of the photo you feed it, and on the masters I tested that dependency pushed the colors darker or lighter than requested.I found this while building a color preview for pi-pi.ee, an online shop I built. The shop stocks black, grey
The Architecture of Impenetrable Web Security: Why Amiry Design Engineers Decoupled Defense Systems
Most digital agencies treat cybersecurity as an afterthought—an SSL certificate slapped on a shared hosting server running an outdated WordPress installation with 35 third-party plugins. This approach is catastrophic for international organizations and luxury brands. In 2026, automated credential stuffing, distributed denial-of-service (DDoS) attacks, and SQL injection bots crawl the web 24/7 searching for vulnerable attack vectors.At Amiry Design, our security philosophy starts from first princ
How to Add a Rich Text Editor to a shadcn/ui App
shadcn/ui gives you buttons, dialogs, inputs, and dozens of other components, but no rich text editor. When you need one for blog posts, comments, notes, or a CMS, you usually end up wiring Tiptap yourself and building a toolbar that matches the rest of your UI.editorcn is that missing piece. It's a set of Tiptap-based editors installed with the shadcn CLI and styled with your shadcn theme tokens. Like shadcn/ui, the source is copied into your project, so you own the code.In this guide you'll:In
How I Built a Bilingual Portfolio with Next.js and TypeScript
A portfolio is a strange project. It has to be small enough to stay fast, but complete enough to show how you think. It has to work in two languages without feeling like two separate sites. And it has to be easy to update, because the work it describes will keep changing.This site is the result of those constraints. It is a static Next.js export with English at / and Arabic at /ar, two root layouts, a typed content model, and a design system built around one accent color. Here is how the pieces
How Old Are You, Exactly? The Month-End Rule Behind a Correct Age Calculator
We are a small Saudi team in Riyadh, and one of our free browser tools is an age calculator. It answers a question that sounds trivial: "how old am I, in years, months and days?" People use it for school forms, visa applications and official papers, so the answer has to match what other careful software says, to the day.It turned out that "years, months and days" is not a single obvious calculation. The hard part is the end of the month. This post shows the short function we ship, the bug in the
Loading states for a heavy 3D model - do not show an empty canvas
Even a well-compressed product model is a few MB, and for a second or two on a normal connection the user is looking at an empty canvas. That gap is where people decide the page is broken and leave. A configurator needs a loading state as much as it needs the model. GLTFLoader gives you progress for freeThe loader reports bytes as they arrive:loader.load( '/models/pool.glb', (gltf) => { scene.add(gltf.scene); hideLoader() }, (event) => { if (event.lengthComputable) { const
Running VS Code end-to-end tests on a Windows desktop nobody can see
My end-to-end tests press Ctrl+S in real VS Code windows. That can't happen on the screen I'm working on.The extension under test is Virga, which runs Apex and SOQL scratches against an org with Ctrl+S and lets you close them without a "save changes?" dialog. Most of what can go wrong in it lives in VS Code itself: auto save, the dirty state of a tab, native dialogs, keymaps that also want Ctrl+S, tabs that come back after a restart. A fake of the VS Code API can imitate those, and Virga's unit