MoreRSS

site iconThe Practical DeveloperModify

A constructive and inclusive social network for software developers.
Please copy the RSS to your reader, or quickly subscribe to:

Inoreader Feedly Follow Feedbin Local Reader

Rss preview of Blog of The Practical Developer

How I Built a Daily Stock Digest Using n8n (Financial Automation Guide)

2026-04-10 19:40:31

You open Chrome. One tab turns into eight.

Yahoo Finance. TradingView. Twitter. A random newsletter you barely trust. Back to your watchlist. Copy. Paste. Scroll. Repeat.

Forty-five minutes later, you still don't feel confident about what's actually moving the market.

And the worst part?

You'll do it all again tomorrow.

There's a better way.

What You're Actually Going to Build

A daily email that lands in your inbox at 7 AM with your tracked stocks, clearly labeled movers (🟢 up, 🔴 down, ⚪ flat), plus the 2–3 most relevant news headlines per ticker.

Built with:

  • n8n workflow
  • EODHD APIs (market data + news)
  • Google Sheets (your watchlist)
  • Gmail (delivery)

Why This Problem Is Bigger Than It Looks

This isn't about saving 30 minutes.

It's about consistency.

Manual research feels productive, but it's chaotic. One day you check everything. The next day you skip half your list because you're in a rush.

That's how you miss entries.

That's how you react instead of plan.

And slowly, your "system" becomes noise.

I realized this the hard way.

I wasn't losing money because I lacked information.

I was losing clarity because I had too much of it — scattered across tabs, tools, and half-finished notes.

The fix wasn't more data.

It was structure.

That's where n8n financial automation changes everything.

Why I Chose EODHD APIs (And Why It Actually Matters)

Most people underestimate this part.

They think: "I just need stock data."

No.

You need reliable, structured, and consistent data — every single day.

Otherwise, your automation breaks silently.

I tested multiple APIs before landing on EODHD APIs. Some had good pricing but poor coverage. Others had great data… but inconsistent endpoints. And a few? They just randomly failed when you needed them most.

That's unacceptable if you're building automated stock alerts.

Here's what changed with EODHD.

1. One API, Multiple Use Cases

With a single provider, I could fetch:

  • End-of-day prices
  • Intraday movements
  • Financial news
  • Fundamentals

That matters. Because the moment you start stitching multiple APIs together… things break. Different formats. Different latencies. Different failure points.


👉 Try EODHD APIs — one consistent financial data API for prices, news, and fundamentals.

2. Clean, Predictable Responses

This sounds boring. It's not.

If your JSON structure changes unexpectedly, your whole n8n workflow collapses. With EODHD APIs, the responses are stable. Which means your automation stays stable. And that's the real goal.

3. Built for Automation, Not Just Dashboards

Most tools are built for humans — dashboards, charts, interfaces. But when you're building stock market automation, you need something built for machines. Fast responses. Clear endpoints. No unnecessary noise.

That's exactly what EODHD APIs provide.

4. Coverage That Actually Scales

You start with 10 tickers. Then 20. Then 50. Maybe you add crypto. Maybe ETFs. Maybe international stocks.

If your API can't scale with you, you'll rebuild everything later. EODHD handles that from day one.

5. The Hidden Advantage: News Integration

This was the game changer.

Most APIs give you price data. Few give you context.

EODHD APIs let me pull news per ticker, which turns raw numbers into actionable insight. Because +2% without context is meaningless. +2% because of earnings or a product launch? That's signal.

That's why this setup works — not because of n8n alone, but because the data layer is solid. And if you're serious about n8n financial automation, this is the part you don't want to mess up.

The Workflow, Step by Step

This entire system runs on a simple n8n workflow with five nodes. Each one does one job. Nothing fancy. Just clean automation.

1. Schedule Trigger (7 AM daily)

Runs the workflow every morning before you wake up. Because if it depends on you clicking a button, it won't happen consistently.

2. Google Sheets — Read Ticker List

Pulls your watchlist dynamically from a simple spreadsheet. This turns your system into something you can edit in seconds without touching code.

3. HTTP Request → EODHD APIs

Fetches end-of-day price changes and latest news per ticker. This is where your financial data API does the heavy lifting.

4. Code Node (JavaScript)

Classifies each stock as 🟢 / 🔴 / ⚪ and builds the email layout. This is the "brain" — turning raw data into something readable.

5. Gmail Node — Send the Digest

Sends a clean, formatted email straight to your inbox. No dashboards. No logins. Just information where you already are.

That's it. Five nodes. And suddenly you've built your own stock market automation system.

The Output: What the Email Actually Looks Like

Subject line:

📈 Daily Market Movers — March 23

You open it. First thing you see: a clean list of your stocks, each one with a clear signal:

No thinking required.

Then underneath each ticker: 2–3 short headlines. Not 20 links. Just the ones that matter.

Example:

AAPL 🟢 +2.3%

  • Apple announces new AI chip strategy
  • Analysts raise price target ahead of earnings

You scan it in under a minute. You understand what's happening in under two.

And for the first time, your morning doesn't start with chaos. It starts with clarity.

That's what n8n financial automation actually buys you.

How to Customize It for Your Strategy

Once this is running, you'll start tweaking it. That's where it gets interesting.

You can also:

  • Change your tickers directly in Google Sheets — no redeploy needed
  • Adjust the "mover" threshold (e.g., only show stocks moving ±3%)
  • Add a Slack or Telegram notification alongside email
  • Extend it to crypto using the same EODHD APIs

Or go further — turn it into a mini financial dashboard. Combine it with a screener:

That's how simple workflow automation turns into a full system.

FAQ

Do I need coding skills to build this?

Not really. You can build most of this using n8n's visual interface. The only "code" part is the formatting node, and even that can be copied and adjusted.

Is the EODHD APIs free tier enough to run this daily?

Yes, for a small watchlist. If you're tracking 10–20 tickers, the free tier works fine. If you scale beyond that, upgrading makes sense.

Can I run this on n8n cloud or do I need to self-host?

Both work. n8n Cloud is faster to set up. Self-hosting gives you more control if you already run your own stack.

What happens if a ticker returns an error?

You can handle it in the workflow. Add a simple fallback in the code node to skip or flag missing data. Your email still sends — just without breaking everything.

Can I add more data points like earnings dates or analyst ratings?

Yes. That's the beauty of using a proper financial data API. You can enrich the digest with whatever data matters to your strategy.

You know that moment in the morning when you're staring at 8 tabs, trying to piece together what matters?

That used to be me.

Now I wake up, open one email, and I'm done. No friction. No noise. No wasted time. Just signal.

If you're serious about building your own n8n financial automation system, don't overthink it. Set this up this weekend.

Because once it's running, you don't go back.


👉 Get your free EODHD APIs key here — and have this running before Monday.

Looking for technical content for your company? I can help — LinkedIn · [email protected]

Local-First Vectors: How to Build Privacy-Preserving AI Apps without the Cloud

2026-04-10 19:32:37

The Missing Piece for On-Device AI

The world of AI is moving to the edge. With the rise of on-device models like Transformers.js, Gemma, and Phind, we are closer than ever to a truly "dark" application architecture—one where zero data leaves the user's device.

However, there’s a paradox: while we have the models running on-device, we are still sending our sensitive data to cloud-based vector databases like Pinecone or Weaviate to perform similarity searches.

I wanted to solve this paradox.

I’ve been building TalaDB: an open-source, local-first document and vector database built in Rust that runs identically across the Browser (WASM), Node.js, and React Native.

The Multi-Platform Problem

If you've ever tried to build a cross-platform, local-first app, you know the pain:

  • Developing for the browser? You're likely stuck with IndexedDB or a complex WASM-SQL setup.
  • Developing for Mobile? You're probably using SQLite.
  • Developer Experience (DX) Hell: Managing separate drivers, binary extensions for vector search (sqlite-vss), and split business logic is a nightmare.

I wanted a single, unified API. One core to rule them all.

Introducing TalaDB: A Unified Engine

TalaDB provides a familiar, MongoDB-like API for both document filtering and vector similarity search. Whether you are in a React Native app or a Chrome SharedWorker, the code looks exactly the same:

const results = await articles.findNearest('embedding', query, 5, {
  category: 'support',
  locale: 'en',
});

One call. Metadata filter + Vector ranking. No cloud round-trips.

Deep Dive: Under the Hood

Why Rust + redb?

I chose a pure-Rust architecture because of the safety and performance guarantees. For the storage engine, I use redb—a high-performance B-tree store that provides ACID transactions without the overhead of a full SQL engine.

WASM + OPFS: The Bleeding Edge

In the browser, TalaDB leverages the Origin Private File System (OPFS). By running the database inside a SharedWorker, I can achieve near-native performance while keeping the main UI thread completely free.

Binary Compactness

By using postcard for binary serialization, TalaDB keeps data footprints extremely small—often smaller and faster than traditional JSON-based stores. The entire WASM bundle is sub-400KB.

Practical Example: Offline Semantic Search

Imagine building a support app that works 100% offline. Here is how you'd handle a hybrid query:

import { openDB } from 'taladb';

const db = await openDB('docs.db');
const articles = db.collection('articles');

// Find the 5 most relevant articles for a given embedding
const results = await articles.findNearest('embedding', userVector, 5);

results.forEach(({ document, score }) => {
  console.log(`[${score.toFixed(2)}] ${document.title}`);
});

The Future of Local-First

TalaDB is currently in Alpha (v0.3.0). My goal is to bridge the gap between human privacy and machine-learning intelligence.

I’m currently focused on:

  • ⚡ Further optimizations for React Native JSI.
  • 📡 Adding atomic sync and multi-user capabilities.
  • 🧠 Expanding the query operator library.

TalaDB is open-source and MIT licensed. I’d love for you to try the alpha, give me some feedback, or even give the project a star if you find it useful.

Links:

Maximize Performance in HTML5: Proven Techniques for Faster, Smoother Web Apps

2026-04-10 19:31:34

HTML5 represented a fundamental shift in the nature of the web. It transformed browsers from document viewers into application platforms, capable of running games, streaming video, rendering 3D graphics, processing data in background threads, and functioning offline. With that power came a new responsibility: the management of performance.

Performance, in the context of HTML5, is not simply about page load speed. It encompasses the full arc of user experience, from the first moment a network request is made, through the browser’s parsing and rendering pipeline, to every subsequent interaction a user has with the page. MDN’s documentation frames it clearly: users want web experiences that are fast to load and smooth to interact with, and developers must strive for both goals simultaneously.

The importance of performance extends beyond user experience. Google’s Core Web Vitals, a set of metrics measuring load speed, visual stability, and interactivity, are now confirmed ranking signals in search results.

The article covers three major performance domains: the Critical Rendering Path and its optimization; script loading strategies; media and asset optimization; background processing through Web Workers and Service Workers; the HTML5 Canvas API and its GPU-accelerated counterpart WebGL; Core Web Vitals as the modern performance standard; and the toolchain used by developers to measure and diagnose performance issues.

Foundational Tips to Maximize Performance in HTML5 (Tips That Always Work)

1. The Critical Rendering Path

Every performance discussion in HTML5 eventually leads back to one foundational concept: the Critical Rendering Path (CRP). This is the sequence of steps a browser follows to convert raw HTML, CSS, and JavaScript into the pixels a user actually sees. Understanding this process is not optional for performance-focused developers; it is the foundation upon which every optimization is built.

How the Browser Renders a Page

When a browser receives an HTML document, it begins constructing the Document Object Model (DOM) by parsing the markup from top to bottom. Simultaneously, any CSS encountered triggers the construction of a separate CSS Object Model (CSSOM). The browser must merge the DOM and CSSOM into a Render Tree, which includes only the visible elements and their computed styles. From the Render Tree, the browser calculates the position and size of every element (Layout), and finally draws those elements to the screen (Paint).

This pipeline is elegant but fragile. Anything that interrupts or delays any stage of the process will delay the moment when the user first sees content. The term ‘render-blocking’ describes resources that pause this pipeline, and eliminating or deferring those resources is the first major category of HTML5 performance optimization.

CSS as a Render-Blocking Resource

CSS is, by default, render-blocking. When the browser encounters a stylesheet linked in the document head, it halts the rendering pipeline until that stylesheet is fully downloaded and parsed. This behavior is intentional; the browser does not want to display unstyled content, but it creates a significant bottleneck, particularly for large or slowly-loading stylesheets.

It is recommended to adopt two primary strategies for addressing this. The first is to inline critical CSS, the styles needed to render above-the-fold content, directly in the HTML document’s head, eliminating the network request entirely for that initial paint. The second is to load non-critical CSS asynchronously by temporarily setting the media attribute to print (which the browser treats as low-priority) and updating it to all once loaded.

Linking CSS with a traditional link tag with rel=’stylesheet’ is synchronous and blocks rendering. Optimize the rendering of your page by removing blocking CSS.

JavaScript as a Parser-Blocking Resource

If CSS is render-blocking, JavaScript is even more disruptive: it is parser-blocking. When the browser encounters a standard script tag, it stops DOM construction entirely, executes the script, and only then resumes. HTML5 provides two attributes to address this: async and defer. A script marked async is fetched in parallel with HTML parsing and executed as soon as it downloads. The defer attribute also fetches in parallel but delays execution until after the document is fully parsed, before DOMContentLoaded fires. Deferred scripts also execute in document order, making defer the safer choice for interdependent scripts.

2. Script Loading Strategies

JavaScript management is widely recognized as the most impactful area of HTML5 performance optimization. Scripts are large, they block the main thread during execution, and the JavaScript ecosystem encourages developers to pull in large frameworks and libraries that users must download even if only a fraction of the functionality is used. The developer community has coalesced around several complementary strategies.

Code Splitting and Lazy Loading of Modules

Code splitting divides a JavaScript bundle into smaller pieces that are loaded only when needed. Rather than sending the entire application’s JavaScript on initial page load, code splitting ensures that each route or feature loads only the code it requires. Lazy loading of modules means deferring the import of a JavaScript module until it is actually needed. In React, this is achieved using React.lazy() combined with Suspense. Keep the initial JavaScript payload as small as possible; under 200KB for critical pages is a widely cited benchmark.

Tree-Shaking and Dead Code Elimination

Tree-shaking removes unused code from a JavaScript bundle before it is served to users. Modern build tools like Webpack, Rollup, and Vite perform this automatically when ES Modules (ESM) are used, because ESM’s static import syntax allows tools to analyze which exports are actually consumed at build time. Code that is imported but never called is excluded from the final bundle. Selecting tree-shakeable dependencies is therefore as much a performance decision as an architectural one.

ES Modules and Modern Browser Delivery

ES Modules are now natively supported by all modern browsers. The community in 2026 increasingly advocates for shipping ES modules directly using type="module" on script tags, while maintaining a bundled fallback using nomodule for older environments. This ‘differential serving’ approach delivers smaller, faster code to the majority of users without sacrificing backward compatibility.

3. Media and Asset Optimization

Media optimization - images and video - is the ‘lowest hanging fruit of web performance.’ Images and videos are large; they dominate page weight, and they are often the first resources a user waits for. Optimizing them correctly delivers the greatest performance gains for the least development effort.

Image Optimization

Image optimization in 2026 involves format selection, responsive delivery, and loading strategy. WebP offers substantially better compression than JPEG and PNG while maintaining comparable quality. AVIF, a newer format, outperforms WebP in many cases. In 2026, AVIF and WebP are broadly considered the gold standards for web images.

Responsive images are delivered using the srcset attribute and the element, allowing the browser to select the most appropriate image based on device pixel ratio and viewport width. The loading="lazy" attribute, a native HTML5 feature, defers loading of images below the viewport until they are needed, with no JavaScript required. This attribute also works on iframe, video, and audio elements.
Developer consensus: Always set explicit width and height attributes on images. This allows the browser to reserve space before the image loads, preventing Cumulative Layout Shift, one of Google’s Core Web Vitals and a direct ranking factor.

Video Optimization

For background videos, removing the audio track reduces file size with no user-visible impact. The preload attribute controls how aggressively the browser fetches video data before playback is requested. Setting preload="none" or preload="metadata" defers large video downloads, significantly reducing initial page weight.

Font Optimization

Web fonts introduce performance challenges around text visibility. The font-display: swap CSS property ensures that text is rendered immediately in a system fallback font and swaps to the custom font once it is loaded, preventing the Flash of Invisible Text (FOIT). WOFF2 is the modern font format standard; it includes compression natively, unlike TTF and EOT formats which require external GZIP or Brotli compression. For icon fonts, the community increasingly recommends replacing them with compressed SVGs or inline SVG sprites to eliminate an additional HTTP request.

Conclusion

The practices covered in this article, from the Critical Rendering Path to Core Web Vitals, from lazy-loaded assets to Web Workers, are not advanced topics reserved for specialists. They are the fundamentals of modern web development. What makes them worth revisiting in 2026 is precisely that, in the rush toward AI-assisted tooling and rapid delivery, these foundations are increasingly being skipped.

That gap creates an opportunity, whether you are building something yourself or evaluating someone else's work.

If you are a developer, keep these practices close, not as a checklist, but as a lens. When reviewing a pull request, architecting a new feature, or debugging a sluggish interaction, these are the questions to ask first. Render blocking, bundle size, layout shift: these rarely get caught in code review if no one is actively looking for them.

If you are a product owner, CTO, or someone looking to hire HTML5 developers or engage a team for your site or product, these fundamentals make for a solid evaluation baseline. Ask candidates or vendors how they approach render-blocking resources, image optimization, or Core Web Vitals. In the AI era, strong tools can generate code quickly, but knowing whether that code is actually performant requires a grasp of the basics that no tool supplies automatically. How well someone understands these core principles is a reliable signal of the quality of work you can expect.

Create a mini-website with HTMLSave

2026-04-10 19:22:06

HTMLSave is a popular online platform primarily used for hosting and managing simple HTML-based webpages without the need for traditional web hosting setups. It is specifically designed for beginners, students, or developers who need to get a small project live in seconds.

Core Features of HTMLSave

The service serves as a "paste-bin" for code but with the added benefit of rendering it as a live website.

  • Zero Configuration: You don't need to deal with FTP, servers, or domain names. You simply paste your code and save.
  • Support for Web Technologies: While the name suggests just HTML, the platform fully supports CSS and JavaScript, allowing you to host interactive sites.
  • Custom Subdomains: Users can choose a specific name for their site (e.g., yourname.htmlsave.net) to make the link more professional.
  • Ad-Free Experience: Unlike many free hosts, HTMLSave provides a clean, ad-free environment for your pages.
  • Password Protection: A unique feature of the service is the ability to lock your webpage behind a password so users with the password can co work (update code and preview it) together.

When to Use It

It is best suited for:

  • Quick Prototyping: Testing how a snippet of code looks and behaves in a live browser environment.
  • Learning: A "playground" for students to practice HTML/CSS and see immediate results.
  • Landing Pages: Hosting a quick "Link in Bio" page or a simple digital resume.
  • Sharing: Sending a live preview of a design to a client or peer.

Pro-Tip: If you are using the free version of the web service, keep in mind that it is intended for lightweight projects. For massive websites with heavy image assets, you would typically move to a dedicated host like Netlify or GitHub Pages.

Are you looking to host a specific project, or were you trying to use it for code snippets?

Why I Built an AI IELTS Grader That Replaces the $50-Per-Essay Human Tutor

2026-04-10 19:15:55

A founder story. Originally published on englishaidol.com. This version syndicated with permission.

TL;DR: I'm a TESOL-certified English teacher. I watched thousands of international students hit a wall because they couldn't afford human writing feedback. So I built an AI that gives instant band-score feedback on IELTS and TOEFL writing, calibrated to the same rubric real examiners use. It's free. Here's the story.

A student emailed me in 2023. She was from a small city in Vietnam. Her target university in Canada required IELTS band 7.0. She was stuck at band 6.0 and her test was in six weeks.

She'd already taken it twice. Each retake cost $240 -- more than a month's income for her family. She couldn't afford a third.

She asked me if I could review her writing samples. I said yes, I'd do it for free. She sent me 30 essays.

I didn't know what to say. Her vocabulary was solid. Her grammar was strong. But she was making the same five mistakes in every single essay -- mistakes I could spot in 10 seconds each. Things like not addressing every part of the prompt, using linking words mechanically, mistaking "impressive" vocabulary for precise vocabulary. Classic band-6 ceiling problems.

If she had a human tutor to catch these mistakes, she could fix them in a week and probably score band 7.0 or higher on her next attempt.

But human IELTS tutors charge $30-50 per essay review. For the 20-30 practice essays she needed, that's $600-1,500 -- more than the total cost of her university application, visa, and first month's rent combined. She couldn't afford it. So she was stuck, making the same mistakes with no one to point them out.

I wrote back with a 4-page breakdown of her issues. A week later she emailed to say she'd improved dramatically on her practice essays. Two weeks after that, she scored band 7.5 on her real test and got accepted to her target university.

That email is why I built English AIdol.

The problem is structural, not individual

After that student, I started paying attention. I counted.

On r/IELTS alone, there are hundreds of new posts every week from students asking for writing feedback. Most of them never get a real response -- the top comment is usually "looks good!" or "try to use more cohesive devices" which isn't actually feedback.

I tracked the feedback requests from students in five markets: Vietnam, the Philippines, Indonesia, India, and Brazil. The pattern was identical across all of them:

  • Students who could afford human tutors ($30-50 per essay) showed consistent improvement from band 6 to band 7+
  • Students who couldn't afford human tutors plateaued at band 6 and either gave up on their target school or took the test 3-5 times before getting the score they needed

The bottleneck wasn't talent. It wasn't effort. It was access to feedback.

IELTS is a global gatekeeper for international education, immigration, and professional licensing. For students in low and middle-income countries, the test fee alone ($240) is often more than a month's income. When you add retakes and tutor fees, the total cost of passing IELTS can exceed $2,000 -- money that many families simply don't have.

That's not a talent gap. That's a feedback access gap. And feedback, unlike test fees, is something software can provide at near-zero marginal cost.

Why "just use ChatGPT" isn't the answer

The first thing people say when I describe English AIdol is: "Can't students just use ChatGPT for this?"

The honest answer is: not really, at least not reliably.

ChatGPT can give decent general writing feedback. But it's not calibrated to the IELTS band descriptors. When I tested it against real IELTS samples with known scores, ChatGPT tended to be dramatically over-generous -- it would score a band-5.5 essay as a band-7.0. Students would submit essays, get told they were band 7, go take the real test, and score 5.5. They'd come out of the test center crushed, thinking the test was unfair when actually they'd just been getting bad feedback for months.

I knew the solution had to be different:

  1. Trained specifically on IELTS/TOEFL rubrics, not generic writing feedback
  2. Calibrated against real band-scored samples, not inferred from general training data
  3. Transparent about the four official criteria (Task Achievement, Coherence & Cohesion, Lexical Resource, Grammatical Range & Accuracy) -- not a single number without breakdown
  4. Free at the core -- if the whole point was to serve students who couldn't afford human tutors, charging $30/month would defeat the purpose

What I built

English AIdol went live in early 2024 as a small experiment. The core product: you submit a Writing Task 1 or Task 2 response, and the AI returns a band-score estimate, criterion-level breakdown, and sentence-by-sentence improvement notes in about 10 seconds.

The AI is calibrated against the official IELTS band descriptors. In our internal testing it predicts within 0.5 bands of real examiner scores approximately 90% of the time -- which is actually close to the inter-rater reliability ceiling for trained human IELTS examiners (around 85-92%, depending on the study).

That accuracy matters because it means students can trust the feedback. If you submit an essay and get a "band 6.5" estimate from English AIdol, you can be roughly 90% confident that a real examiner would give you between band 6.0 and band 7.0.

The free tier includes AI feedback on Writing and Speaking for IELTS, TOEFL iBT, TOEIC, and PTE. No credit card. No "free trial that expires in 7 days." Students can actually complete their test preparation without paying anything. That's the whole point.

Two years later

English AIdol now serves students in 80+ countries. The interface and blog content is available in 20+ languages (Vietnamese, Korean, Chinese, Japanese, Indonesian, Thai, Portuguese, Spanish, Hindi, Arabic, Farsi, and more) because we serve markets where English-only interfaces are a barrier.

When ETS launched the new TOEFL iBT format in January 2026, we rebuilt our TOEFL modules in three months. Most competitors still haven't updated. I think that's partly because our team is small and moves fast, but also because our motivation is different -- we genuinely care about students having accurate feedback for the test they're actually taking, not the test from two years ago.

The students who email me now mostly don't thank me for the product. They thank me for the fact that the product is free. That tells me something about how broken the existing system is.

What I've learned

A few things that might be useful for anyone thinking about building in EdTech or an adjacent space:

1. The most valuable features are the ones that remove gatekeepers. Writing feedback used to be gatekept by human tutors. Pronunciation feedback used to be gatekept by conversation partners. Speaking practice used to be gatekept by paid mock interviews. AI changes all of that -- but only if you use it to remove the gatekeepers, not to build a slicker paywall.

2. Calibration is the hard part, not the AI. Building a chatbot is easy. Building one whose scores actually correlate with real examiner scores requires hundreds of hours of evaluation against known samples. This is the part most competitors skip, and it's why ChatGPT gives unreliable IELTS scores.

3. Free-tier generosity is marketing AND ethics. For English AIdol, our free tier is used by hundreds of thousands of students who will never pay us a cent. That's not a failure of monetization -- those students tell their friends, write Reddit posts, create TikToks about us, and occasionally become paying users years later when they can afford it. The free tier is how we exist.

4. Localization matters more than you think. When we launched Vietnamese content, Vietnamese user acquisition went up 20x almost overnight. When we launched Korean content, same thing. Most English-learning platforms still only offer English interfaces, which is backwards -- the students learning English are, by definition, NOT fluent in English yet.

What's next

We're working on three things:

  1. Updating all TOEFL materials to the 2026 format -- this is mostly done, but the new Interview Speaking task still needs more examples
  2. Expanding to German and Korean test prep -- Goethe-Institut and TOPIK specifically
  3. A research partnership with a TESOL program to publish validation data on our scoring accuracy

If you're a student preparing for IELTS, TOEFL, TOEIC, or PTE, try English AIdol for free. No account needed for your first submission. If it helps, tell a friend. If it doesn't, tell me what's missing -- I read every email at [email protected].

If you're an educator or researcher and want to talk about validation or integration, I'd love to hear from you too.

Thanks to everyone who has tested English AIdol, sent bug reports, and written thank-you emails. I read every single one. Keep them coming.

And to the student whose email started all of this -- you know who you are. I hope Canada is treating you well.

-- Alfie Lim, founder, English AIdol

Enhancing ffetch: Opt-in Shortcuts for Requests and Responses While Preserving Native Fetch Compatibility

2026-04-10 19:12:25

Introduction and Problem Statement

The release of ffetch 5.1.0 marks a pivotal moment in the evolution of HTTP client libraries, addressing a critical tension between developer productivity and backward compatibility. At its core, ffetch is a lightweight, production-ready HTTP client that wraps native fetch, adding essential features like timeouts, retries with exponential backoff, and lifecycle hooks. However, as web applications grow in complexity, developers increasingly demand convenience methods for common tasks without sacrificing the simplicity of native fetch.

The problem is twofold: First, native fetch, while versatile, lacks built-in mechanisms for advanced use cases such as retry logic with jitter or response parsing shortcuts. Second, existing solutions often force developers into a trade-off—either adopt a more feature-rich library that breaks compatibility with native fetch or manually implement these features, leading to verbose, error-prone code. This friction slows development cycles and increases the risk of bugs in production environments.

ffetch 5.1.0 tackles this issue head-on by introducing opt-in request and response shortcuts via plugins. These shortcuts, such as .json() for parsing JSON responses, are designed to reduce boilerplate while preserving native fetch compatibility. The opt-in nature ensures that developers can adopt these enhancements incrementally, without disrupting existing workflows. This approach sets a new standard for how modern libraries can evolve—by layering innovation on top of proven foundations rather than replacing them outright.

To illustrate, consider the causal chain of adopting these shortcuts: Impact → Internal Process → Observable Effect:

  • Impact: Developers face increased complexity when manually handling retries, timeouts, and response parsing.
  • Internal Process: ffetch 5.1.0 introduces plugins that abstract these common tasks into reusable methods, leveraging native fetch under the hood.
  • Observable Effect: Code becomes more concise and readable, reducing cognitive load and minimizing the risk of errors in production.

For example, the requestShortcutsPlugin and responseShortcutsPlugin in ffetch 5.1.0 allow developers to write:

const todo = await api.get('/todos/1').json()

Instead of:

const response = await api.get('/todos/1')
if (!response.ok) throw new Error('Network response was not ok')
const todo = await response.json()

This simplification is not just syntactic sugar—it’s a mechanical reduction of code complexity, directly translating to faster development cycles and lower maintenance overhead. By preserving native fetch compatibility, ffetch ensures that developers can adopt these shortcuts without fearing lock-in or compatibility issues.

In summary, ffetch 5.1.0’s opt-in shortcuts address a pressing need in the ecosystem: enhancing developer productivity without compromising the familiarity and reliability of native fetch. This update is a testament to the principle that innovation and compatibility are not mutually exclusive—they can, and should, coexist in modern tooling.

Implementation and Scenarios

The introduction of opt-in request and response shortcuts in ffetch 5.1.0 is a masterclass in balancing innovation with backward compatibility. The technical approach hinges on a plugin-based architecture, where requestShortcutsPlugin and responseShortcutsPlugin are injected into the client configuration. These plugins act as non-invasive layers atop the native fetch API, preserving its behavior while extending functionality. Below, we dissect the six key scenarios where these enhancements are applied, detailing their mechanisms and impact.

Scenario 1: JSON Response Parsing

Mechanism: The .json() shortcut in responseShortcutsPlugin intercepts the response stream, applies response.json(), and handles potential parsing errors. This abstracts the manual error handling and stream consumption typically required.

Impact → Internal Process → Observable Effect: Without this shortcut, developers would manually chain .then(response => response.json()), risking unhandled rejections if the response is not valid JSON. The plugin encapsulates this logic, reducing code verbosity and error risk. Observable effect: await api.get('/todos/1').json() reads like native fetch but is safer and more concise.

Scenario 2: Retry Logic with Exponential Backoff

Mechanism: The requestShortcutsPlugin integrates retry logic with a formula: delay = 2^(attempt-1) 1000 + jitter. This is implemented as a middleware that intercepts failed requests, recalculates delays, and reissues requests until max retries are reached.

Causal Chain: Native fetch lacks retry mechanisms, forcing developers to implement them manually. Manual retries often omit jitter, leading to thundering herd problems (e.g., simultaneous retries overwhelming servers). The plugin’s jitter introduces randomness, distributing retries and reducing server load. Observable effect: Improved resilience without manual boilerplate.

Scenario 3: Timeout Handling

Mechanism: Timeouts are implemented via a race condition: the request is aborted if it exceeds the configured timeout. The plugin uses AbortController under the hood, ensuring compatibility with native fetch’s signal API.

Edge Case Analysis: Without timeouts, long-running requests can block UI threads or exhaust resources. The plugin’s timeout mechanism terminates stalled requests, freeing up resources. Observable effect: Predictable request lifecycles, even in edge cases like flaky networks.

Scenario 4: Lifecycle Hooks

Mechanism: Hooks like onRequest and onResponse are implemented as interceptors. They allow developers to inject logic (e.g., logging, authentication) at specific points in the request lifecycle.

Practical Insight: Native fetch lacks lifecycle hooks, forcing developers to wrap requests in custom functions. The plugin’s hooks modularize this logic, reducing code duplication. Observable effect: Cleaner, more maintainable codebases.

Scenario 5: Pending Request Tracking

Mechanism: The plugin maintains a registry of active requests. When a request is initiated, it’s added to the registry; upon completion, it’s removed. This enables features like request cancellation or batch tracking.

Risk Mechanism: Without tracking, developers risk memory leaks from orphaned requests. The registry centralizes request state, mitigating this risk. Observable effect: Safer long-lived applications, especially in single-page apps.

Scenario 6: Cross-Environment Compatibility

Mechanism: The plugins are designed to work across browsers, Node.js, SSR, and edge runtimes by leveraging environment detection. For example, Node.js uses http modules for timeouts, while browsers use AbortController.

Decision Dominance: Alternative solutions like runtime-specific forks would fragment the codebase. The unified plugin approach abstracts environment differences, ensuring consistency. Observable effect: Write-once, run-anywhere functionality without conditional logic.

Comparative Analysis of Solutions

Three options were considered for enhancing ffetch:

  • Option 1: Monolithic Enhancements (rejected)

  • Mechanism: Bake all features directly into the core library.

  • Drawback: Breaks native fetch compatibility, forcing developers to adopt new APIs.

  • Rule: If compatibility is non-negotiable → avoid monolithic designs.

  • Option 2: External Utilities (suboptimal)

  • Mechanism: Provide standalone functions for tasks like retries or parsing.

  • Drawback: Requires manual integration, increasing cognitive load.

  • Rule: If seamless integration is critical → prefer plugins over utilities.

  • Option 3: Opt-In Plugins (optimal)

  • Mechanism: Encapsulate enhancements in optional plugins, preserving core behavior.

  • Advantage: Developers adopt features incrementally without disrupting workflows.

  • Rule: If X (need for both innovation and compatibility) → use Y (opt-in plugins).

Conclusion

The opt-in plugins in ffetch 5.1.0 represent a Goldilocks solution: they neither force adoption nor require manual integration. By abstracting complexity into reusable methods, they mechanically reduce code verbosity, error risk, and cognitive load. The plugins’ incremental nature ensures developers can adopt enhancements at their own pace, setting a new standard for HTTP client libraries. The only condition under which this solution fails is if the underlying fetch API itself is deprecated—a highly unlikely scenario given its widespread adoption.

Conclusion and Future Outlook

The ffetch 5.1.0 update marks a significant leap in HTTP client functionality by introducing opt-in request and response shortcuts while preserving native fetch compatibility. This innovation directly addresses the growing complexity of web applications, where developers demand both advanced features and simplicity. By encapsulating common tasks like JSON parsing, retry logic, and timeout handling into reusable plugins, ffetch reduces boilerplate code and cognitive load, enabling faster development cycles and lower maintenance overhead.

Impact on Developers

The introduction of requestShortcutsPlugin and responseShortcutsPlugin transforms how developers interact with HTTP requests. For instance, the .json() shortcut intercepts the response stream, applies response.json(), and handles parsing errors internally, resulting in safer, more concise syntax. Similarly, the exponential backoff with jitter mechanism in retry logic distributes retries to prevent thundering herd problems, enhancing resilience without manual intervention. These improvements collectively reduce error risk and streamline workflows, making ffetch a more productive tool for developers.

Future Improvements and Extensions

While ffetch 5.1.0 sets a new standard, future iterations could further enhance its utility based on user feedback and evolving needs. Potential improvements include:

  • Additional Plugins for Specific Use Cases: Expanding the plugin ecosystem to include GraphQL support, OAuth integration, or WebSocket handling could cater to niche requirements without bloating the core library.
  • Enhanced Error Handling: Introducing more granular error types and customizable error callbacks could provide developers with finer control over failure scenarios.
  • Performance Optimizations: Further reducing the overhead of plugin injection or optimizing request batching could improve performance in high-throughput environments.

Comparative Analysis and Decision Dominance

The opt-in plugin architecture of ffetch 5.1.0 emerged as the optimal solution after evaluating three approaches:

  1. Monolithic Enhancements: Rejected due to breaking native fetch compatibility, which is non-negotiable for many developers.
  2. External Utilities: Suboptimal because they require manual integration, increasing complexity and reducing seamlessness.
  3. Opt-In Plugins: Optimal as they balance innovation and compatibility, allowing incremental adoption without disrupting workflows. This approach fails only if the native fetch API is deprecated, an extremely unlikely scenario.

Rule for Choosing a Solution: If both innovation and compatibility are critical, use opt-in plugins to encapsulate enhancements without disrupting existing workflows.

Final Thoughts

ffetch 5.1.0 exemplifies how modern libraries can evolve to meet developer needs without sacrificing backward compatibility. By abstracting complexity into optional plugins, it empowers developers to write cleaner, more maintainable code while leveraging the reliability of native fetch. As web development continues to demand efficiency and scalability, tools like ffetch will remain indispensable for staying competitive in the fast-paced tech industry.