Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Newsletter Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

WebDevPro

62 Articles
Kinnari Chohan
19 Jan 2026
9 min read
Save for later

WebDevPro #123: Looking Back at 2025 and January in Focus

Kinnari Chohan
19 Jan 2026
9 min read
Crafting the Web: Tips, Tools, and Trends for Developers Advertise with Us|Sign Up to the Newsletter @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } WebDevPro #123 Looking Back at 2025 and January in Focus Crafting the Web: Tips, Tools, and Trends for Developers Hi , Welcome back to the first WebDevPro issue of the year. We’re reopening with a tighter promise: a sharper take on what’s happening in web development, and what’s actually worth your attention. The web moved fast in 2025, but the real story was the direction the updates were pointed in. Everyday development got more structured, more AI-assisted, and more performance-aware, and the teams that adapted early are already moving differently. Last year we sent 42 issues to 40,000+ subscribers. This year, we want each edition to feel useful within the first minute: the ideas you can carry into your codebase, the shifts that change how you build, and the updates you should act on before they turn into surprises. This edition is a reset and a catch-up in one. We’re bringing back pieces from past issues that still hold up when you’re dealing with async complexity, messy failure modes, and production AI features. Then we compress 2025 into the shifts that mattered, followed by a short news corner to get you current. Let’s get started! Most popular articles from our past newsletters Taming Asynchronous Control Flow in Node.js: From Callback Hell to Elegant Patterns (Originally sent: August 06, 2025) Starting from the classic “callback hell” problem, this article showed how simple techniques like early returns and modular functions can clean up asynchronous code. It then introduced essential async control patterns, including sequential execution, concurrency, race condition prevention, and limited parallelism using queues, all grounded in practical Node.js examples. Even as async and await improve readability, the underlying coordination problems have not gone away. APIs are more distributed, users are more impatient, and systems are more parallel. Knowing how to control flow, limit concurrency, and avoid race conditions remains critical for building resilient applications. Rethinking Error Handling with Information Architecture (Originally sent: September 15, 2025) Errors are not all the same, and this article made a strong case for treating them differently. By classifying errors into user, system, and contextual types, it reframed error handling as an information architecture and UX problem rather than a purely technical one. The piece explored how clear messaging, thoughtful fallback navigation, and consistent structure help users recover when things go wrong, without losing trust or orientation. As products grow more complex and AI-driven systems introduce new failure modes, error states have become more visible and more consequential. Designing for breakdowns, empty states, and partial failures is now a core part of resilient UX. This article’s focus on graceful degradation, user-centered language, and recovery paths feels increasingly relevant in a world where systems fail in subtle, contextual ways rather than simply crashing. Building an AI Email Enhancer with React 19 and Vercel AI SDK (Originally sent: September 29, 2025) This article explored how modern React and AI tooling come together in a real-world feature. It walked through building a type-safe AI email enhancer using React 19 Server Functions, useActionState, Zod validation, and the Vercel AI SDK. Beyond the mechanics, it showed how server-first form handling and structured AI responses can turn raw input into polished communication with minimal friction. As AI features move from experimentation into core product workflows, reliability and developer experience have become non-negotiable. This piece focused on exactly that. By emphasizing type safety, server-side execution, and predictable form behavior, it anticipated a shift toward AI integrations that are trustworthy, maintainable, and production-ready. In 2026, this approach feels less like a demo and more like the baseline for serious AI-powered web apps. The shifts that defined 2025 TypeScript became GitHub’s #1 language: In August 2025, TypeScript crossed a symbolic threshold: it became the most used language on GitHub by contributor counts, overtaking both Python and JavaScript. TypeScript isn’t “just nicer types” anymore. It’s the default foundation for modern web app scale, and it fits the direction frameworks and AI-assisted coding are already pulling teams toward: more structure, fewer runtime surprises, and codebases that stay maintainable as they grow. AI became a baseline developer skill, not a differentiator:In August 2025, TypeScript crossed a symbolic threshold: it became the most used language on GitHub by contributor counts, overtaking both Python and JavaScript. TypeScript isn’t “just nicer types” anymore. It’s the default foundation for modern web app scale, and it fits the direction frameworks and AI-assisted coding are already pulling teams toward: more structure, fewer runtime surprises, and codebases that stay maintainable as they grow. WebAssembly 2.0 made the browser a serious performance platform: With Wasm 2.0 marked “official,” the story is less “new tech” and more “this is stable enough to bet on.” WebAssembly keeps showing up where JavaScript naturally struggles: graphics-heavy experiences, compute-intensive features, and workloads that want near-native performance without leaving the browser. As Wasm matures, it quietly expands what “web app” can mean, turning the browser into a practical runtime for edge-case performance rather than a hard constraint teams work around. Tech jobs in 2025 quietly stabilized, even as layoffs stayed part of the story: After the brutal reset in 2022 and 2023, 2025 looked less like a rebound and more like a steady return to normal. Open roles kept inching up across startups and public tech companies, while layoffs were far less sweeping than the 2023 peak and increasingly concentrated in specific companies. The story of 2025 wasn’t a hiring frenzy, it was selective job creation and early signs that technical hiring is rebuilding momentum. JavaScript turned 30:Last year, our favorite semicolon-optional, closure-loving, eventually-async language turned 30. It’s officially old enough to rent a car, and it’s still picking up new features every year. Thirty years of function-scope confusion, a brief era where jQuery felt mandatory, and endless hours untangling asynchronous code. Through all of it, JavaScript stepped out of the browser, powered the rise of Node.js, and now runs everywhere from edge runtimes and cloud platforms to tiny devices. This week’s news corner JavaScript Rising Stars 2025 points to a new center of gravity: workflows: n8n emerged as the clear breakout winner, jumping from fifth place last year to number one with a record setting surge in GitHub stars, reflecting growing demand for AI powered automation and low code workflows. React continues to anchor the frontend world, reclaiming the top framework spot, while projects like shadcn/ui and react-bits underline the momentum around composable, design forward UI systems. On the backend, newcomer Motia signals a potential shift toward unified full-stack frameworks that collapse APIs, workflows, and AI agents into a single abstraction, making this year’s rankings less about incremental wins and more about where modern JavaScript development is heading next. Node.js shipped coordinated security releases across active lines: Node.js pushed security updates for v20.x, v22.x, v24.x, and v25.x on January 13, 2026, addressing multiple vulnerabilities across the active release lines. If you’re running Node in production, this is the kind of patch cycle you treat like a sprint task, not a “later” item. The practical move: check your runtime versions, plan a fast upgrade window, and make sure your dependency chain (especially anything touching HTTP, permissions, or request parsing) gets the same level of scrutiny. Angular 21.1 is landing, and the RC is already hinting at the direction: Angular 21.1 is expected imminently, and the 21.1.0-rc.0 release is a useful preview of what the team is tightening up next. Even if you don’t jump on minors day one, RC notes are a strong early warning system: they show what’s being stabilized, what’s being nudged into “new default” territory, and what might create friction in apps that sit a little off the happy path. Claude Code added Tool Search, making “tool use” feel less manual:Tool Search is now showing up in the Claude ecosystem, and it changes the ergonomics of agentic coding. Instead of you hard-wiring a small set of tools into context, the system can discover and select from a broader tool universe without blowing up the prompt budget. The result is less ceremony around “which tool do I expose,” and more momentum when you’re moving between code, docs, and actions. What do you want more of in 2026? Hit reply and tell us! Aaand that’s a wrap! This issue is a reset around one idea: web dev is rewarding teams that build with clearer contracts and tighter guardrails. From async control and resilient error states to TypeScript’s rise, production-ready AI workflows, and WebAssembly getting practical, the direction is the same. Even this week’s updates fit the pattern: patch Node, track Angular’s next release, and watch how tool-first coding is evolving. Before you close this tab, pick one default you’ve been relying on and tighten it. If something surprises you, hit reply and tell us what you learned. Cheers! Editor-in-chief, Kinnari Chohan Have any ideas you want to see in the next article? Hit Reply! SUBSCRIBE FOR MORE AND SHARE IT WITH A FRIEND! *{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}} @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} }
Read more
  • 0
  • 0

Kinnari Chohan
02 Feb 2026
9 min read
Save for later

WebDevPro #124: Why Modern JavaScript Feels Fragmented, Plus This Week’s Updates

Kinnari Chohan
02 Feb 2026
9 min read
Crafting the Web: Tips, Tools, and Trends for Developers Advertise with Us|Sign Up to the Newsletter @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } WebDevPro #124 Why Modern JavaScript Feels Fragmented, Plus This Week’s Updates Crafting the Web: Tips, Tools, and Trends for Developers Webinar: How to Build Faster with AI Agents Learn how full‑stack developers boost productivity by 50% with AI agents that automate layout, styling, and component generation through RAG and LLM pipelines. See how orchestration and spec‑driven workflows keep you in control of quality and consistency. Save your seat! Welcome to this week’s issue of WebDevPro! Before we get into the updates and tools, let’s start with a familiar moment. Imagine this. You’re deep in a JavaScript codebase, following a clean map and filter chain, when you suddenly land in a class full of mutable state and lifecycle methods. Same language, different mental model. That shift is easy to miss, but over time, it adds real cognitive overhead. Modern JavaScript often feels more complicated than it needs to be, even when the syntax itself is familiar. JavaScript doesn’t neatly transition from one programming style to another as projects grow. Instead, it accumulates them. You might begin with step-by-step procedural code, adopt functional patterns along the way, and later introduce object-based structures to manage scale. In practice, most real-world codebases blend all three. In this issue, we'll start with a deep dive into JavaScript, looking at how that layering came to be, why it can make code harder to reason about, and how to approach those tradeoffs with more intention. Then we will move on to the key updates from the past week, and wrap up with a tool worth adding to your workflow. Procedural thinking as the foundation For many developers, procedural logic is the starting point. Programs are expressed as a sequence of steps executed in a clear and predictable order. Control flow is explicit, and it is easy to follow how data moves through the program. Loops and conditional statements play a central role in this style. They make execution order visible and help explain how decisions affect program behavior. for (let i = 0; i < items.length; i++) { if (items[i].active) { handle(items[i]) } } This approach emphasizes execution order and state changes. It works well when programs are small and logic is linear. Importantly, this style never disappears. Even as programs grow, procedural code remains a valid and familiar tool. Introducing functional patterns As programs become more complex, functional patterns begin to appear more frequently. Array methods and callbacks provide a more concise way to work with collections and reduce repetitive looping logic. Instead of describing how a loop executes, this style focuses on what transformation is applied to the data. items .filter(item => item.active) .forEach(handle) Here, intent is clearer, but control flow is less explicit. Readers must understand how each method behaves and how functions are applied. For some, this improves readability. For others, it introduces a new layer of abstraction that requires adjustment. Crucially, this style does not replace procedural logic. Both approaches coexist, and developers are expected to move between them as needed. Shifting toward composition As functional ideas are reinforced, composition becomes more prominent. Functions are treated as reusable building blocks that can be passed around and combined. This encourages thinking in terms of data flow rather than execution steps. Logic is expressed by chaining operations together, which can make intent clearer while obscuring the underlying sequence of events. At this stage, developers are often working with at least two distinct paradigms simultaneously: procedural control flow and functional composition. Object-based organization for larger programs As programs grow further, object-based organization emerges as a way to manage complexity. Classes and objects group related data and behavior, providing a structural model for larger systems. class ItemHandler { handle(item) { if (item.active) { // ... } } } This approach shifts the focus again. Instead of steps or transformations, code is organized around responsibilities and roles. Object-based organization can improve clarity in large programs, but it introduces a third way of thinking. Procedural, functional, and object-oriented styles now coexist within the same language and often within the same codebase. Accumulation instead of replacement A defining characteristic of JavaScript is that new paradigms are added without removing older ones. Procedural logic remains valid even as functional patterns appear. Functional composition continues to be useful when object-based structures are introduced. Nothing is deprecated at the architectural level. Every style remains available, and developers are free to choose the approach that fits the problem at hand. This cumulative nature explains why JavaScript codebases often contain a mixture of paradigms. The language supports each style equally and does not enforce a single architectural direction. Understanding the resulting tension As paradigms accumulate, readers and developers must constantly adjust how they interpret code. Different sections of a program may require different mental models depending on the style being used. This flexibility is powerful, but it increases cognitive load. Understanding a program requires not only knowledge of syntax, but also awareness of which paradigm is currently in play. Maintaining consistency becomes more challenging as programs grow. The same language constructs can support multiple architectural interpretations depending on context. Final words JavaScript is not broken. It is intentionally flexible. The challenge is not choosing the right paradigm, but navigating multiple paradigms at once. When procedural logic, functional composition, and object-based organization coexist, developers must be deliberate about how and when each style is used. Understanding how these paradigms accumulate rather than replace one another helps explain why modern JavaScript can feel complex even when the individual concepts are familiar. Want to go deeper? JavaScript from Beginner to Professional is a solid pick for developers transitioning into JavaScript. It uses more than 100 practical exercises and projects to develop real, working JavaScript skills. This Week in the News ⚙️ Node.js v25.5.0 Is Out:Node.js has shipped v25.5.0, continuing the steady pace of updates ahead of the next LTS release. This one focuses on runtime fixes and smaller improvements rather than headline features. If you like keeping an eye on where Node is heading next, this release is worth skimming through. 🧱 The Boring JavaScript Stack Reaches v1.0: The Boring JavaScript Stack has officially hit v1.0, and the name is very much intentional. It is an opinionated full-stack starter built with Sails, Inertia, Tailwind CSS, plus your choice of Vue, React, or Svelte. The goal here is fewer decisions, less setup churn, and getting to actual product code faster. 🧠 A Conversation with Anders Hejlsberg: Last week’s interview with Anders Hejlsberg offers a thoughtful look into the mindset of one of the most influential language designers behind C# and TypeScript. The discussion touches on language evolution, long-term trade-offs, and what it takes to design tools that scale with both developers and ecosystems. For an overview of the conversation, Aaron Winston summarizes Hejlsberg's lessons from C# and TypeScript on fast feedback loops, scaling software, open source visibility, and building tools that last. Beyond the Headlines 🐢 Fixing TypeScript Performance Problems:If your TypeScript project has started to feel slow, this article will feel very familiar. It walks through common causes of sluggish builds and editor lag in larger TS codebases. There are practical fixes here that teams can apply without rewriting everything from scratch. 🧭 JavaScript Frameworks Heading Into 2026: This is a community-driven look at how JavaScript frameworks are shaping up as we move toward 2026. It talks less about hype cycles and more about adoption, trade-offs, and long-term sustainability. A good read if you are thinking about whether to stick, switch, or wait with your current stack. 🅰️ Angular Community Stories and Signal Forms: The Angular team shares new community stories along with real-world code samples. There is also an update on Signal Forms, which builds on Angular’s signals model for handling reactive forms. If you work on form-heavy Angular apps, this is a useful glimpse into where things are going. 🤖 How Cursor Shipped Its Coding Agent: This post breaks down how Cursor built and shipped its AI coding agent. It goes into architectural decisions, trade-offs, and the realities of putting an AI-assisted dev tool into production. A solid behind-the-scenes read if you are curious about how modern developer tools are actually built. Tool of the Week ⚡Bun Gets Faster with v1.3.7 Bun shipped v1.3.7 last week with a JavaScriptCore update that brings noticeable performance gains, including faster async and await handling and ARM64 improvements. There’s also a new option to generate profiling data in Markdown for easier sharing, along with native support for JSON5 and JSONL. If you are curious why Bun keeps gaining traction, this article is still a good explainer on what’s driving its adoption. That’s all for this week. Have any ideas you want to see in the next article? Hit Reply! Cheers! Editor-in-chief, Kinnari Chohan SUBSCRIBE FOR MORE AND SHARE IT WITH A FRIEND! *{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}} @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} }
Read more
  • 0
  • 0

Kinnari Chohan
09 Feb 2026
3 min read
Save for later

WebDevPro #125: Where AI actually saves time in modern development workflows

Kinnari Chohan
09 Feb 2026
3 min read
Crafting the Web: Tips, Tools, and Trends for Developers Advertise with Us|Sign Up to the Newsletter @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } WebDevPro #125 Where AI actually saves time in modern development workflows Crafting the Web: Tips, Tools, and Trends for Developers Hi , Welcome to this week’s issue of WebDevPro! Aditya Agarwal, Facebook’s 10th employee and former CTO of Dropbox, sparked a wider conversation in the developer community this week after sharing a personal reflection about coding with Claude, Anthropic’s AI assistant. After a weekend building with Claude, he wrote: “It was very clear that we will never ever write code by hand again.” Then he admitted something more surprising: He felt happy, but also disoriented. Now that isn’t a prediction for “someday.” It’s a workflow shift happening right now. The real challenge for most teams isn’t access to AI. It’s integration. How do you apply AI to scaffolding, debugging, refactoring, UI generation, and delivery pipelines without disrupting your stack or compromising quality? That’s why this upcoming Progress workshop stood out to us. It’s designed to help developers integrate AI into real workflows, without losing control over quality, security, or governance. Webinar: AI for Developers – How to Achieve a 50% Productivity Boost If interested, sign up here This session breaks down technical workflows, architectural considerations, and hands-on demos showing how AI can augment development tasks, without requiring framework changes or replatforming. We’ll cover topics you care about: AI‑Assisted Component Scaffolding How AI can generate baseline UI components, form logic, data-binding structures, and reduce initial setup time. Debugging & Refactoring Using AI Agents Techniques for leveraging AI to identify bottlenecks, suggest optimized patterns, and modernize legacy code. AI‑Enhanced UI Development with Kendo UI & Telerik Practical examples of generating boilerplate, bindings, CRUD screens, tests, and documentation directly from your existing tech stack. Integrating AI into Dev Workflows Where AI fits into CI/CD, code reviews, architectural planning, prototyping, and cross-team collaboration. How Teams Achieve Measurable Gains (up to 50%) Real scenarios showing reduced time spent on repetitive implementation tasks, improved code consistency, and faster iteration cycles. Security & Practical Limitations What to automate, what not to automate, and how to ensure AI‑generated code aligns with team standards. Who should attend: Senior devs building complex front‑end or full‑stack applications Dev leads and architects driving technical decision‑making Teams exploring AI adoption without changing their existing stack Register & Save Your Seat! 👉 Join the webinar and see how AI can be embedded into real engineering workflows. 📅 February 26, 2026 ⏰ 9:30 PM GMT+5:30 Secure your spot! SUBSCRIBE FOR MORE AND SHARE IT WITH A FRIEND! *{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}} @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} }
Read more
  • 0
  • 0

Kinnari Chohan
16 Feb 2026
11 min read
Save for later

WebDevPro #126: Using AI in Development Without Losing Architectural Control

Kinnari Chohan
16 Feb 2026
11 min read
Crafting the Web: Tips, Tools, and Trends for Developers Advertise with Us|Sign Up to the Newsletter @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } WebDevPro #126 Using AI in Development Without Losing Architectural Control Crafting the Web: Tips, Tools, and Trends for Developers Webinar: How to Build Faster with AI Agents Learn how full‑stack developers boost productivity by 50% with AI agents that automate layout, styling, and component generation through RAG and LLM pipelines. See how orchestration and spec‑driven workflows keep you in control of quality and consistency. Save your seat! Welcome to this week’s issue of WebDevPro. If you’ve written any meaningful amount of code recently, AI is already part of your workflow. It finishes your lines, scaffolds components, suggests refactors, and removes a lot of the friction from day-to-day implementation. At the same time, more teams are shipping AI-powered capabilities directly into their products. The productivity gains are real. Development moves faster. Experimentation becomes easier. But speed introduces a structural question that doesn’t get talked about enough. When implementation becomes this easy, AI can start shaping architecture by default. Not through dramatic failures, but through small decisions that slip in unnoticed. A suggestion becomes a pattern. A pattern becomes the norm. Over time, structure starts drifting, responsibilities blur, and the codebase becomes harder to reason about. This piece looks at how to prevent that. We’ll look at practical ways to keep architectural control while still using AI heavily: how to set guardrails before generating code, where AI logic should live once it becomes part of your product, and what to review so “correct” output doesn’t slowly weaken your design. AI should accelerate implementation, not quietly define structure or responsibility. When Implementation Speed Becomes the Default When AI integrates into the development environment, the nature of coding changes. Developers move from writing every line manually to reviewing and selecting generated suggestions. That shift is efficient, but it also changes what drives consistency in a codebase. Suggestions are generated from generalized patterns. They can be correct, but correctness is not the same as architectural alignment. A project’s structure depends on decisions that hold across features, not on what looks plausible inside a single file. Encode Guardrails Before You Generate One practical way to preserve architectural control is to define expectations before generation. In practice, this means writing down the constraints that matter in your codebase so the assistant consistently reinforces them. For example, a strong instruction set begins by defining the development role clearly: You are an expert in TypeScript, Angular, and scalable web application development. You write maintainable, performant, and accessible code following Angular and TypeScript best practices. From there, it becomes easier to add concrete constraints that prevent structural drift. Even a small rule can make a difference, such as discouraging weak typing: Avoid the any type; use unknown when type is uncertain This kind of guidance does not guarantee perfect output. It does something more important: it keeps the assistant working within a defined standard instead of inventing one through suggestion. When AI Becomes Part of the Application The architectural stakes rise when AI is not only assisting development but also powering feature behavior. At that point, the questions are no longer about scaffolding. They become questions of placement, responsibility, and cohesion. One useful pattern is to configure AI behavior deliberately through a system instruction and then route all interaction through a structured interface. Example model configuration and system instruction: const instructions = ` Welcome to citypass. You are a superstar agent for this car parking validator. You will assist users by submitting parking tickets. You can convert date phrases to ISO strings and act as a geocode service to convert a location or address to coordinates long/lat. `; const ai = getAI(firebaseApp); const model = getGenerativeModel(ai, { model: 'gemini-2.5-flash', systemInstruction: instructions, tools: [toolset] }); this.chat = model.startChat(); This approach makes two architectural decisions explicit. First, AI behavior is constrained by a clear instruction. Second, interaction happens through a controlled interface instead of being scattered across unrelated parts of the application. A Practical Boundary: UI for Input, Services for Processing When AI is exposed to users, architectural control often comes down to a simple boundary. The UI collects input and shows results. The AI processing stays encapsulated behind an interface that can be tested and evolved. A clean example is offering an “AI Creator” entry point near an existing workflow, opening a modal to capture a prompt: Ticket creation flow with an AI Creator entry point used to capture user input for AI-assisted ticket creation. AI Creator button and modal markup: <button nz-button nzType="link" type="button" (click)="isVisible.set(true)" >AI Creator </button> <nz-modal [(nzVisible)]="isVisible" nzTitle="AI Creator" (nzOnCancel)="isVisible.set(false)" (nzOnOk)="ok()"> <ng-container *nzModalContent> <textarea [(ngModel)]="prompt" rows="3" placeholder="Enter ticket details" nz-input> </textarea> </ng-container> </nz-modal> This interface design matters because responsibility stays clear. The component manages interaction and user input. The AI-driven work happens only when the user explicitly triggers it, and the application can decide where that processing belongs. The Drift Risk: Structure by Convenience AI rarely causes dramatic architectural failures. The more common risk is incremental drift. A generated approach is accepted, then repeated, and then becomes the default. Over time, similar features are built with slightly different patterns, responsibilities move across layers, and ownership becomes less obvious. This is why the guiding principle needs to be visible early in the workflow: AI should accelerate implementation, not make architectural decisions. Maintaining Architectural Control Architectural control in an AI-assisted workflow comes from a small set of repeatable practices: Define expectations before generation so the assistant reinforces standards Encapsulate AI-enabled behavior behind clear interfaces Review generated code for placement and responsibility, not only for correctness These practices keep speed from rewriting structure. Final words AI can absolutely increase velocity. It can also unlock product capabilities that would have been expensive or slow to build even a year ago. But long-term maintainability still comes down to structure. The difference is that AI changes how structure gets created. It can reinforce good decisions, or it can quietly introduce new patterns through convenience, repetition, and speed. That’s why boundaries matter. When they’re clear, AI becomes a multiplier for discipline. When they’re loose, drift becomes the default. AI should accelerate implementation, not quietly define structure or responsibility. Architectural control isn’t about resisting AI. It’s about staying deliberate while moving fast. Want to learn more? Get your copy of Angular Projects, 4th Edition now! This Week in the News 🧩TypeScript 6.0 beta and roadmap shift: TypeScript 6.0 beta introduces incremental improvements across type checking and configuration while laying groundwork for the long-discussed native rewrite in Go that promises serious performance gains. The team is clearly thinking beyond syntax tweaks and focusing on compiler architecture, which signals that large codebases and build speed are now central to the TypeScript story. For teams pushing monorepos or heavy CI pipelines, this roadmap matters more than any single feature flag. 📊 State of JavaScript 2025 survey results: The State of JavaScript 2025 survey provides a broad snapshot of how developers are working across the JS ecosystem. TypeScript continues to see strong adoption, reinforcing its position as a standard part of modern JavaScript development. In tooling, newer build systems and faster runtimes are gaining momentum, reflecting a clear preference for performance-focused developer experience. The survey also compares usage, satisfaction, and interest across frameworks, testing tools, browser APIs, and runtimes, highlighting which technologies feel stable and which are generating curiosity. Overall, the results show an ecosystem that is maturing around modern defaults while steadily evolving toward faster tooling and more streamlined workflows. ⚛️ State of React 2025: The State of React 2025 survey offers a data-backed look at how developers are building with React today. Core tooling remains strong: Next.js, React Router, and Redux continue to see widespread usage, while TanStack Query and Axios are common choices for data handling. On the build side, Vite has emerged as the dominant tool, reflecting the ecosystem’s shift toward faster development workflows. UI libraries like MUI and shadcn/ui show meaningful adoption, and modern state solutions such as Redux Toolkit are preferred when external state is needed. The results also highlight a practical trend: many teams still rely primarily on built-in React APIs for state management, reaching for external libraries only as complexity grows. Beyond the Headlines ⚡Running Next.js at Enterprise Scale:Next.js scales well, but enterprise usage needs more than default settings. This piece breaks down what changes when you’re running Next.js under real traffic: defining clear SLOs/SLAs, instrumenting performance monitoring, and understanding the framework’s request lifecycle so you can spot bottlenecks early. It also highlights practical architecture choices like using CDNs and caching effectively, picking the right rendering strategy (SSG vs SSR) per route, and planning for horizontal scaling with shared caches and load balancing. 🐢 Is Claude Code losing its engineering edge:This post critiques recent shifts in Claude Code’s behavior, arguing that guardrails and simplifications are reducing its usefulness for experienced developers who value precision and depth. It reflects a broader tension in AI tooling between safety, accessibility, and raw capability. For developers relying on AI as a serious engineering assistant, subtle model behavior changes can have an outsized impact on trust and workflow. 🧭 Debugging workflows that actually benefit from AI: An exploration of AI-assisted debugging workflows that break down how you can leverage models to trace issues, interpret stack traces, and accelerate root-cause analysis without feeling like you’re guessing at prompts. ⚛️ React Server Components performance insights: This piece examines how React Server Components behave in real world performance scenarios, moving past high level explanations to measure tradeoffs in rendering, hydration, and network boundaries. It challenges simplistic assumptions about automatic speed gains and highlights where architectural decisions still matter. For teams evaluating RSC adoption, the nuance here is critical before refactoring large parts of an app around the paradigm. Tool of the Week 🌀🛠️ OpenClaw — The AI Agent That Does Work for You OpenClaw is an open-source autonomous AI agent that goes beyond chat: it can execute real tasks like managing email, calendars, messaging apps, and other workflows by integrating with platforms such as WhatsApp, Telegram, and Slack. Developed by Austrian engineer Peter Steinberger, it grew from an experimental project into one of the fastest-adopted agent tools in the community because of its ability to act instead of just respond. Since its introduction in November, OpenClaw has seen a viral rise, surpassing 100,000 stars on GitHub and attracting 2 million visitors in a single week, signaling strong developer curiosity around agent-based systems. This week, OpenClaw made headlines when creator Peter Steinberger announced he’s joining OpenAI. Sam Altman highlighted Steinberger’s expertise in multi-agent systems as strategically important for building the next generation of personal AI assistants, and OpenClaw will continue as an open-source foundation supported by OpenAI. This move signals how quickly agent-centric tooling is becoming a central focus for major AI platforms. For anyone interested in trying OpenClaw yourself or seeing it in action, this tutorial walks through setup and use:📺 OpenClaw Full Tutorial for Beginners. That’s all for this week. Have any ideas you want to see in the next article? Hit Reply! Cheers! Editor-in-chief, Kinnari Chohan SUBSCRIBE FOR MORE AND SHARE IT WITH A FRIEND! *{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}} @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} }
Read more
  • 0
  • 0

Kinnari Chohan
23 Feb 2026
12 min read
Save for later

WebDevPro #127: Design Patterns as Decision Frameworks, Not Recipes

Kinnari Chohan
23 Feb 2026
12 min read
Crafting the Web: Tips, Tools, and Trends for Developers Advertise with Us|Sign Up to the Newsletter @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } WebDevPro #127 Design Patterns as Decision Frameworks, Not Recipes Crafting the Web: Tips, Tools, and Trends for Developers Unblocked: The context layer your AI tools are missing Give your agents the understanding they need to generate reliable code, reviews, and answers. Unblocked builds context from your team’s code, PR history, conversations, documentation, planning tools, and runtime signals. It surfaces the insights that matter so AI outputs reflect how your system actually works. See how it works Welcome to this week’s issue of WebDevPro. If you’ve been building and maintaining systems for a while, you’ve probably felt the friction that doesn’t show up in code reviews. And here’s something that doesn’t get said often enough: most engineering pain isn’t caused by bad code. It’s caused by unexamined decisions. Nobody deliberately optimizes for rigidity. Nobody sets out to make performance worse or future changes harder. But when trade-offs aren’t made explicit, that’s exactly where teams end up. You notice it when: A small requirement change forces a wide refactor A performance issue appears under load and the root cause isn’t obvious “Best practice” debates stall because everyone is arguing from instinct, not intent We’re often handed rules like these: Use strict equality Avoid blocking I/O Prefer Map over Object Use Set for deduplication Be careful with parseInt These guidelines are useful, especially early on. They prevent common mistakes. But over time, following rules without understanding the trade-offs turns into habit, not judgment. This week’s issue looks at patterns differently. Not as templates to apply or badges of clean code, but as decision frameworks. By the end of this article, you’ll start seeing what a piece of code is really optimizing for, notice the hidden costs behind everyday implementation choices, think more deliberately about where change should happen, and reframe conversations from “Is this correct?” to “What are we trading off?” That shift from applying rules to making deliberate trade-offs is where engineering starts to feel intentional. And that’s what we’re unpacking today. Code Shape and the Cost of Change Most problematic code works. That’s why it survives. createUser(name, email, password, phoneNumber, role = 'guest') There’s nothing obviously wrong here. Until the domain changes. Add a required field. Deprecate one parameter. Split roles into multiple variants. Now you’re updating dozens of call sites and hoping argument order wasn’t misused somewhere. Switching to object parameters: createUser({ name, email, password, phoneNumber, role = 'guest' }) This changes what the API optimizes for. Specifically, order stops mattering, adding fields becomes safer, and call sites become self-documenting. This is design thinking at the function level. You’re choosing a shape that absorbs change instead of amplifying it. Hidden Transformations and Predictability Loose equality in JavaScript produces results that surprise people: false == 0 // true '' == false // true [] == false // true These aren’t bugs; they follow the language’s coercion rules. The issue is that the conversion happens implicitly. When a comparison behaves unexpectedly, it looks like a logic error, not a type conversion chain. Using === keeps comparisons explicit. It removes hidden work. Parsing has similar edges. parseInt(0.0000005) // 5 parseInt converts its input to a string, then parses from the start until it hits an invalid character. A number like 0.0000005 may be represented as "5e-7", so parsing stops at "e". This is documented behavior. The problem isn’t the function. It’s assuming there are no intermediate transformations. The broader lesson: implicit conversions reduce clarity. When behavior depends on hidden steps, bugs become harder to reason about. Runtime Reality: Blocking Work and Delegation Node.js executes JavaScript on a single main thread that drives the event loop. CPU-heavy synchronous code blocks that thread. While it runs, nothing else progresses. That’s why synchronous work in request handlers can reduce throughput and increase latency under load. Asynchronous APIs often help because some operations can be delegated to the system or to worker threads (for example, many crypto operations have asynchronous variants). The main thread remains free to coordinate. But async alone doesn’t solve architectural problems. Performance often improves more by reducing how often expensive work runs than by simply changing it to async. Caching, batching, and eliminating redundant computation frequently have a bigger impact than switching APIs. The real pattern isn’t “async good, sync bad.” It’s understanding where your runtime is serial and designing accordingly. Data Structures as Cost Models Choosing between Object, Map, Array, and Set is about workload and not preference. Objects fit well when: keys are known and stable you’re modeling record-like data JSON serialization matters Maps fit well when: keys are dynamic frequent insertions and deletions occur iteration order must be preserved non-string keys are required Arrays excel at ordered data and transformations. Sets excel at uniqueness and fast membership checks. No structure is universally better. Each implies a different cost model. When you align structure with usage patterns, the code becomes simpler and more predictable. Classic Patterns: Controlling Where Change Happens Design patterns get introduced as diagrams. Boxes, arrows, interfaces. In practice, nobody reaches for Strategy because they love abstractions. They reach for it because some piece of logic keeps changing and it’s starting to infect everything around it. Pricing rules change. Validation rules change. Feature flags change. If that logic is scattered across the system, every update becomes a small cleanup project. Strategy just gives that volatility a place to live. Observer shows up when components are getting too aware of each other. One module updates something and suddenly three others need to react. Hard-coded calls turn into a web of dependencies. Events or observers aren’t about elegance. They’re about reducing how much each part needs to know. Adapter is what you write when an external API doesn’t quite fit your model, and you don’t want your entire codebase shaped by someone else’s decisions. It’s a boundary. A buffer. None of these patterns are impressive on their own. What they’re really doing is controlling where change hurts. They add indirection, yes. That indirection costs something. But in return, you stop paying interest every time requirements shift. That’s the trade. Containment Over Cleverness There’s always a moment when modifying a prototype feels like a clever shortcut. You add a helper to Array.prototype so you don’t have to import a utility everywhere. You tweak Object.prototype to normalize something globally. It works. It even feels elegant. The catch is that you’ve quietly changed the rules for the entire runtime. Now every array in the system has that extra method. Every object inherits the behavior whether it asked for it or not. If something breaks, the failure won’t point back to your “nice little improvement.” It’ll surface somewhere unrelated, and debugging it will take longer than the shortcut saved. In small scripts, this might be fine. In shared codebases, libraries, or long-lived services, it’s a different story. The blast radius is bigger than it looks. Most engineers grow out of this not because someone tells them it’s wrong, but because they’ve spent a day tracing a bug back to a global modification they forgot existed. After that, containment starts to feel a lot more attractive than cleverness. Final words: Making Trade-offs Explicit The deepest anti-pattern isn’t picking the “wrong” API but rather building for neatness today in places that are guaranteed to change later. That’s why patterns matter. Not because they’re clever, but because they force the trade-offs into the open: CPU vs latency memory vs speed coupling vs flexibility simplicity now vs adaptability later Used like recipes, patterns turn rigid fast. Used like decision frameworks, they do something much more valuable: they make teams talk about consequences instead of preferences. You spend less time arguing about “best practices,” and more time agreeing on what kind of system you’re actually building. That’s the shift from following rules to developing engineering judgment. This Week in the News 🧩TypeScript 6.0 Beta Is Here and 7.0 Will Change More Than You Think: TypeScript 6.0 is now in beta and while it looks like a transitional release, it lays the groundwork for the Go-based TypeScript 7. Some changes may subtly affect existing projects, especially around deprecated behaviors and internal shifts. This is the release to test against early so you are not caught off guard when 7.0 lands with deeper architectural changes. 🌐 WebMCP and EPP Show Where Chrome Wants the Web to Go Next: With WebMCP and EPP, Chrome is exploring structured communication between web apps and external processes. This could reshape how developer tools, AI agents, and browser-based apps coordinate capabilities. If you care about automation-heavy workflows or AI-assisted development, this signals where the platform is heading. 🔗 npm Just Made Supply Chain Security Harder to Ignore: npm 11.10.0 rolls out bulk trusted publishing configuration and stronger lifecycle script protections. Teams managing multiple packages can now streamline trusted publishing, while script security improvements reduce risk from malicious or unexpected install-time behavior. Worth reading if you maintain libraries or ship production packages regularly. 🛠️ Interop 2026 Aims to Remove More Cross Browser Headaches: Interop is a yearly cross-browser effort where engine teams align on specific platform features and work together to close gaps in behavior and support. Interop 2026 is now announced, continuing the collaboration between WebKit, Chromium, and Gecko with a fresh set of focus areas. For developers, it is one of the most reliable signals of which web platform fixes are actually likely to land across all major browsers. Beyond the Headlines ⚡Node vs Deno vs Bun Benchmarks Show Where the Real Gaps Are: Fresh performance benchmarks compare Node.js, Deno, and Bun across real-world scenarios rather than synthetic micro tests. The results challenge a few common assumptions about which runtime is “fastest” and where that speed actually matters. Worth reading before you make runtime decisions based purely on hype or benchmark screenshots. 🧠 Performance Is Not a Technical Problem: This essay argues that most performance issues stem from priorities, incentives, and product decisions rather than raw engineering limits. It reframes optimization as a cultural and organizational question, not just a profiling exercise. A sharp perspective shift for anyone working on growing codebases where “we’ll fix it later” keeps winning. ♟️What Deep Blue Still Teaches Us About AI Hype: Simon Willison revisits IBM’s Deep Blue moment and connects it to today’s AI narratives. The piece explores how milestone victories shape public perception, funding, and expectations long after the headlines fade. A thoughtful read for developers navigating the current AI wave and trying to separate signal from spectacle. 🧵 HTTP in Node.js Gets Tricky Fast and This Guide Explains Why: Making an HTTP request in Node.js looks simple until you hit retries, timeouts, streaming, backpressure, and error handling in real production code. This deep dive breaks down the patterns that help you move beyond quick fixes and build request logic that stays reliable under load. It’s also a great preview of the thinking behind Node.js Design Patterns, one of the most practical books for developers building serious Node.js systems. Tool of the Week 🧮 Excelize Makes Spreadsheet Automation in Go Feel Like a Superpower If you’ve ever had to generate Excel reports, clean up spreadsheets, or build export pipelines, you already know the pain: most tooling is either fragile or wildly overcomplicated. Excelize, built by Ri Xuis an open-source Go library that makes working with real .xlsx files feel straightforward, from formatting and formulas to charts and large-file handling. The most interesting part is the story behind it. The write-up on how Excelize was builtshows what it takes to make “boring” infrastructure reliable: handling OpenXML edge cases, keeping the API Go-friendly, and evolving features without breaking existing users. It’s a strong example of how long-term OSS gets built, one painful spreadsheet at a time. Good developer tooling rarely starts as “let’s build a library.” It starts as “this keeps hurting, let’s fix it properly.” Excelize is the result of sticking with that fix long enough to turn it into real infrastructure. That’s all for this week. Have any ideas you want to see in the next article? Hit Reply! Cheers! Editor-in-chief, Kinnari Chohan Brought to you in cooperation with Unblocked: SUBSCRIBE FOR MORE AND SHARE IT WITH A FRIEND! *{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}} @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} }
Read more
  • 0
  • 0

Kinnari Chohan
02 Mar 2026
15 min read
Save for later

WebDevPro #128: TypeScript Under Pressure in Evolving Full Stack Systems

Kinnari Chohan
02 Mar 2026
15 min read
Crafting the Web: Tips, Tools, and Trends for Developers Advertise with Us|Sign Up to the Newsletter @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } WebDevPro #128 TypeScript Under Pressure in Evolving Full Stack Systems Crafting the Web: Tips, Tools, and Trends for Developers Most Spring Boot projects stop at REST APIs Real systems require service discovery, API gateways, centralized configuration, and built-in resilience. In this live, hands-on workshop, you’ll build a working microservices system end-to-end, define service boundaries, wire up discovery, configure a gateway, and handle failures properly. 🎟 Register now and get 40% off with code SAVE40 Welcome to this week’s issue of WebDevPro. This issue looks at a common transition in modern engineering: taking a fast proof of concept and turning it into something that can survive real change. Consider a small internal AI support chatbot. The architecture is simple. A React frontend collects messages and sends them to an Express POST /api/chat endpoint. The server returns a short reply. The goal here is speed, not durability. To move quickly, the frontend stores messages as any[]. The backend reads req.body.messages from untyped JSON and returns a response like: { "reply": "You said: hello" } There is no formal contract between frontend and backend. The agreement lives in shared understanding: reply is a string, and messages is an array of objects with role and content. When both sides are written close together, this feels stable. Then the requirements change. The reply must now include structured data: the assistant’s message, references, and follow-up questions. The backend evolves and begins returning an object under reply instead of a string. The frontend does not change. The build passes. The browser fails at runtime because React attempts to render an object as if it were a string. Nothing in the type system flagged the mismatch because nothing at the boundary defined what the response was supposed to be. This is where TypeScript either acts as a safety mechanism under change or becomes a thin layer of annotations. What follows is a practical look at how that same chatbot evolves into a production-safe system by making contracts explicit and boundaries deliberate. Phase One: Turning Assumptions into a Shared Contract The chatbot did not break because the change was complex. It broke because the change was invisible to the type system. On the frontend, state was typed as any[]. The API response was treated as whatever res.json() returned. On the backend, req.body was used without an explicit shape. From TypeScript’s perspective, there was nothing concrete to compare, so the change in response structure did not register as a problem. The fix was not adding defensive conditionals in the UI. It was introducing a shared domain contract and making both sides depend on it. Instead of allowing the frontend and backend to “just agree,” the system defines explicit types for: ChatMessage ChatRequest ChatReply ChatResponse These types live in a shared module that both the frontend and backend import. The frontend state becomes ChatMessage[]. The API call returns Promise<ChatResponse>. The backend handler constructs a value that must satisfy ChatResponse. At that point, the contract stops being an assumption and becomes code. If someone changes the shape of reply again, the compiler will force every dependent piece of code to reconcile with that change. The mismatch that previously appeared in the browser now appears during build. In practical terms, this shifts the feedback loop. Instead of discovering drift during manual testing or after deployment, the team discovers it the moment they try to compile. That difference seems small, but over time it fundamentally changes how safely a system can evolve. Phase Two: Making the Network Boundary Honest Introducing shared types stabilizes collaboration between frontend and backend. It does not solve everything. There is still one place where untyped data enters the system: the network boundary. On the backend, req.body arrives as raw JSON. On the frontend, res.json() returns data that TypeScript cannot inspect at runtime. Even with shared contracts, the system is still trusting external input. In the chatbot’s case, this matters more as the system grows. Deployments may not always be perfectly synchronized. A proxy or middleware layer might alter payloads. A partial rollout could temporarily mix versions of frontend and backend. Shared types alone cannot guard against that. The practical adjustment is simple but important: treat boundary data as unknown until it is validated. Instead of assuming that req.body matches ChatRequest, the backend checks that it actually does. Instead of assuming that res.json() returns a valid ChatResponse, the frontend verifies the shape before proceeding. These checks do not need to be elaborate. Lightweight type guards are enough to confirm that required properties exist and have the correct types. Once the data passes that validation step, the rest of the system can rely on strong typing with confidence. This introduces a clear separation of responsibilities: Outside the boundary, data is untrusted. Inside the boundary, data is guaranteed to match the domain contract. In day to day development, this prevents subtle corruption. Rather than allowing malformed data to move deeper into the UI or business logic, the system fails immediately at the edge. Errors become explicit and local instead of diffused and harder to trace. The chatbot remains small, but its architecture becomes more deliberate. The boundary is no longer a blind spot; it becomes a controlled entry point. Phase Three: Containing Vendor Volatility As the chatbot matures, another requirement arrives: support more than one LLM provider. This is a common inflection point. Early on, it is convenient to wire the backend directly to a single SDK. The response from the provider flows straight through the server and into the UI. It feels efficient. It also quietly couples your entire stack to a vendor’s response shape. If that vendor changes its format, or if you decide to introduce a second provider, the ripple effects can reach the frontend quickly. What began as a backend integration detail becomes a full-stack coordination problem. In the chatbot’s evolution, this risk is handled differently. Instead of exposing raw provider responses, the system defines a provider interface that returns a domain-level ChatReply. Each provider implementation adapts its own SDK response into that shared shape. The rest of the application does not know or care which provider generated the reply. It only understands the domain contract. This decision seems architectural, but it has very practical consequences. Switching providers or introducing a second one no longer forces a redesign of shared types. The volatility is contained. The surface area of change is smaller. TypeScript reinforces this separation. The compiler ensures that every provider implementation produces a valid ChatReply. The backend handler depends on the interface, not on vendor-specific JSON. In a growing system, this is what stability looks like. The parts that are likely to change are isolated behind clear contracts. The parts that need to remain steady, especially the frontend, are shielded from that churn. Phase Four: Making States Explicit as Features Expand Feature growth rarely stops at integration. The chatbot evolves again. Sometimes a response includes citations. Sometimes it does not. A quick solution would be to add optional fields. Over time, optional fields accumulate. The type becomes flexible, but also ambiguous. It becomes unclear which combinations are valid and which are accidental. Instead, the chatbot models these variations explicitly using a discriminated union. A response is either a plain answer or an answer with citations, and the kind field identifies which one it is. On the frontend, rendering logic switches on that kind. The exhaustive check ensures that every variant is handled. This design choice has a subtle but important effect. When a new response variant is introduced later, the compiler highlights every place that must adapt. Nothing slips through unnoticed. In everyday development, this reduces the risk of partial updates. The type system becomes a guide for refactoring, not just a static annotation layer. The chatbot still feels small. The difference is that its possible states are no longer implied. They are declared. Phase Five: Removing Quiet Type Erosion As the chatbot grows, new endpoints appear. Health checks. Admin actions. Maybe analytics or feedback capture. The API surface expands gradually. This is usually where small shortcuts start accumulating. A common one looks harmless: const data = (await res.json()) as ChatResponse; The cast makes the compiler quiet. It also shifts responsibility back to the developer. At the exact point where the system is most exposed to incorrect data, you are asserting that everything is fine. In a small codebase, this feels manageable. In a growing one, these assertions multiply. Over time, they erode the safety you thought TypeScript was providing. In the chatbot’s evolution, this problem is addressed structurally rather than procedurally. Instead of scattering casts, the system defines a mapping between route literals and their request and response types. The endpoint determines the shape. The generic client enforces it. Now the type of /api/chat is tied directly to ChatRequest and ChatResponse. You cannot accidentally call the wrong endpoint and pretend it returns something else. The compiler resolves the relationship based on the route itself. This removes a category of silent drift. It also makes the API surface self-documenting. When someone adds a new endpoint, they define its contract in one place, and the rest of the system aligns automatically. It is a small shift in structure, but it prevents gradual type erosion. What This Evolution Actually Achieved The chatbot still answers questions. The UI still renders messages. The architecture is not radically different from the initial proof of concept. What changed is where mistakes surface. At first, mismatches appeared in the browser. After shared contracts, they appeared during compilation. After boundary validation, they appeared at the edge of the system. After isolating providers, vendor changes stopped leaking across layers. After modeling variants explicitly, feature growth became safer. After tightening endpoint typing, unsafe assumptions stopped spreading quietly. None of these changes required advanced language features. They required clarity about boundaries and discipline about contracts. In a system that evolves under real-world pressure, assumptions are the most fragile dependency. TypeScript is most valuable when it turns those assumptions into enforceable structure. The chatbot did not become more sophisticated for its own sake. It became more predictable under change. For a deeper exploration, pre-order Clean Code with TypeScript. The book takes a detailed look at the evolving chatbot system and walks through the architectural decisions, trade-offs, and production considerations behind it. If you’re a PacktPub subscriber, you can access the Early Access version right away. This Week in the News ☁️ Cloudflare rebuilds Next.js on Vite: Cloudflare unveiled vinext, an experimental reimplementation of the Next.js API surface built on Vite, reportedly put together in a week using AI coding agents and the official Next.js test suite as a spec. Instead of adapting Next’s build output for non-Vercel platforms, Cloudflare rebuilt the framework layer itself to make deployment on its infrastructure more natural. vinext already supports routing, SSR, React Server Components, server actions, middleware, and both routing systems, passing about 94 percent of the Next 16 test suite. Cloudflare claims faster builds and smaller client bundles in early benchmarks, while calling the results directional. It is still early, but this is a bold signal in the ongoing platform versus framework conversation. 🅰️ Angular Skills for coding agents: Angular developers can now equip their coding agents with “Angular Skills,” a set of curated defaults and patterns designed to guide agents toward modern Angular best practices. The project packages conventions, structure, and tooling preferences so AI-assisted workflows generate code that feels aligned with today’s Angular ecosystem. Do agent skills materially improve output quality? That remains to be seen. At the very least, they formalize standards and make human intent more explicit, which may be half the battle in AI-assisted development. 🟢Node.js 24.14.0 LTS and 25.7.0 Current released: Node shipped both an LTS and a Current release this week, and this one is more than routine version churn. The LTS update tightens up async_hooks, improves fs.watch reliability, adds proxy configuration support, and begins exposing early ESM embedder API enhancements. If you’re running backend services, SSR stacks, or dev tooling that leans on Node internals, these changes are practical, not cosmetic. Meanwhile, 25.7.0 Current gives a preview of where the runtime is heading. Framework maintainers and teams with native modules should treat this as a signal to test early and avoid CI surprises later. 📈 OpenClaw briefly overtakes Python projects on GitHub: A retro game reimplementation project saw a spike in GitHub activity that temporarily outranked major Python repositories. While largely a trend metric, this serves as a reminder that GitHub stars and ranking spikes do not always reflect lasting ecosystem impact. For developers, this is a useful gut check. Popularity metrics can highlight energy, but they don’t always indicate production relevance or long-term impact. 🤖 Claude Code turns one as distillation dispute surfaces:Anthropic marked the first anniversary of Claude Code while raising concerns about competitors using Claude outputs to train rival models through large-scale distillation. The discussion moves beyond company rivalry and into deeper questions around model output ownership, competitive boundaries, and how AI tooling companies protect their work. For developers building AI-powered products, this matters. The ecosystem is still defining what is acceptable reuse, what is extraction, and where legal lines will be drawn. Tooling decisions today are increasingly shaped by these policy and governance shifts 🏛️ React moves to the Linux Foundation:React and React Native are now governed by a newly formed React Foundation under the Linux Foundation. This shifts stewardship from a single corporate sponsor to neutral, open governance. For teams betting their front end architecture on React, this reduces long-term platform risk. Governance stability may not feel urgent in daily development, but it quietly shapes the future of roadmaps, community trust, and ecosystem continuity. Beyond the Headlines 🦀 Ladybird adopts Rust for new components: The Ladybird browser project is moving new development to Rust, citing safety and maintainability. This isn’t just about language preference. It reflects the industry’s steady migration toward memory-safe systems programming in infrastructure-level code. The browser space has historically been C and C++. Rust’s continued expansion here signals that safety is becoming a baseline expectation, not a luxury. 🤖 The five stages of AI agents: A useful framework is emerging around how AI agents evolve: from basic task automation to more autonomous, goal-oriented systems. For developers experimenting with AI workflows, this gives structure to what can otherwise feel like hype. The takeaway is simple. Not every workflow needs autonomy. Understanding where your system sits on that spectrum prevents overengineering and keeps expectations grounded. 🧠 Mitchell Hashimoto on AI adoption: Mitchell Hashimoto, the co-founder of HashiCorp shared a candid look at integrating AI tools into his workflow. Not evangelism. Not backlash. Just a practical breakdown of where AI speeds things up and where it still falls short. That grounded middle space is where most developers are operating right now. AI is useful. It is not magic. And thoughtful integration beats blanket adoption. Refactoring production systems is risky, especially when API changes and hidden coupling are involved. In this Deep Engineering session, learn how to safely evolve real-world codebases using ast-grep and Claude Code, with practical guardrails you can apply immediately. Use code WDP40 to get 40% off your seat. Tool of the Week 🛡️ Zod Makes Runtime Validation Feel Native to TypeScript If you’ve ever trusted req.body a little too much or written as SomeType just to quiet the compiler, you already know the pain: TypeScript disappears at runtime. The type system keeps you safe inside your codebase, but JSON at the network boundary remains unchecked. Zod solves that gap cleanly. It’s a TypeScript-first schema validation library that lets you define runtime validation and static types in one place. You describe the shape once, validate incoming data against it, and automatically infer the TypeScript type. No duplication. No drift between interface and validator. The real value shows up under change. When your API evolves or a provider shifts its response format, Zod forces the mismatch to surface immediately at the boundary instead of leaking deeper into your system. It turns assumptions into enforced contracts. Good architecture is often about making edges explicit. Zod gives those edges structure. That’s all for this week. Have any ideas you want to see in the next article? Hit Reply! Cheers! Editor-in-chief, Kinnari Chohan SUBSCRIBE FOR MORE AND SHARE IT WITH A FRIEND! *{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}} @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} }
Read more
  • 0
  • 0
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at $19.99/month. Cancel anytime
Kinnari Chohan
09 Mar 2026
12 min read
Save for later

WebDevPro #129: Why Single Page Applications Changed How We Build Web Apps

Kinnari Chohan
09 Mar 2026
12 min read
Crafting the Web: Tips, Tools, and Trends for DevelopersAdvertise with Us|Sign Up to the Newsletter @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} }WebDevPro #129Why Single Page Applications Changed How We Build Web AppsCrafting the Web: Tips, Tools, and Trends for DevelopersMost Spring Boot projects stop at REST APIsReal systems require service discovery, API gateways, centralized configuration, and built-in resilience. In this live, hands-on workshop, you’ll build a working microservices system end-to-end, define service boundaries, wire up discovery, configure a gateway, and handle failures properly.🎟 Register now and get 40% off with code SAVE40Welcome to this week’s issue of WebDevPro!Take a moment to think about the web apps you use every day. A dashboard updates without refreshing the page. A chat window receives messages in real time. A project board moves tasks across columns instantly.Modern web applications behave very differently from traditional websites. Interfaces update instantly, dashboards refresh without reloading the page, and navigation feels closer to using installed software than browsing documents. This experience is powered by an architectural shift called the Single Page Application, or SPA.By the end of this article, you will understand three things that shape modern frontend systems. First, what actually defines a Single Page Application beyond the buzzword. Second, why the SPA model improves responsiveness and interactivity in web applications. And third, how React enables this architecture through its rendering model and state-driven design.This is not a tutorial about setting up React or writing components. Instead, the goal is to understand the architectural thinking behind SPAs and how React fits into that model.The architectural shift behind modern web appsEarly websites were built around a page-based model. Each interaction triggered a request to the server, which generated a new HTML document and returned it to the browser. This worked well when the web primarily delivered content.Modern web applications demand a different experience. Consider tools such as analytics dashboards, project management systems, or collaborative editors. Users interact continuously with the interface. Data updates frequently, UI elements move around the screen, and navigation happens rapidly.In a traditional page-driven architecture, each of those interactions would require a server request and a full page refresh. Even small updates would rebuild the entire interface.Single Page Applications address this limitation by shifting the responsibility for rendering the interface into the browser itself.Instead of repeatedly requesting new pages, the browser loads the application once and then updates the interface dynamically as data changes. This change might sound simple, but it transforms the browser from a document viewer into a runtime environment for applications.What actually defines a Single Page ApplicationThe term “Single Page Application” can be misleading. It does not mean an application literally has only one page in the user experience. Instead, it describes how the application is delivered and rendered.A SPA typically loads a single HTML document that acts as a container for the application. Once the application initializes, JavaScript takes responsibility for rendering and updating the interface.From that point onward, most user interactions modify the current interface rather than loading new documents.Several architectural patterns define this approach.Client-side renderingIn a traditional website, the server generates HTML for each page request. In a SPA, the browser renders most of the interface.The server still plays an important role. It provides data through APIs and delivers the initial application bundle. However, the frontend application determines how that data appears on the screen.This allows the interface to update instantly when new data arrives.Persistent application runtimeBecause the application remains loaded in the browser, its logic persists across user interactions.Instead of rebuilding the interface from scratch, the system modifies the existing UI based on changes in application state.This persistence allows applications to maintain context and update small pieces of the interface without resetting the entire page.Virtual navigationUsers still see URLs change when navigating through a SPA, but the navigation logic is handled inside the application rather than by the server.The application interprets the URL and determines which components to display. From the user's perspective, the experience feels like normal navigation. Internally, the browser remains on the same underlying document.Together, these characteristics create the foundation of SPA architecture.Why the SPA model improves responsivenessThe key advantage of SPAs is not simply that they avoid page reloads. The deeper benefit is that they reduce unnecessary work.In a page-based system, the browser discards the entire interface whenever a new page loads. The server reconstructs the page, sends it back, and the browser renders it again.In a SPA, the application updates only the parts of the interface that change.Once the application code is loaded, the browser already contains everything needed to update the UI. When data changes, the system redraws only the relevant components rather than rebuilding the entire page.This approach becomes particularly valuable in highly interactive environments.Imagine a data dashboard where metrics update continuously while users filter results, adjust settings, and move between views. Rebuilding the entire interface for each interaction would create unnecessary delays.SPAs allow these updates to happen immediately because the rendering logic runs locally in the browser.However, this architecture introduces new complexity. The browser must now manage application state, UI rendering, and navigation. Without structured tools, this quickly becomes difficult to maintain.This challenge is where frameworks such as React play an important role.How React enables SPA architectureReact does not directly implement the SPA model. Instead, it provides a system that makes managing dynamic interfaces significantly easier.At its core, React helps developers answer a difficult question: how should the interface update when application data changes?Instead of manipulating the browser DOM directly, React introduces a model where the UI is described as a function of application state.This approach rests on two key ideas: the Virtual DOM and state-driven rendering.The Virtual DOM and efficient UI updatesEvery webpage contains a structure known as the Document Object Model, or DOM. The DOM represents the hierarchy of elements that make up the interface.Updating the DOM directly can become expensive when applications contain large numbers of elements or frequent updates.React addresses this problem through the Virtual DOM.The Virtual DOM is an in-memory representation of the interface maintained by React. When application state changes, React creates a new representation of the interface and compares it with the previous version.This comparison process determines exactly what has changed between the two states.React then updates only those elements in the real DOM that need to change. This process is often referred to as reconciliation.By reducing the number of direct DOM operations, React helps maintain performance even when applications grow large and complex.State as the driver of the interfaceThe second important idea in React is that the interface should be driven by state.React applications are built from components, each representing a piece of the user interface. Components maintain state that describes the data they display.When that state changes, React automatically updates the component's output and reconciles the differences in the DOM.A simplified example illustrates the concept.import { useState } from "react";function Counter() { const [count, setCount] = useState(0); return ( <button onClick={() => setCount(count + 1)}> Count is {count} </button> );}In this example, the interface is directly derived from the value of count. When the state changes, React recalculates the component output and updates the interface accordingly.Developers do not manually manipulate DOM elements. Instead, they describe how the interface should look given a particular state.This declarative model simplifies reasoning about complex interfaces. It also aligns naturally with the needs of Single Page Applications, where the interface must update frequently in response to data changes.Why React became central to modern frontend developmentReact's design aligns well with the requirements of SPA architecture.Component-based design allows large interfaces to be broken into smaller, manageable pieces. Each component encapsulates its logic, state, and rendering behavior.The Virtual DOM helps maintain performance by minimizing unnecessary DOM updates. Meanwhile, React's state-driven model ensures that the interface stays synchronized with application data.Together, these ideas provide a structured approach to managing dynamic user interfaces.This combination of performance and developer ergonomics helped React become one of the most widely used frameworks for building modern web applications.Final wordsSingle Page Applications represent a shift in how the web is used. Instead of treating the browser as a document viewer, modern applications treat it as an execution environment for complex software.This architectural shift allows web applications to behave more like native software, delivering responsive interfaces and fluid user experiences.Understanding SPAs means understanding three core ideas. First, the browser now handles much of the interface rendering that used to happen on the server. Second, applications persist in the browser and update the interface dynamically rather than rebuilding pages. And third, frameworks such as React provide the abstractions needed to manage the resulting complexity.Once you view the web through this lens, many modern frontend patterns begin to make sense. Component-based architectures, state-driven rendering, and client-side routing all exist to support the same goal: building web applications that behave like real software rather than collections of pages.These concepts are explored further in Full-Stack React, TypeScript, and Node (2nd Edition), currently available in early access for PacktPub subscribers.Preorder now!This Week in the News📊 State of React Native results are out: The latest State of React Native survey is live, offering a snapshot of how developers are using the framework today. It covers adoption trends, satisfaction, tooling, and common pain points across the ecosystem. Worth a look if React Native is part of your stack or roadmap.🤖 Cloudflare rebuilds Next.js as AI reshapes the commercial open source model: Cloudflare surprised the developer community this week by claiming that a single developer rewrote Next.js in just one week using AI tools, spending about $1,100 in tokens. The experiment highlights how quickly large codebases can now be recreated with AI-assisted development, raising new questions about the speed and economics of building complex frameworks.📈 Next.js 16 upgrade triggers unexpected request spikes: Some developers upgrading from Next.js 15 to 16 report higher server request volume and increased response latency. The change appears to put more strain on backend infrastructure, which could mean higher compute usage and increased hosting costs in production. A useful read if you’ve ever been surprised by a framework behaving differently outside local dev.🔐 When a GitHub Issue Becomes a Supply Chain Attack: A security write-up explains a vulnerability chain called Clinejection that exploited an AI GitHub issue bot. The attack combined prompt injection with CI cache poisoning to publish a malicious package. It’s a good reminder that AI agents in developer workflows introduce a new kind of supply chain risk.💬 Vercel introduces the AI Chat SDK: Vercel has released a new Chat SDK aimed at simplifying how developers build conversational AI interfaces. The SDK provides primitives for streaming responses, handling message state, and integrating with multiple AI providers. If you’re building AI features into web apps, it removes a lot of the plumbing typically required for chat-style interactions.Beyond the Headlines🔄 Migrating from TypeScript 5.x to 6.0: This GitHub gist explores some extreme TypeScript type patterns that push the compiler surprisingly far. It’s a fascinating look at how conditional types, inference, and recursion turn TypeScript into something close to a compile-time programming language.🤖 AI Is Writing More Software, but Who Checks the Output?: Lean creator Leo de Moura explores what happens if AI systems eventually generate the majority of production code. The essay looks beyond productivity gains and asks deeper questions about verification, correctness, and how we maintain trust in software when humans are no longer writing most of it. A thoughtful perspective on where AI-assisted development could lead.🎞 Web Performance with Image Sprites: Sprite animations are an old web technique that still works surprisingly well today. Josh Comeau walks through how sprite sheets function, how to implement them with modern CSS, and when they’re preferable to other animation approaches. A great refresher for anyone building playful UI interactions or performance-friendly animations.🧠 Patterns for building agentic systems: Simon Willison breaks down emerging patterns in “agentic engineering” workflows. The article looks at how developers are structuring AI agents that can reason, call tools, and coordinate tasks across systems. If you’re experimenting with agent-style architectures, this piece highlights the design patterns that are starting to emerge.Tool of the Week🧩Build Custom Rich Text Editors with YooptaIf you're building apps that need rich text editing, finding a flexible editor can be tricky. Many solutions are either too rigid or difficult to extend.Yoopta Editor is a modern, open source rich text editor framework built for React. It uses a block-based architecture, making it easier to customize editing experiences, add plugins, and control how content is structured.For developers building CMS tools, collaborative editors, or AI-assisted writing interfaces, Yoopta offers a flexible foundation without forcing a fixed editing model.That’s all for this week. Have any ideas you want to see in the next article? Hit Reply!Cheers!Editor-in-chief,Kinnari ChohanSUBSCRIBE FOR MORE AND SHARE IT WITH A FRIEND!*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}} @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} }
Read more
  • 0
  • 0

Kinnari Chohan
16 Mar 2026
13 min read
Save for later

WebDevPro #130: Rethinking State Management in Modern React

Kinnari Chohan
16 Mar 2026
13 min read
Crafting the Web: Tips, Tools, and Trends for Developers Advertise with Us|Sign Up to the Newsletter @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } WebDevPro #130 Rethinking State Management in Modern React Crafting the Web: Tips, Tools, and Trends for Developers Most Spring Boot projects stop at REST APIs Real systems require service discovery, API gateways, centralized configuration, and built-in resilience. In this live, hands-on workshop, you’ll build a working microservices system end-to-end, define service boundaries, wire up discovery, configure a gateway, and handle failures properly. 🎟 Register now and get 40% off with code SAVE40 📢 Important: WebDevPro is Moving to Substack We’ll be moving WebDevPro to Substack soon.Once the transition is complete, all future issues will come from packtwebdevpro@substack.com. To make sure the newsletter continues reaching your inbox, please add this address to your contacts or whitelist it in your mail client. No other action is needed. You’ll keep receiving WebDevPro on the same weekly schedule. Substack will also give you more control over your subscription preferences if you decide to adjust them later. Welcome to this week’s issue of WebDevPro! If you’ve worked with React for a while, you’ve probably run into the same recurring question: how should we manage state in this application? State management is one of those topics that almost every React team ends up debating sooner or later. Should everything live in context? Do we need a global store? Would something like Zustand make things simpler? Those conversations usually focus on tools. But in many cases the real problem shows up earlier than that. In practice, React applications rarely become difficult to maintain because the wrong library was chosen. They become difficult to maintain because different kinds of state get handled in the same way. A form input, an API response, a UI filter, and a shared user object often end up managed with identical patterns. That is where complexity starts to creep in. In this article, we will look at the main categories of state that appear in React applications and how each category is best managed. By the end, you will have a clearer way to decide where state belongs in a React app, whether that means local component state, shared state, server data tools, or even the URL itself. Not all state belongs in the same place State in React applications usually falls into a few clear categories. Local state lives inside a single component. A dropdown menu, a modal visibility toggle, or a small UI interaction typically belongs here. Hooks such as useState or useReducer work well because the logic remains isolated. Server state represents data fetched from APIs or databases. This includes user profiles, product listings, or analytics data. The key difference is that the source of truth lives outside the application. Form state includes field values, validation errors, and submission status. Forms have their own lifecycle and benefit from specialized tools such as React Hook Form or React’s form hooks. URL state stores small pieces of UI state in route or search parameters. Tabs, filters, pagination, and search queries often belong here. Shared state exists when multiple components need access to the same data. Authentication details, application settings, or user preferences are common examples. Understanding these categories clarifies an important point. React state is not a single problem. It is a set of related problems that require different solutions. The easiest state to manage is the state you never store One of the most common sources of complexity in React applications comes from duplicated state. Consider a list of items where the interface displays only active entries. A common pattern stores both the original list and a filtered version of it. const [items, setItems] = useState([...]) const [filteredItems, setFilteredItems] = useState([]) useEffect(() => { setFilteredItems(items.filter(item => item.active)) }, [items]) This introduces synchronization logic that React must maintain. A simpler approach derives the filtered list directly from the original state. const [items, setItems] = useState([...]) const filteredItems = items.filter(item => item.active) The application now maintains a single source of truth. React calculates the derived value when needed. Derived state reduces bugs and simplifies reasoning about data flow. Many React components become easier to maintain once unnecessary state variables disappear. Shared state is where React applications become complicated Local state remains predictable because it stays within a component. Shared state changes that dynamic because multiple components read and update the same values. Developers often encounter this situation when user data, permissions, or global settings must appear across different sections of the interface. The simplest approach begins with prop drilling. A parent component holds the state and passes it through props to child components. This technique often receives criticism, yet it works well for a small number of adjacent components. It also keeps data flow explicit and easy to trace. Problems appear when the component tree becomes deeper. Intermediate components may receive props they do not use, simply to pass them further down the hierarchy. At this stage, many teams introduce React context. Context allows components to access shared values without passing them through each level of the tree. A provider component stores the shared state and exposes it to any descendant component. This pattern simplifies access but introduces a different trade-off. When context values change, every consumer beneath the provider may re-render. For small applications this rarely matters. In larger interfaces the rendering behavior becomes harder to control. Libraries such as Zustand approach shared state from a different angle. Zustand creates a centralized store and allows components to subscribe only to the pieces of state they require. const userName = useUserStore(state => state.userName) Components update only when the subscribed value changes. This selective subscription reduces unnecessary renders and keeps the shared state logic compact. Context and Zustand both solve shared state challenges, but they operate at different scales. Context works well for moderate application state. Zustand becomes attractive once shared state spreads across larger parts of the interface. Server state follows a different lifecycle Data fetched from external services introduces a different category of state entirely. Server data involves caching, background refetching, loading indicators, and stale data management. Handling these concerns with useState and useEffect often leads to repetitive code and fragile synchronization. Libraries such as TanStack Query address this layer directly. They treat server data as cached resources rather than ordinary component state. Components request data using a shared query key. const { data } = useQuery({ queryKey: ['user', userId], queryFn: fetchUser }) TanStack Query stores the response in a client cache. Other components requesting the same query receive the cached result rather than triggering another network request. This model separates server data concerns from UI logic. React components remain focused on rendering rather than managing asynchronous data lifecycles. Some state belongs in the URL Another overlooked location for state is the browser address bar. Interfaces often contain UI state that describes how a page is being viewed. Active tabs, filter selections, search queries, and pagination indexes all fall into this category. Storing this information in URL search parameters creates several benefits. The state becomes shareable through links. Refreshing the page preserves the interface configuration. Browser navigation also restores previous UI states naturally. Framework hooks such as useSearchParams and routing utilities make this pattern straightforward. const params = useSearchParams() const activeTab = params.get('tab') Many teams duplicate this information inside React state and attempt to synchronize it with the URL. Removing that duplication simplifies the architecture. The address bar can act as a reliable source of truth for small pieces of UI state. Choosing the right home for state Modern React offers many tools for managing state, but the real skill lies in recognizing where each type of state belongs. Local UI interactions usually remain simplest when handled with component state. Values that can be computed from existing data should be derived instead of stored. Data fetched from APIs benefits from tools designed for server state, such as TanStack Query, which handle caching and refetching automatically. UI state that affects navigation, such as active tabs or filters, often works best when stored in URL parameters. Shared client state can start with straightforward prop passing and evolve into solutions such as context or Zustand when multiple components need coordinated access. The key takeaway is not which library to choose. It is learning to recognize the nature of the state problem in front of you. Once you can distinguish between local, shared, server, form, and URL state, the architecture decisions become much clearer. Instead of forcing every problem into the same pattern, each piece of state can live in the place where it is easiest to manage. That shift in thinking leads to React applications that are easier to reason about, easier to scale, and far less prone to the state management issues that often slow teams down. Build real skills in LLMs and agentic AI with this 20+ course Packt bundle, featuring titles like Learn Python Programming, 4E and The LLM Engineer’s Handbook. Learn how to design and deploy intelligent systems while supporting World Central Kitchen. 👉 Grab the LLM & Agentic AI Career Accelerator bundle This Week in the News 🧠 TypeScript 6.0 RC prepares the ecosystem for the Go-powered compiler:TypeScript 6.0 RC has landed and it marks an important transition for the language. This release functions largely as a stepping stone toward TypeScript 7.0, which will introduce a new native compiler written in Go. The RC itself contains only a few small changes compared to the beta, but the bigger shift lies in the groundwork being laid for the next generation of the toolchain. Required updates to tsconfig.json help projects align with upcoming architecture changes, giving teams time to prepare before the performance gains of the Go-powered compiler arrive later this year. ⚛️ SolidJS 2.0 beta introduces first-class async and a redesigned reactive core: SolidJS has entered the 2.0 beta phase after several years of experimental work on its next-generation reactive system. The release introduces major architectural changes including a rewritten signals implementation, deterministic batching, and first-class async support built directly into the framework’s primitives. New patterns such as action and optimistic state helpers aim to make server mutations and UI updates easier to manage, while updates to control flow and rendering bring several breaking changes developers will notice quickly. The beta sets the stage for broader ecosystem updates ahead of the stable 2.0 release. ☁️ Astro 6 introduces a Rust compiler and deeper Cloudflare alignment:Astro 6 arrives as the framework’s first major release since its acquisition by Cloudflare in January, and the platform direction is already becoming clearer. The update introduces an experimental Rust compiler that will eventually replace the original Go-based .astro compiler, promising faster builds and a modernized compilation pipeline. Development workflows also improve through Vite’s new Environment API, which allows developers to run the exact production runtime during development. Astro also introduces a new Fonts API that simplifies custom font handling across projects. 🌊 Cloudflare pushes for a simpler modern JavaScript Streams API:Cloudflare engineers are questioning the design of the Web Streams API, arguing that it reflects an earlier era of JavaScript before patterns like async iteration became common. The result is an abstraction that often feels overly complex, with specialized readers, locking mechanics, and extra boilerplate. Cloudflare proposes a simpler model built on modern JavaScript primitives that could improve both ergonomics and performance. Early benchmarks suggest potential speedups of up to 120× across runtimes such as Node.js, Deno, and Workers. In a related talk, James Snell explains how an async-iterator-driven approach could make streaming code easier to reason about for developers working with edge platforms and large data pipelines. 🎥 Watch the talk: https://www.youtube.com/watch?v=abbeIUOCzmw Beyond the Headlines 🤖 Literate programming may finally make sense in the AI agent era: Donald Knuth’s idea of literate programming asked developers to write code as a narrative meant for humans, with the compiler following along. For decades the concept remained mostly academic. This piece revisits the idea through the lens of AI-assisted development, where agents read, analyze, and generate code alongside developers. Clear explanations, structured reasoning, and intent-rich programs suddenly become far more valuable. The argument is simple but compelling: the rise of coding agents may finally make literate programming practical. 🐘 Just use Postgres and delay the infrastructure sprawl:Many modern stacks quickly grow into a collection of specialized tools: queues, search services, analytics systems, and caches. This article argues that much of that complexity arrives too early. PostgreSQL already includes powerful capabilities such as JSON support, full-text search, background jobs, and extensions that cover a surprising range of workloads. For many products, a single Postgres database can carry far more responsibility than teams assume. The takeaway is pragmatic: lean on Postgres longer and introduce new infrastructure only when the workload genuinely demands it. ⚡Building a real-time collaborative to-do app with Jazz and Vue: Real-time collaboration often brings complex backend logic, synchronization challenges, and WebSocket plumbing. This tutorial shows a simpler path by building a collaborative to-do app using Jazz and Vue. The stack manages shared state and synchronization automatically, allowing the interface to update instantly as multiple users interact with the same data. The walkthrough focuses on how collaborative state flows through the application and how the UI reflects updates in real time. It offers a practical introduction to modern tooling for building collaborative applications. ⚛️ Why React needed Fiber and what problem it actually solved:React Fiber is one of the biggest architectural changes in React’s history, yet its purpose is often misunderstood. This deep dive explains why the original reconciliation algorithm struggled with large or complex updates. Fiber introduced a scheduling model that allows React to pause, resume, and prioritize rendering work instead of processing everything in one blocking pass. That change laid the foundation for features such as concurrent rendering and smoother user experiences under heavy workloads. Tool of the Week 🛠️ VMPrint deterministic PDF generation without headless browsers Print-to-PDF pipelines often rely on headless Chrome, bringing along browser quirks and inconsistent rendering. VMPrint takes a different approach with a pure TypeScript typesetting engine that bypasses the DOM entirely and computes layout through typographic math. The result is deterministic output across browsers, Node.js, and edge runtimes like Cloudflare Workers. Given identical input, VMPrint guarantees identical layout down to the sub-point position of every glyph. For teams building document generation pipelines or publishing systems, it offers a precise and reproducible alternative to browser-based rendering. That’s all for this week. Have any ideas you want to see in the next article? Hit Reply! Cheers! Editor-in-chief, Kinnari Chohan SUBSCRIBE FOR MORE AND SHARE IT WITH A FRIEND! *{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}} @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} }
Read more
  • 0
  • 0

Kinnari Chohan
02 Jun 2025
9 min read
Save for later

WebDevPro #93: AI Tools, Java 25, and TypeScript Goes Turbo

Kinnari Chohan
02 Jun 2025
9 min read
Crafting the Web: Tips, Tools, and Trends for DevelopersAdvertise with Us|Sign Up to the Newsletter @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} }WebDevPro #93: AI Tools, Java 25, and TypeScript Goes Turbo 🌍🔍Crafting the Web: Tips, Tools, and Trends for DevelopersWeb Devs: Turn Your Knowledge Into IncomeBuild the knowledge base that will enable you to collaborate AI for years to come💰 Competitive Pay Structure⏰ Ultimate Flexibility🚀 Technical Requirements (No AI Experience Needed)Weekly payouts + remote work: The developer opportunity you've been waiting for!The flexible tech side hustle paying up to $50/hourAPPLY NOWHi ,This week’s stack is fast, fearless, and full of firsts. Microsoft’s orchestrating smarter updates, Nova’s giving JavaScript a Rusty reboot, and TypeScript Native is blowing devs away with 10x faster builds. From minimalist Go setups to AI tools that build apps on the fly, this drop is packed.Here’s what’s shifting the stack:🪐 Nova lands – Rust-built, JS-ready, 70% test262 and flying.⚡ TypeScript Native preview – 10x faster builds, written in Go.🧠 Local-first apps are trending – Rethinking dev with fast, private tools.🛠️ Go devs ditch DI frameworks – Redowan says skip the extras because Go’s got this.🔧 Miško Hevery on junior devs – Show what you’ve built; buzzwords won’t cut it.🔮 Perplexity Labs: AI-generated charts, tables, and web apps in seconds.Plus, a must-read for Rust devs: Rust Web Programming (3rd Edition) is your hands-on guide to async, WebAssembly, microservices, and deployment in the real world.Want to be featured in WebDevPro? Share your tips or takes—we’re all ears!Advertise with usInterested in reaching our audience? Reply to this email or write to kinnaric@packt.com.Learn more about our sponsorship opportunities here.Latest news: what's new in web development? 🧑‍💻 The dev world doesn’t stop buzzing, and neither do we. From lightning-fast TypeScript previews to Java’s latest brewing batch and a Rusty new JS engine, here’s what’s hot and happening this week. Stay sharp, stay curious.🧠 Skyvern’s Web Bench Is Here to Shake Up AI Testing: Skyvern launched Web Bench, a rich dataset with 5,750 tasks across 452 real websites. It tests both “read” and “write” actions, mimicking real user behavior more closely than ever. Skyvern 2.0 nailed the “write” tasks like downloads, form-filling, and more.🪐 Nova: A Rusty New Star in the JS Engine Galaxy: Say hi to Nova, an experimental JavaScript + WebAssembly engine written entirely in Rust. Built on data-oriented design principles, it’s aiming for efficiency and modularity. Already passing 70% of test262, it’s one to watch in engine land.🪟 Windows Update Just Leveled Up: Microsoft is turning Windows Update into a full app orchestration platform. Now third-party apps can tap into eco-friendly scheduling and unified update handling. Currently in private preview, but expect broader rollout soon.☕ Java 25: The Brew Gets Stronger: The upcoming JDK 25 introduces 17 new features, including Shenandoah’s generational GC. It also brings PEM support for cryptographic keys and fresh memory tools. Set to launch in September as the next long-term support release.⚡ TypeScript Native Preview: 10x Faster, Written in Go: Microsoft drops TypeScript Native, a reimagined toolchain powered by Go. Expect a 10x speed boost on most projects. No joke! You can try it now via nightly builds or the VS Code extension.Last Day! Get $149 Worth of Bestsellers for Just $18!These 4 bestselling titles are worth $149 on their own. Grab them along with 18 more must-have C# and .NET books in our Mega Bundle for just $18.Don’t miss out. The offer ends tonight!Expert corner: what's the web community talking about?🎙Got a finger on the pulse of dev Twitter? We do. From AI pair programming to local-first revolutions and Go’s no-frills philosophy, the community is buzzing. Here’s what everyone’s talking (and tweeting) about this week.🌀 Web Design Déjà Vu: Are We Back in 1997?: Cybercultural dives into the comeback of ’90s web vibes with centered layouts and deliberate simplicity. It’s a subtle takedown of today’s heavy, overengineered websites that often forget the basics. If this got your gears turning, you’ll love our upcoming release: Responsive Web Design with HTML5 and CSS!🧠 Local-First Development is Stealing the Spotlight: Cloud fatigue? You’re not alone. Local-first apps are making a comeback, where your data lives with you.Fast, private, resilient. Developers are buzzing: what if the cloud is just a sidekick, not the star?🛠️ Go Devs Are Ditching DI Frameworks: Redowan’s spicy take? Most Go projects don’t need DI frameworks at all. With Go’s clean interfaces and structure, doing it by hand just feels right. It’s minimalist engineering at its finest, and the dev world’s nodding along..🧪 Picking Your Next Programming Language (Without the Hype): Michael Lynch drops a brainy guide for devs itching to try something new. No trend-chasing here. Just simplicity, uniqueness, and impact. It’s the nudge you need to break out of your language bubble.🤖 Real Devs Are Pairing with LLMs: Senior engineers are teaming up with AI for debugging, planning, and code reviews. Peter Mbanugo’s piece shows how LLMs are already solid dev teammates. It’s not the future. It’s happening now, in your favorite IDE.🌐 Spring Devs, Say Hello to Smarter API Calls: Spring WebClient is getting major love for async, non-blocking API magic. It’s sleek, reactive, and perfect for scaling microservices like a pro. Less boilerplate, more control. What’s not to love?Packt catalogue: must read dev books📚📘 Rust Web Programming – Third Edition by Maxwell FlittonA hands-on guide to modern web development with Rust, covering async, microservices, nanoservices, WebAssembly, and real-world deployment strategies.📚 Comprehensive intro to full-stack Rust web dev🧠 Covers WebAssembly, Axum, native TLS, SurrealDB🏗️ Emphasizes microservice and nanoservice architectures🛠️ Hands-on with real projects and cloud deployment Grab your copy!Under the Radar 🔍Tiny tools. Big vibes.Not on your radar yet? These gems are quietly leveling up developer workflows, from whiteboarding to wireframes. They’re the kind of tools you’ll wish you’d discovered sooner.🧠 RegexLearn: An interactive regex tutorial that builds up your skills visually. Great for beginners who are tired of trial-and-error and ready to really get it.✏️ tldraw: A collaborative whiteboard made with developers in mind. Draw mockups, diagrams, or user flows and export them with dev-ready clarity.🔧 ToolHunt: A curated hub of underrated tools for developers, designers, and indie hackers. Think Product Hunt, but more focused and less noisy.👤 UI Faces: Need realistic avatars for UI mocks, team pages, or placeholder content? Access real human faces that feel authentic, not like stock photos.Exclusive expert spotlight: Miško Hevery on Junior Devs, AI & Making It Real 🎤This week’s expert spotlight features Miško Hevery, creator of Angular and Qwik, and currently CTO at Builder.io. With a career dedicated to building fast and scalable web apps, Miško has helped shape how modern development is done at scale. In our latest chat, he shares what still matters for junior devs in the age of AI—why LLMs are just tools, not shortcuts, and why building real things is still the strongest signal you can send. Spoiler: it’s not about how you build, but that you build at all.🎥 Watch the clip onX. Follow us on WebDevPro for more dev insights and hot takes.There's been like a growing narrative about, junior level roles probably being taken away. What kind of career advice would you want to give newcomers who are just starting out with web development in this age of AI and LLMs?The advice hasn’t changed: when you walk into an interview, what people want to see is what you’ve built.It doesn’t matter if you did it the hard way or used LLMs—what matters is that you executed. Because building isn't just coding. It’s goal-setting, problem-solving, and figuring out the path of least resistance.If you're just starting out, contribute to open source or build something valuable—even if no one uses it. Show that you can make something real.Ideas are cheap. Execution is the hard part. Can you persist, ask the right questions, and keep pushing when things get hard? That’s what really makes you stand out.Machine Learning Summit 2025Level up your skills with exclusive insights from top ML experts! 40% OFF if you book now.🎤 LLMs AMA with Sebastian RaschkaAsk your most pressing questions about large language models📈 GPTs for Time Series with Khuyen TranDiscover how to bring generative models to real-world forecasting.💡Learn directly from Luca Massaron, Thomas Nield, and 20+ ML experts in a power-packed lineup of live sessions, workshops, and AMAs.Use Code: EARLY40REGISTER NOW AND GET 40% OFFAI in the spotlight 🔦🤖 Perplexity Labs Drops – AI That Builds Charts, Apps & Answers 📊 From questions to interactive apps in seconds. 🧠 Acts like a 24/7 answering machine with built-in data visualization smarts. 🛠️ Makes AI more hands-on for devs, teams, and solo builders alike.Developer tip of the week 💡📊 Use console.table() to debug like a bossInstead of cluttering your console with objects or arrays, console.table(data) gives you a clean, sortable table view.Perfect for debugging API responses, datasets, or arrays of objects at a glance.And that's a wrap 🎬That’s your scoop from the dev-verse this week. Radar scans complete, tools tested, and tabs (mostly) cleared.If your brain’s buzzing with ideas or feedback, hit reply. We love a good code rant.Until next week, ship smart, sip coffee, and stay curious!Cheers!Kinnari Chohan,Editor-in-chiefSUBSCRIBE FOR MORE AND SHARE IT WITH A FRIEND!*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}} @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} }
Read more
  • 0
  • 0

Kinnari Chohan
23 Mar 2026
14 min read
Save for later

WebDevPro #131: Building Reliable Applications with Cursor: A Spec-Driven Workflow for Incremental Development

Kinnari Chohan
23 Mar 2026
14 min read
Crafting the Web: Tips, Tools, and Trends for DevelopersAdvertise with Us|Sign Up to the Newsletter @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} }WebDevPro #131Building Reliable Applications with Cursor: A Spec-Driven Workflow for Incremental DevelopmentCrafting the Web: Tips, Tools, and Trends for DevelopersMost Spring Boot projects stop at REST APIsReal systems require service discovery, API gateways, centralized configuration, and built-in resilience. In this live, hands-on workshop, you’ll build a working microservices system end-to-end, define service boundaries, wire up discovery, configure a gateway, and handle failures properly.🎟 Register now and get 40% off with code SAVE40📢 Important: WebDevPro is Moving to SubstackWe’ll be moving WebDevPro to Substack soon.Once the transition is complete, all future issues will come from packtwebdevpro@substack.com.To make sure the newsletter continues reaching your inbox, please add this address to your contacts or whitelist it in your mail client. No other action is needed. You’ll keep receiving WebDevPro on the same weekly schedule.Substack will also give you more control over your subscription preferences if you decide to adjust them later.Welcome to this week’s issue of WebDevPro!If you’ve been experimenting with tools like Cursor, you’ve probably had that moment where the output looks promising but not quite right. You tweak the prompt, try again, and end up chasing the result instead of building something stable.What tends to work far better is not bigger prompts or more detailed instructions, but a shift toward a spec-driven, incremental workflow. One that mirrors how experienced developers already build systems, but adapts it to work effectively with AI-assisted coding environments.In this article, we want to walk through a more reliable way to approach this. By the end, you’ll have a practical workflow for structuring your projects, breaking down features, and working with AI coding tools in a way that actually scales beyond small experiments.Why direct prompting breaks down in real projectsIt is tempting to treat Cursor as a high-powered code generator. Describe the app, mention the tech stack, and expect a complete implementation.That approach holds up for small, disposable prototypes. It starts to fracture as soon as the project has multiple features, shared state, or evolving requirements.There are a few reasons for this.First, ambiguity compounds quickly. Even a well-written prompt leaves room for interpretation. The model fills in those gaps based on patterns, not your intent.Second, outputs are inherently variable. The same prompt can produce slightly different structures, naming conventions, or flows. This makes it difficult to build predictably.Third, you give up control of the system’s shape. Instead of designing the architecture, you are reacting to whatever the model generates.The result is a loop of correction rather than a process of construction.A more reliable approach: constrain, decompose, iterateA more effective pattern is to treat the tool as a collaborator that works best within clearly defined boundaries.The workflow is straightforward:Define what the system should doBreak it into discrete units of workImplement those units incrementallyRefine through feedbackThis is familiar territory. The difference is that your artifacts, like specifications and task lists, are now also guiding the model.Start with a specification that removes guessworkBefore opening Cursor, it helps to define how the application should behave in concrete terms. Consider a simple example: a math practice application for children.At a glance, it sounds trivial. In practice, it involves a number of decisions:What kinds of operations are supportedHow questions are presentedHow users interact with answersHow incorrect attempts are trackedWhat metrics are surfaced in a statistics viewWriting this down in a structured format forces clarity. It also creates a shared reference point for every subsequent step.One useful approach is to draft the specification in Markdown using a general-purpose language model. The key is not the initial output, but the interaction that follows. Asking the model to clarify uncertainties before generating the spec often leads to better results.Once you have a draft, it is worth reviewing line by line. Fill in gaps, remove contradictions, and add constraints that matter to you. Visual expectations, state transitions, and edge cases are all worth capturing early.The specification becomes less of a document and more of a contract. It defines intent in a way that both you and the tool can consistently refer back to.Translate the specification into a phased TODO listWith a clear specification in place, the next step is to decompose it into manageable units of work.Instead of thinking in terms of “build the app,” the focus shifts to “implement the next smallest meaningful piece.” A structured TODO list works well for this. Features are grouped into phases, and each phase contains tasks that can be completed independently.For example: Phase 1: Project setupInitialize React applicationConfigure styling systemCreate base routing and placeholder pages Phase 2: Core interactionGenerate math questionsRender question cardsImplement answer selection logicThis breakdown serves two purposes: It reduces cognitive load. You are no longer juggling the entire system in your head. It also gives Cursor a much clearer target. Instead of interpreting a broad request, it can focus on a well-defined task.Build incrementally and keep the scope tightWith the TODO list in place, you can begin implementing features in Cursor. The important shift here is how you frame your prompts. Rather than asking for a full implementation, you anchor the request to specific artifacts and a limited scope:Use the specification and TODO list to complete Phase 1. Mark completed tasks.This keeps the model grounded. It knows where to look for context and what success looks like. In the case of the math practice app, the first phase might result in:A scaffolded React projectBasic routingPlaceholder pages such as Home, Practice, Stats, and SettingsAt this stage, the application is simple, but functional. That is intentional. Each phase establishes a stable base for the next.Iterate deliberately instead of restartingOnce the initial output is in place, the next step is refinement.It is common for the first version of the UI or structure to feel underdeveloped. The instinct might be to rewrite the prompt or regenerate the feature from scratch. A more effective approach is to iterate on top of what already exists.For example:Improve the homepage layout. Add clearer navigation and better spacing.This kind of prompt is focused and contextual. It builds on existing work rather than replacing it.Over time, this creates a steady progression:Initial structureIncremental improvementsTargeted fixesEach step is small, but collectively they move the system toward a more polished state.Designing for variability instead of fighting itOne characteristic of working with language models is that outputs are not perfectly consistent. Even with the same inputs, you may see variations in structure, naming, or implementation details. Rather than trying to eliminate this variability, it helps to account for it in your workflow.Specifications anchor intent.TODO lists constrain scope.Incremental development limits the blast radius of changes.Together, these reduce the impact of variation. You retain control over the system, even as the underlying outputs shift slightly.A closer look at a single featureTo make this more concrete, consider the first phase of the math practice application. The goal is to establish the basic application shell. You begin with two inputs:A specification that defines pages and navigationA TODO list that outlines setup tasksThe prompt is simple and scoped:Complete Phase 1 using the provided specification and TODO list.Cursor initializes the project, sets up dependencies, and creates the necessary files. You run the application locally and see a basic interface with navigation between pages. At this point, the system is functional but minimal. You then refine:Improve the visual structure of the homepage and navigation.The tool updates components, adjusts layout, and introduces better spacing. You review the changes, keep what works, and continue. This pattern repeats for each feature. The system grows in layers, each one built on a stable foundation.Patterns that hold up in larger projectsA few patterns consistently make this approach effective. Clear specifications reduce the need for corrective prompts later. They shift effort from fixing outputs to shaping intent early.Breaking work into smaller tasks improves reliability. Each unit is easier for the model to interpret and implement correctly.Iteration keeps progress steady. Instead of waiting for a perfect result, you move forward through a series of improvements.Documentation becomes an active part of the process. Specifications and TODO lists evolve alongside the code, keeping everything aligned.Most importantly, you remain in control of the system’s design. The tool accelerates execution, but the direction still comes from you. But this workflow is not automatic. It depends on a few habits.If the specification is vague, the outputs will reflect that.If tasks are too large, the results become inconsistent again.If changes are accepted without review, small issues compound over time.The tool amplifies the process you bring to it. Structure leads to leverage. Lack of structure leads to friction.Closing thoughtsWorking with Cursor is less about mastering prompts and more about shaping a reliable development process. Once you move away from one-shot generation and toward a spec-driven, incremental approach, the experience changes. The tool becomes more predictable. The codebase becomes easier to reason about. Progress feels steadier.In many ways, this is not a new way of building software. It is a return to fundamentals, adapted for a new interface. The difference is that when the structure is right, the speed at which you can move begins to compound.If you want to go deeper into this way of working, especially with hands-on examples and a full project walkthrough, this approach is explored in detail in Vibe Coding with Cursor. It’s a practical guide to building real applications using these patterns, and a useful next step if you’re looking to move beyond experimentation into something more structured.This Week in the News🤖 OpenAI to acquire Astral: OpenAI is acquiring Astral and its widely used open-source Python developer tools, including uv, Ruff, and ty. The move strengthens OpenAI’s push into developer tooling, bringing core workflows like dependency management, linting, and type checking closer to its ecosystem. The goal is to accelerate Codex beyond code generation, positioning it to operate across the full development lifecycle, where it can work directly within the tools developers already use.🗓️ Why JavaScript still struggles with dates: The JavaScript new Date(someString) constructor is notoriously over-eager, stemming from legacy C++ parsers in engines like V8 and SpiderMonkey that aggressively "guess" date components to maintain backwards compatibility. This leads to absurd "hallucinations" where the engine prioritizes finding a year at any cost. Beyond these quirks, the parser's inconsistency is a frequent source of production bugs; for instance, new Date("2024-03-25") is treated as UTC, while adding a time element like T00:00 shifts it to Local Time, often causing "off-by-one-day" errors for users in different time zones. To avoid silent data corruption, such as new Date(null) defaulting to the 1970 Unix Epoch, developers should abandon these loose string constructors in favor of strict ISO 8601 formatting or the modern, predictable Temporal API.▲ Next.js 16.2 updates:Next.js 16.2 introduces a set of refinements focused on improving performance, stability, and the overall developer experience. The release builds on recent changes to the app router and server components, with updates that make common workflows more predictable and easier to manage. The direction remains consistent, with Vercel continuing to smooth out rough edges while aligning Next.js more closely with modern React patterns and production needs.⚡Vite 8 and Void, the fill-stack pivot: The Vite ecosystem is expanding beyond build tooling. Alongside the release of Vite 8, which brings updates focused on faster builds and a more streamlined developer experience, the VoidZero team has introduced Void, a Vite-native deployment platform built on Cloudflare Workers. Void aims to turn Vite apps into full-stack applications by bundling capabilities like databases, KV storage, object storage, and AI inference directly into the workflow. Together, these updates signal a shift toward a more integrated Vite stack that spans both development and deployment.⚖️ No AI code in Node.js core? A new petition sparks debate:A long-running discussion around AI-assisted development in OpenJS Foundation projects has taken a new turn. A Node.js contributor has started a petition urging the TSC to restrict AI-generated code from being merged into Node’s core, following concerns raised alongside a large 19K LOC PR. The debate touches on deeper questions around code quality, maintainability, and ownership as AI becomes a common part of development workflows.🧩 How TanStack approaches modern developer tooling:TanStack shares a set of ecosystem updates alongside a detailed talk that breaks down the thinking behind its tooling approach. The focus stays on building framework-agnostic, composable primitives that can scale across different application architectures without locking developers into a specific stack. The talk offers a deeper look into how these decisions play out in practice, from managing server state to structuring UI logic, and why flexibility and interoperability remain central to TanStack’s design philosophy.Beyond the Headlines📉 The hidden cost of “comprehension debt”:Addy Osmani introduces the idea of comprehension debt: the growing gap between how quickly code can be produced and how easily it can be understood. As tools (especially AI) accelerate code generation, the burden shifts to developers who need to read, debug, and maintain that code. It’s a useful lens for thinking about long-term code quality. Fast output is valuable, but only if teams can still reason about what they’ve built.🧠 React to Svelte migration with AI agents: Strawberry shares how it rewrote 130K lines of React code to Svelte in just two weeks using coding agents, cutting UI complexity and doubling performance in the process. The write-up goes deeper into why the team moved away from React’s rendering model toward Svelte’s compiler-first approach, and how AI-assisted workflows made a full rewrite practical at a scale that would usually take months. It’s a strong signal of how framework decisions, performance constraints, and AI-driven development are starting to converge in real-world systems.🎥 Rethinking how we build modern web apps: This talk explores how modern web development is evolving, touching on architecture, tooling, and the trade-offs developers face as applications grow in complexity. It’s a useful watch if you’re thinking about how today’s patterns scale in real-world systems.🚄 Understanding how JIT affects runtime performance: This post explores how Just-In-Time (JIT) compilation behaves in practice, looking at how execution performance evolves over time. It offers a deeper look at runtime optimizations and how they impact real-world performance characteristics.Tool of the Week🔍 Understand code changes with structural diffsTraditional diffs compare text line by line, which can make complex changes hard to follow. Difftastic takes a different approach by comparing the syntax tree of your code, helping you see what actually changed at a structural level.It supports multiple languages and highlights meaningful differences, making it especially useful when reviewing refactors or large code updates.That’s all for this week. Have any ideas you want to see in the next article? Hit Reply!Cheers!Editor-in-chief,Kinnari Chohan👋 Advertise with usInterested in sponsoring this newsletter and reaching a highly engaged audience of tech professionals? Simply reply to this email, and our team will get in touch with the next steps.SUBSCRIBE FOR MORE AND SHARE IT WITH A FRIEND!*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}} @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} }
Read more
  • 0
  • 0
Kinnari Chohan
30 Mar 2026
12 min read
Save for later

WebDevPro #132: Async Code That Looks Fine but Fails in Production

Kinnari Chohan
30 Mar 2026
12 min read
Crafting the Web: Tips, Tools, and Trends for Developers Advertise with Us|Sign Up to the Newsletter @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } WebDevPro #132 Async Code That Looks Fine but Fails in Production Crafting the Web: Tips, Tools, and Trends for Developers Most Spring Boot projects stop at REST APIs Most Spring Boot developers stop at REST APIs. That’s enough to build demos but not to build systems that survive production. The real work sits beyond that. Service discovery, resilience, observability, config management are what separate working code from systems that hold up under pressure. You don’t pick this up from tutorials. It comes from building systems, making trade-offs, and seeing them run. Tomorrow, you get exactly that. Live. From scratch. With Simon Martinelli and Josh Long. Only 6 spots left. 🎟 Use code SPRING40 for 40% OFF 📢 Important: WebDevPro is Moving to Substack We’ll be moving WebDevPro to Substack soon.Once the transition is complete, all future issues will come from packtwebdevpro@substack.com. To make sure the newsletter continues reaching your inbox, please add this address to your contacts or whitelist it in your mail client. No other action is needed. You’ll keep receiving WebDevPro on the same weekly schedule. Substack will also give you more control over your subscription preferences if you decide to adjust them later. Welcome to this week’s issue of WebDevPro! Have you ever written async code that looked perfectly fine, only for it to behave unpredictably later? It’s one of those things that feels obvious while coding, but starts to fall apart once real conditions come into play. Asynchronous programming is fundamental to Node.js. The event loop keeps everything moving, delegating work and picking it back up when results return. On paper, it feels straightforward. You write code in sequence, so it should run that way too. But that’s where things get tricky. Execution is shaped by timing, scheduling, and resource contention. These are not visible in the code itself. What looks sequential can run concurrently. What feels predictable can change under load. Many real-world issues don’t come from syntax errors, but from how async behavior interacts with shared resources and execution order. This week’s deep dive breaks down where these assumptions fail and what it takes to make async systems behave reliably. Before we get into it, here’s this week at a glance: 🟦 TypeScript is preparing for a compiler rewrite 📦 pnpm is redesigning how dependencies are stored 🤖 Next.js is pushing toward AI-first app development ⚡ Claude dropped SSR for speed gains 🧩 Storybook is becoming AI-readable infrastructure When Async Execution Breaks Assumptions A common source of failure is incorrect assumptions about execution order. Consider a case where two operationsattempttowrite tothe same file. The code may appear sequential, but without explicit coordination, the operations execute independently. In such scenarios, the following pattern is oftenobserved: async functionraceCondition() { const filename = ... await unlink(filename) writeFile(filename, 'Written from first promise\n',{ flag: 'a' }) writeFile(filename, 'Written from second promise\n',{ flag: 'a' }) } At first glance, this code appears correct because two write operations are triggered one after the other.However, the absence of awaiting these operations means they run concurrently. Both operationsattemptto access the same file at the same time. This leads to inconsistent results, where the order of writes varies across executions. This behavior is known as a race condition. The issue is not syntax, but incorrect assumptions about how asynchronous execution works. Concurrency Does Not Guarantee Order In asynchronous systems, starting operations sequentially does not guarantee sequential execution. Each asynchronous call creates its own execution path, and these paths are resolved independently based on system timing. When multiple operations target the same resource, they compete for access. Without explicit coordination, the runtime does not guarantee which operationcompletesfirst. The outcome becomes dependent on timing rather than intent. This variability may not appear during development but becomes more prominent under production load, where multiple operationsexecutesimultaneously. Coordinating Access: Controlling Async Behavior To prevent race conditions, access to shared resources must be controlled. One approach is to introduce a mechanism that ensures only one operation interacts with the resource at a time. The following structuredemonstratesthis approach: classFileWriter{ #isWriting = false static instance = null constructor() { if (!FileWriter.instance) { FileWriter.instance= this } return FileWriter.instance } asyncwriteFile(filename, data) { if (this.#isWriting) { awaitsetTimeout(250) returnthis.writeFile(filename, data) } this.#isWriting= true const result = awaitwriteFile(filename, data, { flag: 'a' }) this.#isWriting= false return result } } This implementation introduces a lock mechanism. If a write operation is already in progress,subsequentoperationswaitbefore retrying. This ensures thatwritesoccur sequentially rather than concurrently. With coordination in place, execution becomes predictable. Without it, asynchronous code may behave inconsistently under real conditions. Callback Hell: When Async Structure Breaks Readability Asynchronous issues are not limited to executionorder. They also affect howcodeis structured. Deeply nested callbacks create code that is difficult to read andmaintain. An example of this structure is shown below: stepOne((err,resultOne) => { stepTwo(resultOne, (err,resultTwo) => { stepThree(resultTwo, (err,resultThree) => { console.log(resultThree); }); }); }); Although the code executes correctly, the nested structure makes it harder to follow the flow of data and control. Error handling is repeated at each level, increasing complexity. As the number of steps increases, the difficulty ofmaintainingand debugging the code also increases. The Event Loop and Hidden Blocking Node.js relies on non-blocking operations tomaintainperformance. The event loop processes tasks and delegatesworkwhen possible, allowing other operations to continue executing. However, not all operationsare non-blocking. Some APIs perform blocking I/O, which pauses execution of the entire program until completion. This prevents the event loop from handling other tasks. For example, cryptographic operations can block the main thread when executed synchronously. An asynchronous alternative allows work to be delegated externally: generateKeyPair("rsa", {modulusLength:1024 }, () => {}) The asynchronous version allows other operations to continue, while the synchronous version blocks execution. Under production load, blocking operations can significantly reduce system responsiveness. Async Does Not Always Mean Non-Blocking A common misconception is that wrapping a function in asynchronous code makes it non-blocking. This is not always true. If the underlying operation is blocking, it will still block execution. In such cases, performance improvements come from reducing how often the operation runs rather than changing how it is invoked. For example, caching results avoids repeated expensive computations: letcachedSignature= null; if (!cachedSignature) { cachedSignature=signData(...) } This approach improves throughput by reducing execution frequency rather than altering execution style. Async Behavior Under Load Many asynchronous issues only become visible under load. In controlled development environments, operations often execute in predictable sequences, and resource contention is minimal. As a result, code that appears stable during testing can behave differently when multiple operations are triggered at the same time. Race conditions become moreapparentwhen concurrent requests attempt to access ormodifythe same resource. What may appear as an occasional inconsistency during development can become a frequent issue when the same code is executed repeatedly under higher traffic. The lack of coordination between asynchronous operations leads to unpredictable results, making these issues harder to reproduce and debug. Blocking operations also have a more pronounced impactunderload. When a synchronous task runs on the main thread, it prevents the event loop from processing other incoming requests. In low-traffic scenarios, this delay may not be noticeable. Under production conditions, where many requests arrive simultaneously, blocking behavior can cause cascading delays, reducing overall responsiveness. Repeated execution of expensive operations further amplifies the problem. When the same computation is performed for every request without caching or reuse, system resources are consumed unnecessarily. This reduces throughput and increases response times, especially when multiple requests trigger the same operation concurrently. Anotherimportant factoris timing variability. Asynchronous execution depends on system scheduling, resource availability, and workload distribution. Under load, these factors fluctuate more significantly, increasing the likelihood of inconsistent outcomes. Code that relies on implicit ordering or timing assumptions becomes less reliable as concurrency increases. These issues highlight that asynchronous behavior is not only about writing non-blocking code, but also about understanding how that code behaves when multiple operations interact simultaneously. Without coordination, control over execution order, and careful management of shared resources, asynchronous systems can produce inconsistent results under real-world conditions. Final words Asynchronous programming enables Node.js to handle multiple operations efficiently, but it also introduces complexity in execution order, resource access, and performance. Many failures are caused by incorrect assumptions about how asynchronous code behaves. These issues oftenremainhidden during development and only surface under production conditions. Understanding how asynchronous code interacts with the event loop, shared resources, and system constraints is essential for building reliable applications. This Week in the News 🟦TypeScript 6.0 is really about TypeScript 7.0: TypeScript 6.0 quietly sets the stage for a bigger shift. This release moves the ecosystem closer to a Go-powered native compiler planned for TypeScript 7.0, with clear signals that performance and build speed are about to take a serious leap. It focuses less on surface-level features and more on groundwork that could reshape how large codebases compile and scale. 📦 pnpm 11 Beta just changed how dependencies are stored: pnpm 11 Beta offers a glimpse into where package management is heading. The shift to a SQLite-powered store improves lookup speed and reliability, while a broader config overhaul simplifies how projects define and share settings. Stricter build security is now enabled by default, reflecting a growing focus on supply chain safety. This release feels less like an incremental update and more like a rethink of how dependencies are stored and secured. 🤖Next.js just made AI apps feel native: Next.js 16.2 leans deeper into AI-native development. The update reshapes how developers connect model output to real interfaces, tightening the loop between prompting and product. The direction is becoming clear. Next.js is evolving into a foundation for AI-powered applications, not just a frontend framework. ⚡Why Claude dropped SSR for a Vite-powered setup: Anthropic’steam shared how they made Claude and its desktop apps meaningfully faster by moving away from SSR to a static setup using Vite andTanStackRouter. The shift highlights a growing pattern where speed and responsiveness win over traditional rendering models, especially for AI-heavy interfaces that demand instant feedback. 🧩 Storybook MCP brings AI into your UI workflow:Storybook’s latest update introduces an MCP server that lets coding agents understand your components at a deeper level. Instead of guessing structure, AI can now access metadata, generate stories, write tests, and even help fix bugs with more context. It signals a shift where component libraries are no longer just for developers, but also for the tools assisting them. Beyond the Headlines 🧠Fix your Next.js errors without exposing your code: Debugging production errors in Next.js often means staring at unreadable stack traces. This guide walks through setting up source maps withSentryso errors point back to your actual code, not minified chunks. The key detail is balance. You get full visibility in Sentry while keeping source maps out of the browser, which protects your code and improves debugging at the same time. 📊 Most open source projects are already accepting AI code:Phil Eaton surveyed 112 major source-available projects to understand how they handle AI-assisted contributions. The results show a clear trend. Most projects already allow or have accepted AI-generated code, with only a handful enforcing outright bans. The takeaway is not just policy, but reality. AI is already part of how modern open source evolves, and governance is still catching up ⚛️The React quirks you hate are actually fundamental: Some ofReact’smost disliked patterns, like deferred state updates and dependency arrays, are not accidental complexity. This piecearguesthey reflect deeper constraints of asynchronous UI systems. Once you look past the friction, they reveal problems every framework eventuallyhas tosolve, even the ones trying to replace React. 🧩Small programming tricks shape how your code scales: Tiny habits compound. This piece explores how small implementation choices, often dismissed as style or preference, quietly influence readability, maintainability, and long-term velocity. It is a reminder that good engineering is rarely about big rewrites. It is built through consistent, low-level decisions that add up over time. Tool of the Week ✍️ Draw it once, animate it instantly Stroke turns rough sketches into production-ready animations. You draw directly in the browser, and it generates Motion-based code you can drop into a React or Next.js component. Under the hood, it converts your strokes into SVG paths and animates them without manual setup, making it ideal for signatures, logos, or playful UI details. That’s all for this week. Have any ideas you want to see in the next article? Hit Reply! Cheers! Editor-in-chief, Kinnari Chohan 👋 Advertise with us Interested in sponsoring this newsletter and reaching a highly engaged audience of tech professionals? Simply reply to this email, and our team will get in touch with the next steps. SUBSCRIBE FOR MORE AND SHARE IT WITH A FRIEND! *{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}} @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} }
Read more
  • 0
  • 0

Kinnari Chohan
09 Jun 2025
10 min read
Save for later

WebDevPro #94: Angular Trims Down, Node Powers Ahead, Remix Evolves

Kinnari Chohan
09 Jun 2025
10 min read
Crafting the Web: Tips, Tools, and Trends for DevelopersAdvertise with Us|Sign Up to the Newsletter @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} }WebDevPro #94: Angular Trims Down, Node Powers Ahead, Remix Evolves 🌍🔍Crafting the Web: Tips, Tools, and Trends for DevelopersWeb Devs: Turn Your Knowledge Into IncomeBuild the knowledge base that will enable you to collaborate AI for years to come💰 Competitive Pay Structure⏰ Ultimate Flexibility🚀 Technical Requirements (No AI Experience Needed)Weekly payouts + remote work: The developer opportunity you've been waiting for!The flexible tech side hustle paying up to $50/hourAPPLY NOWHi ,This week’s stack is sharper, more secure, and increasingly self-aware. Angular steps into its zoneless future, Remix opens its doors to the community, and the npm ecosystem gets another wake-up call, this time from polymorphic malware. The AI conversation turns introspective, with Claude getting smarter (but secretive).Here's your tl;dr:🧠 Angular 20 lands – defer blocks, zoneless rendering, and performance-first updates.🛡️ npm malware alert – your config files and SSH keys are at risk.🧱 Remix grows up – governance, RFCs, and a steadier contributor experience.🌀 Anthropic Ends Windsurf’s Claude Access in Strategic Move Against OpenAI – no more direct access.🧰 Node doubled down – Config cleanup and smarter await? We’ll take it.📈 2025 dev forecast – AI, ethics, edge-native roles, and framework face-offs.Also worth your time: Learn React Hooks, 2nd Edition dropped, just in time for React 19. Custom hooks, cleaner state logic, and the end of class components; this one’s your upgrade guide.Got a tip or take? Send it our way and you might see it featured in WebDevPro!Advertise with usInterested in reaching our audience? Reply to this email or write to kinnaric@packt.com.Learn more about our sponsorship opportunities here.A better way to handle vendor security reviews?If you've ever dealt with vendor onboarding or third-party cloud audits, you know how painful it can be: long email chains, stale spreadsheets, and questionnaires that don’t reflect what’s actually happening in the cloud.We recently came across CloudVRM, and it’s a refreshingly modern take on the problem.Instead of asking vendors to fill out forms or send evidence, CloudVRM connects directly to their AWS, Azure, or GCP environments. It pulls real-time telemetry every 24 hours, flags misconfigs, and maps everything to compliance frameworks like SOC 2, ISO 27001, and DORA.It’s already being used by banks and infra-heavy orgs to speed up vendor approvals by 85% and reduce audit overhead by 90%.Worth checking out if you're building or maintaining systems in regulated environments, or just tired of spreadsheet security.Watch the demoLatest news: what's new in web development? 🧑‍💻 Frameworks leveled up, malware took aim, and AI stirred the pot (again). Here's what the web dev world chewed on this week.🧠 Angular 20 launches with smarter builds and zoneless progress: Angular’s latest update is all about performance and clean code vibes. With new defer blocks for surgical lazy loading and a move toward a zoneless future (yes, finally), it’s clear the Angular Renaissance isn’t just marketing.🟢 Double Node.js release day: config gets cleaner, await using expands: Node.js dropped not one but two updates recently. Version 22.16.0 introduces experimental support for node.config.json, paving the way for simpler, centralized project configs. Meanwhile, 24.1.0 builds on await usingsupport, pushing Node deeper into structured resource management territory. 🔗22.16.0 release notes🔗24.1.0 release notes🌀 No More Claude for Windsurf; Anthropic Protects Its Models from Rival Ecosystem: Claude now browses the web, but if you were hoping to peek behind the curtain, tough luck. Anthropic says its Windsurf stack won’t be shared, especially not with OpenAI. “Odd,” they said. Strategic, we read between the lines.🛡️ Node.js devs under fire; npm malware strikes again: Installing random npm packages without reading the docs? What is this, the wild west of 2015?A new polymorphic malware campaign is harvesting sensitive files from Node environments. Your .npmrc and SSH keys are not safe. Audit those dependencies or risk getting owned. Literally.📢 Remix opens up: new governance, more community control: Remix is going full open-source adulting. The framework now has RFCs, working groups, and a governance model that invites more voices to the table. Translation: fewer surprises, more stability, and maybe fewer tweets from angry contributors.Expert corner: what's the web community talking about?🎙The dev community’s looking ahead: Some cloning apps for fun, others predicting frameworks, ethics, and AI identity crises. 2025’s shaping up to be less about syntax, more about choices. And yes, vibe shifts included.🎥 CLI? GUI? Try LLM: Viktor Farcic demonstrates how AI can streamline interactions with IDPs. More intuitive than GUIs, more powerful than CLIs. From querying databases to spinning up infrastructure, we're heading toward a prompt-first future.🔭 The 2025 web dev forecast: AI, edge, and... ethics?: Expect more AI, fewer servers, and a rising need for ethical tech decisions. It’s a future full of promise and job titles that don’t exist yet. Edge-native empathy engineer, anyone?🧱 Framework face-off: what to keep an eye on in 2025: From React’s continued dominance to the rise of Qwik and Astro, the framework battlefield is getting crowded. The message? Choose wisely or you’ll be explaining your pick in every team meeting for the next year.🌀 Stack Overflow’s AI gamble and the dev identity crisis: Stack Overflow is leaning hard into AI to stay relevant, but in doing so, it might be redefining what it means to be a “developer.” Is AI the new stack, or just another tool in the belt? Existential crisis loading...📈 Web trends devs can’t ignore in 2025: Think accessibility-first, no-code/low-code evolution, and AI-as-co-pilot. TL;DR: If your stack isn’t flexing with user-centric design, you might be the bottleneck.Packt catalogue plus a bonus excerpt📚📘 Learn React Hooks, 2nd Edition by Daniel BuglReact 19 is here, and with it comes a sharper, cleaner, more powerful Hooks story. If you’re still reaching for useStateand calling it a day, this book is your next upgrade.Author Daniel Bugl walks you through everything, from building your first Hook-based app to writing custom Hooks, handling form actions, and replacing class components like it’s 2018 calling.Grab your copy!About the authorDaniel Bugl is a full-stack developer, product designer, and entrepreneur specializing in web technologies. He holds a BSc in business informatics and an MSc in data science from TU Wien. A contributor to open source and an active React community member, he founded TouchLay, a hardware/software startup helping businesses showcase their offerings. He’s also served as a technical advisor and full-stack dev for large enterprises and the Austrian government, building citizen services and more.Here’s an excerpt from the book that shows how to make state shareable, clean, and debounced, using a custom Hook that syncs with the URL without spamming history.Creating the Debounced History State HookLet’s now get started extracting the code from the CreatePost component into a DebouncedHistory State Hook:1. Copy the Chapter12_3 folder to a new Chapter12_4 folder by executing the following command: $ cp -R Chapter12_3 Chapter12_42. Open the new Chapter12_4 folder in VS Code.3. Create a new src/hooks/debouncedHistoryState.js file.4. Inside it, import the following: import { useState, useEffect } from 'react' import { useDebouncedCallback } from 'use-debounce' import { useHistoryState } from '@uidotdev/usehooks'5. Define a function that accepts an initial state and a timeout value for the debounce: export function useDebouncedHistoryState(initialState, timeout) {6. Now, define the History State Hook: const { state, set, undo, redo, clear, canUndo, canRedo } = useHistoryState(initialState)7. Next, define a State Hook for the actively edited content: const [content, setContent] = useState(initialState)8. Then, define a Debounced Callback Hook that will set the value of the History State Hook: const debounced = useDebouncedCallback((value) => set(value), timeout)9. Add the Effect Hook that we had before in the CreatePost component: useEffect(() => { debounced.cancel() setContent(state) }, [state, debounced])Remember, this Effect Hook is used to sync the History State back into the actively editedcontent state, meaning that it will change the content of the textbox whenever we triggerthe undo, redo, or clear functionality.10. Now, define a handler function which sets the content state and starts the debouncedcallback: function handleContentChange(e) { const { value } = e.target setContent(value)debounced(value)}11. Finally, return all the values and functions we need from the Hook:return { content, handleContentChange, undo, redo, clear, canUndo,canRedo }}We now have a drop-in replacement for the Debounced History State functionality, which is used in the CreatePostcomponent, so let’s implement it!AI in the spotlight 🔦🤖 Even Sundar Pichai’s vibe-coding nowVibe coding? You know it, you’ve seen it, you might already be doing it. Now Sundar Pichai’s officially on board. The Google CEO revealed he’s been spending time riffing with AI tools, coding by description, not syntax. If the guy running Google is vibe-coding, safe to say it’s more than just a phase.Developer tip of the week 💡🛠️ Don’t sleep on SCIMIf you’re building anything that touches user management for enterprise clients, SCIM (System for Cross-domain Identity Management) isn’t just a nice-to-have, it’s table stakes. This spec handles user provisioning, deprovisioning, and role updates automatically via APIs. Translation: no more janky sync scripts or angry IT teams. It’s the kind of protocol you won’t notice... until you desperately need it. Learn it before your biggest customer asks why you don’t support it.Keep a dev journal🌿Logging your daily wins, bugs, and lessons isn't just for retros, it's for you. A dev journal helps you track progress, spot patterns, and level up faster.Get started:📘 You should keep a developer’s journal – Stack Overflow🛠️ Flow by Invide – Minimalist dev journaling tool📋 Developer Brain Template – Notion MarketplaceStart small: jot down a few bullet points at the end of each day. Your future self will thank you!And that's a wrap 🎬Not every week reshapes your workflow but this one nudged the edges. From vibe-coding going mainstream to frameworks tightening up, and protocols like SCIM reminding us the boring bits still matter.Until next time, build thoughtfully.Cheers!Kinnari Chohan,Editor-in-chiefSUBSCRIBE FOR MORE AND SHARE IT WITH A FRIEND!*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}} @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} }
Read more
  • 0
  • 0

Kinnari Chohan
16 Jun 2025
10 min read
Save for later

WebDevPro #95: Latest Django, Python, Spring Tools Releases + Meta AI Privacy Scare

Kinnari Chohan
16 Jun 2025
10 min read
Crafting the Web: Tips, Tools, and Trends for DevelopersAdvertise with Us|Sign Up to the Newsletter @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} }WebDevPro #95: Latest Django, Python, Spring Tools Releases + Meta AI Privacy Scare 🌍🔍Crafting the Web: Tips, Tools, and Trends for DevelopersGet hands-on with MCP!Join us on July 19 for a 150-minute interactive MCP Workshop. Go beyond theory and learn how to build and ship real-world MCP solutions. Limited spots available! Reserve your seat today.Use code EARLY35 for 35% off Hi ,Bugfixes, AI upgrades, security alarms and one privacy blunder that has everyone talking. From core tooling like Django, Spring, and Python getting critical fixes, to OpenAI's smoother GPT-4o and a major misstep in Meta’s AI app design, this week’s webdev round-up is packed with updates that may not make the front page, but absolutely belong in your workflow.Here’s your quick brief:🛠️ Django 5.0.6 and 4.2.13 patch packaging bugs for smoother rollouts🌱 Spring Tools 4.31.0 brings sharper AOT query insight and Spring Boot 3.5 support🐍 Python 3.13.5 fixes a Windows regression affecting extension modules🤖 GPT-4o’s June update improves memory, function calls, and multimodal stability🕵️‍♂️ Meta’s AI app stirs privacy concerns after users share personal data publicly, unknowinglyIn the Expert corner, devs debate the value of Rust compiler speed, explore the rise of passkeys in Spring Security, and unpack how prompt-first AI design could reshape tooling entirely. Read Benj Edward’s o3-pro take or see how David Crawshaw wrestles with AI agents in real workflows.📘 This week’s book pick: Practical Serverless and Microservices with C#.Whether you’re scaling with Azure Functions or simplifying microservices with .NET Aspire, this guide hits both breadth and depth. Grab your copy today!Got a tip or take? Send it our way and you might see it featured in WebDevPro!Advertise with usInterested in reaching our audience? Reply to this email or write to kinnaric@packt.com.Learn more about our sponsorship opportunities here.Latest news: what's new in web development? 🧑‍💻 From framework fixes to AI feature upgrades (and one major privacy red flag), this week’s updates span the tools and topics shaping modern development. Whether you're deep in Python, Spring, or just keeping an eye on AI evolutions, here’s what’s worth your attention.🛠️ Django 5.0.6 and 4.2.13 Bugfix Releases: Django has issued bugfix releases 5.0.6 and 4.2.13, which are reissues of the previous 5.0.5 and 4.2.12 versions. These updates address packaging errors and ensure the stability and reliability of the framework for ongoing projects.🌱 Spring Tools 4.31.0 Sharpens the Dev Toolkit:The latest Spring Tools update brings smoother support for Spring Boot 3.5, better code navigation in VSCode/Eclipse with hierarchical symbols, and improved AOT query visibility. Plus, it’s fully compatible with the Eclipse 2025-06 release.🐍 Python 3.13.5 Fixes Windows Regression: Python 3.13.5 has been released to address a regression affecting Windows users, specifically an issue with the pyconfig.h file in the traditional installer. This fix ensures that extension module builds specify Py_GIL_DISABLED when targeting the free-threaded runtime, maintaining compatibility and stability for developers working on Windows platforms.🤖 OpenAI GPT-4o June Update: Enhanced Functionality:OpenAI has rolled out updates to GPT-4o, focusing on improving system behavior based on user feedback. Enhancements include more reliable memory usage, improved function calling accuracy, and increased stability in multi-modal interactions. These updates aim to make GPT-4o more intuitive and effective across various tasks.🕵️‍♂️ Meta AI App Raises Privacy Concerns:Meta's AI app, launched in April 2025, has come under scrutiny for potential privacy issues. The app features a "Discover" feed where users can share their interactions with the AI chatbot. However, many users have inadvertently shared sensitive information, including personal medical issues and legal matters, often linked to identifiable Instagram profiles. Privacy advocates express concern over users' misunderstanding of the visibility and privacy of their data.Focus mode: On (ft. Beats)🎧 Your code has a rhythm. Your focus should too. This week, we’re tuning into music that powers better dev sessions:Need Deep Flow? Try Endel for AI-generated soundscapes that sync with your circadian rhythm. Think: personalized ambient playlists that cut through noise (literally).Science-Backed Beats: Brain.fm is built on neuroscience. Their “Focus” mode has been shown to improve attention within 15 minutes—perfect for getting into deep work fast.Curated for Coders: Explore Programming Music, a GitHub-curated list of playlists and albums tailored for developers. From ambient to electronic, find your perfect coding soundtrack.Because sometimes the best productivity tool... is a good pair of headphones.Expert corner: what's the web community talking about?🎙What are developers really talking about right now? Whether it’s speculative AI, secure auth, or the eternal love-hate with compilers, this week’s community picks capture the pulse.🧠 Decoding AI "Reasoning" with OpenAI's o3-pro: Viktor Farcic demonstrates how AI can streamline interactions with IDPs. More intuitive than GUIs, more powerful than CLIs. From querying databases to spinning up infrastructure, we're heading toward a prompt-first future.🎙️ Exploring Passkeys with Spring Security:In a recent episode of A Bootiful Podcast, Daniel Garnier-Moiroux delves into the integration of passkeys within Spring Security applications. The discussion offers valuable insights into enhancing authentication mechanisms and the evolving landscape of web security.💰 Meta's $15 Billion Bet on Superintelligence:Meta is reportedly investing $15 billion to pursue the development of computerised "superintelligence," aiming to surpass current AI capabilities. This strategic move includes acquiring a significant stake in Scale AI and reflects Meta's ambition to regain its position in the AI race. The initiative has prompted discussions about the feasibility and ethical considerations of such advancements.🦀 Rust's Compiler Performance Debate:A thought-provoking blog post questions why Rust doesn't prioritize compiler performance more aggressively. The author suggests that while compiler speed is important, it's just one of many aspects the Rust community balances to maintain the language's robustness and safety guarantees.🤖 Programming with AI Agents:David Crawshaw shares his experiences and challenges in integrating AI agents into programming workflows. He emphasizes the importance of understanding the limitations and potential of agents, advocating for a balanced approach that combines human intuition with AI assistance.Packt catalogue plus a bonus excerpt📚📘 Practical Serverless and Microservices with C# by Gabriel Baptista and Francesco AbbruzzeseLearn how to build secure, scalable apps using Azure Functions, Container Apps, and .NET Aspire. This book shows you when to use microservices and serverless and when not to, while guiding you through real-world scenarios, cost planning, and best practices for cloud-native development.Pre-order now!Meet Gabriel...Gabriel Baptista is a tech leader with 20+ years in software development. He heads a team building retail and industrial apps, serves on a tech advisory board, teaches computer engineering, and co-founded start-ups in automation and logistics. He’s also taught software and IT at multiple institutions....and FrancescoFrancesco Abbruzzese, author of the MVC and Blazor Controls Toolkits, has championed the Microsoft web stack since ASP.NET MVC's inception. His company, Mvcct Team, builds web apps, tools, and services. He began with AI-based financial decision systems and later contributed to top-10 games like Puma Street Soccer.If you’ve worked with Kubernetes for local microservices testing, you know the setup can be heavy. In this excerpt from Practical Serverless and Microservices Applications with C# and Azure, see how the same scenario is simplified using .NET Aspire — a lighter, code-first way to orchestrate microservices locally:Using .NET Aspire in practiceIn this section, we will adapt the Kubernetes exampleto run with Aspire. As a first step, let’s copy the whole solution folder into another in a different location, so we can modify it without destroying the previous version.Then, let’s execute the following steps to prepare the overall solution:Add a new App Host project to the solution and call it CarSharingAppHost.Add a new .NET Aspire Service Defaults project to the solution and call it CarSharingServiceDefaults.Add a reference to the FakeSource, FakeDestination, and RoutesPlanning projects to the CarSharingAppHost Add a reference to the CarSharingServiceDefaults project to the FakeSource, FakeDestination, and RoutesPlanning Right-click on the CarSharingAppHost project and, in the menu that appears, select Set as Startup Project.The preceding steps prepare the solution for .NET Aspire. Now, let’s start modifying the code. As a first step, we must add service defaults to all the microservices. Therefore, let’s add builder.AddServiceDefaults(); to the program.cs file of the FakeSource, FakeDestination, and RoutesPlanning projects. Then, we must add app.MapDefaultEndpoints(), which adds health endpoints just to the program.cs file of the RoutesPlanning project, since it is the only web project that we have among our microservices. It must be placed as shown here:var app = builder.Build();app.MapDefaultEndpoints();Now, let’s remember that we added all the microservices parameters as environment variables in their Properties/launcheSettings.json file. We placed them in the Docker launch settings. Now, since these projects will not use Docker anymore while running in Aspire, we must copy all these definitions into the other launch setting profile.This is the launch settings code of the RoutesPlanning project after this change:{"profiles": {"http": {"commandName": "Project","environmentVariables": {//place here your environment variables"ConnectionStrings__DefaultConnection": "Server=localhost;Database=RoutesPlanning;User Id=sa;Password=Passw0rd_;Trust Server Certificate=True;MultipleActiveResultSets=true","ConnectionStrings__RabbitMQConnection": "host=localhost:5672;username=guest;password=_myguest;publisherConfirms=true;timeout=10","Messages__SubscriptionIdPrefix": "routesPlanning","Topology__MaxDistanceKm": "50","Topology__MaxMatches": "5","Timing__HousekeepingIntervalHours": "48","Timing__HousekeepingDelayDays": "10","Timing__OutputEmptyDelayMS": "500","Timing__OutputBatchCount": "10","Timing__OutputRequeueDelayMin": "5","Timing__OutputCircuitBreakMin": "4"},"dotnetRunMessages": true,"applicationUrl": "http://localhost:5212"},"Container (Dockerfile)": {……Want the full walkthrough with real code, resource config, and deployment guidance?Pre-order the book!Developer tip of the week 💡🔐 Mastering OAuth 2.0: Secure Authorization SimplifiedUnderstanding OAuth 2.0 is crucial for modern web development, especially when dealing with third-party integrations. OAuth 2.0 allows users to grant limited access to their resources without sharing credentials. For instance, enabling an application to access your profile data without exposing your password.Key components of the OAuth 2.0 flow include:Resource Owner: The user who authorizes access.Client: The application requesting access.Authorization Server: Validates the user and issues access tokens.Resource Server: Hosts the protected resources.A typical flow involves the user authorizing the client, the client receiving an authorization grant, exchanging it for an access token from the authorization server, and then accessing the resource server using that token.And that's a wrap 🎬Another week, another stack of updates, hot takes, and low-key chaos. If your brain’s buzzing with thoughts, tools, or spicy dev opinions, don’t gatekeep.Until next time.Cheers!Kinnari Chohan,Editor-in-chiefSUBSCRIBE FOR MORE AND SHARE IT WITH A FRIEND!*{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}} @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} }
Read more
  • 0
  • 0
Kinnari Chohan
23 Jun 2025
8 min read
Save for later

WebDevPro #96: Smarter Python, Gemini’s Leaner AI, Tidier Laravel, and Fresh Insights from Miško Hevery

Kinnari Chohan
23 Jun 2025
8 min read
Crafting the Web: Tips, Tools, and Trends for Developers Advertise with Us|Sign Up to the Newsletter @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } WebDevPro #96: Smarter Python, Gemini’s Leaner AI, Tidier Laravel, and Fresh Insights from Miško Hevery 🌍🔍 Crafting the Web: Tips, Tools, and Trends for Developers Scale Smarter with MCP – Secure your Spot at 35% Off 🔥 Last chance to book at 35% OFF. Prices go up Tuesday! SAVE YOUR SPOT at 35% OFF — use code EARLY35 at checkout Hi , Welcome to WebDevPro #96. This week’s round-up packs sharp updates you’ll actually care about: 👥 State of React 2025: Redux’s Mark Erikson urges a healthier, more open React community. 🤖 Google launches production-ready Gemini 2.5 AI models: Google’s fastest AI yet, with new Pro and Flash-Lite models for scale. 🎤 TanStack Start vs. Next.js: Omer Syed on bleeding edge versus battle-tested. 🔦 Misko Hevery on Angular and LLMs: Why AI is your copilot but you're still in control. Want to be featured in WebDevPro? Share your tips or takes, we’re all ears! Advertise with us Interested in reaching our audience? Reply to this email or write to kinnaric@packt.com. Learn more about our sponsorship opportunities here. Latest news: what's new in web development? 🧑‍💻 🐍 Python 3.14.0b3 Now Available: Python 3.14’s third beta is out and it’s not holding back. We’re getting template strings, a tail-call-optimized interpreter, and remote debugging via pdb. It also brings Sigstore-based release signing, ditching old-school PGP. If you’re tracking Python’s evolution, this beta is a serious step forward. ⚙️ Laravel 12.0.11 Ships: Laravel 12.0.11 dropped with cleaner type declarations and a tidier .gitignore. It’s one of those updates that won’t break a thing but still makes your project feel better maintained. Good news for teams using static analysis tools. It’s small, but sharp. 🌱 Spring Framework Updates: The Spring team quietly pushed out updates across its ecosystem. Web Services, Vault, Pulsar, and the Authorization Server all got maintenance releases. These are bug-fix heavy with a few minor enhancements sprinkled in. Nothing flashy—but stability is a feature, right? 🤖 Gemini 2.5 Lands: Google Brings the Heat: Gemini 2.5 is here in Pro and Flash flavors, with Flash-Lite making its debut as Google’s leanest model yet. It’s fast, cheap, and built for high-volume apps. With multimodal input and longer context windows, Google’s aiming squarely at OpenAI’s turf. The AI race just got more crowded. 🗄️ pg_auto_reindexer v15 Released: PostgreSQL’s index cleaner just leveled up. Version 15 adds support for PG15, improves worker management, and trims bloat without locking your DB. It’s exactly the kind of tool you want running quietly in the background. Smart, efficient, and unassuming. Smarter breaks: Your brain’s best friend 🧠 Your brain wasn’t built for nonstop standups and JSX. Quick, intentional breaks can sharpen focus and cut down errors. But what should you do during a break? ⏳ Stack them into a 5-minute reset - twice a day is all it takes for sharper, healthier flow. Try these dev-friendly micro-breaks: 👀 Use Time Out (macOS) or Stretchly (Windows/Linux/macOS) to get regular reminders to pause and look away. 🤲 Follow this 2-minute wrist stretch routine to ease stiffness and reduce RSI risk. Ideal between commits. 🌿 Try Headspace’s 1-minute meditation to clear your head without leaving your desk. Expert corner: what's the web community talking about?🎙 ⚛️ TanStack Start vs. Next.js: Choosing the Right React Framework: In this deep technical comparison, Omer Syed explores how TanStack Start stacks up against the battle-tested Next.js for full-stack React development. While Next.js shines with its ecosystem and file-based routing, TanStack leans into cutting-edge primitives like React Server Components and deeply integrated caching. It’s a thoughtful breakdown for devs choosing between playing it safe or going fully modern, ideal for those who want performance and type safety from the start. 🧑‍🤝‍🧑 State of React and the Community in 2025: Redux maintainer Mark Erikson delivers an honest reflection on the cultural and communication challenges within the React ecosystem, from maintainer burnout to unclear roadmaps. By offering constructive suggestions and much-needed transparency, the post goes beyond code. It’s a call for a healthier, more collaborative open source culture that React developers can rally around. 🎨 Frontend Magic: Beyond the Usual Tricks: Kaiwen Wang shares a sharp and elegant list of underused frontend techniques like overflow: clip subtleties, scroll-boundary-behavior, and other layout-level optimizations. These aren’t your typical tips. They are the kind of details that turn good UIs into great ones. It’s a goldmine for frontend developers who love refining the edges of performance, polish, and user experience. Developer tip of the week 💡 Debug like a Pro with console.count() Next time you’re tracing tricky code paths, skip the manual counters and console.logspam. 👉 Drop console.count('myLabel') anywhere — it auto-tracks how many times that line runs. Example: function handleClick() { console.count('Click handler called'); // your logic } You’ll spot loops, duplicate events, or unexpected calls at a glance - no setup, no cleanup. 📌 Bonus: Use console.countReset('myLabel') to reset counts between flows. Packt catalogue: must read dev books📚 📘 Mastering Restful Web Services with Java by Marián Varga, Pedro Andrade, Silvio de Morais, Thiago Bomfim, and Igor Fraga A practical, hands-on guide to designing, building, documenting, testing, and deploying RESTful APIs using modern Java frameworks. Packed with examples, this book helps backend developers create scalable, secure, and production-ready APIs using Spring Boot, OpenAPI, and beyond. 📘 Covers full REST API lifecycle from design to deployment 🧪 Includes testing strategies with AI-powered tools like ChatGPT 🔒 Focus on security, observability, and performance tuning 🐳 Hands-on with Spring Boot, OpenAPI, Docker, and more Grab your copy! Exclusive expert spotlight: Miško Hevery on Angular, LLMs, and the future of development 🎤 This week we’re back with Miško Hevery, creator of Angular and Qwik, and currently CTO at Builder.io. With a career dedicated to building fast and scalable web apps, Miško has helped shape how modern development is done at scale. In this follow-up interview, Miško shares his thoughts on where LLMs add real value, why human understanding still matters, and what developers should focus on learning today. 🎥 Watch the clip onX. Follow us on WebDevPro for more dev insights and hot takes. Would learning a framework like Angular still be relevant in the years to come, or will AI and LLMs take over most of development? No, I think at the end of the day, you still need to understand things. LLMs are like expert systems—they’re great at answering your questions, but you're still the one driving. Maybe one day, LLMs will do all the driving, but we’re far from that. Right now, you still need to be aware of what’s going on. LLMs are fantastic for helping you translate knowledge—like asking, “I know how to do this in Angular, how would I do it in React?” They’re accelerators, not replacements. Think of it this way: if no one had written content about frameworks, LLMs wouldn't be able to help. They rely on the massive body of blog posts, tutorials, and docs that already exist. You can think of them as compressing all that shared knowledge into a usable form. But you’re still in the driver’s seat. You’re still making decisions. LLMs can make you more productive—maybe even reduce the need for two extra engineers—but they don’t replace the developer. Not yet. 🎬 That’s your scoop from the dev-verse this week.If your brain’s buzzing with ideas or feedback, hit reply. Until next week. Cheers! Kinnari Chohan, Editor-in-chief SUBSCRIBE FOR MORE AND SHARE IT WITH A FRIEND! *{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}} @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} }
Read more
  • 1
  • 1

Kinnari Chohan
30 Jun 2025
6 min read
Save for later

WebDevPro #97: LTS-Level Node Upgrades, Rust Introduces Let Chains, Claude Now Lets You Create Apps in Chat

Kinnari Chohan
30 Jun 2025
6 min read
Crafting the Web: Tips, Tools, and Trends for Developers Advertise with Us|Sign Up to the Newsletter @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } WebDevPro #97: LTS-Level Node Upgrades, Rust Introduces Let Chains, Claude Now Lets You Create Apps in Chat 🌍🔍 Crafting the Web: Tips, Tools, and Trends for Developers Hi , Welcome to WebDevPro #97! This week brings updates that you will want to bookmark. Let's start with the highlights: 🟢 Node.js v24.3.0 & v22.17.0 LTS Released: V8 upgrades, better diagnostics, and more stable production builds 🦀 Rust 1.88 Sharpens Safety and Extensibility: Adds non-exhaustive traits, assume intrinsic, and wildcard Cargo features 🧠 GitHub CEO: Manual Coding Still Matters: Thomas Dohmke reminds devs they're still essential—even in the AI era 📄 Claude’s “Artifacts” Feature: Turn chats into editable, versionable documents for collaborative projects ✨ Gemini CLI as Your AI Agent: Google’s new tool makes terminal scripting cleaner and AI-assisted We’ve rounded up releases, tools, and expert takes that sharpen your workflow and won’t waste your time. Scroll down and dig in. Latest news: what's new in web development? 🧑‍💻 🟢 Node.js v24.3.0 & v22.17.0 LTS Released: This week’s Node.js update delivers something for everyone. The current version, v24.3.0, upgrades to V8 12.4 and brings improved performance diagnostics and bug fixes. Meanwhile, v22.17.0 (LTS) is a stability-focused release with important security patches and production-ready enhancements. 🦀 Rust 1.88 Sharpens Safety and Extensibility: Rust 1.88.0 adds support for #[non_exhaustive] on traits, letting library authors design more resilient APIs. The release also introduces a new assume intrinsic for unsafe code optimizations and brings glob pattern support to Cargo’s --features flag. Clean, smart, and built for scale. 💡 Google Debuts Gemini CLI as an AI Agent for Your Terminal: Google’s Gemini CLI is now open source and ready to streamline dev workflows. It’s built for scripting, automation, and direct integration with Gemini models, right from your local terminal. Think AI-assisted coding, testing, and deployment all within reach of a simple command. 🧠 Claude’s New “Artifacts” Feature Adds Collaborative Muscle: Anthropic’s Claude just got a major UX upgrade. The new Artifacts feature turns conversations into editable, persistent code or content blocks, right inside the interface. This lets you iterate, refine, and co-develop with Claude in a much more interactive way. Ideal for code, writing, and docs. 📦 JSON Imports Now Baseline Across Major Browsers: Importing JSON just got simpler; no bundler tricks required. That means you can now import data from './file.json' directly in your modules. It’s a small change with big cleanup potential for modern JavaScript projects. ☕ Jakarta EE 11 Is Official with Java 21 Support: Jakarta EE 11 has landed, marking the platform’s first feature release under a faster, six-month cadence. It adds support for Java 21, introduces a leaner Core Profile for modern workloads, and reaffirms Jakarta’s push toward cloud-native enterprise Java. This is the most forward-looking EE release in years. Eyes on the prize, not the strain 👁️ After a marathon of debugging and deployments, your eyes deserve a break. Whether you’ve been wrangling flexboxes or frameworks, this one’s for you. Try the 20-20-20 Rule: Every 20 minutes, look at something 20 feet away for 20 seconds. This quick habit helps reduce digital eye strain, boost focus, and protect long-term eye health. 🔬 Learn the science behind it: How a simple visual reset can make a big difference. 🧘 Get a gentle reminder: Install the 20-20-20 EyeCare Chrome extension, it’ll nudge you to take breaks before the fatigue kicks in. Expert corner: what's the web community talking about?🎙 🧠 GitHub CEO says AI Can’t Replace Manual Coding (Yet): In a recent interview with The New Stack, GitHub CEO Thomas Dohmke emphasized that AI is a productivity enhancer, not a replacement for human developers. His message echoes a growing sentiment in the dev community: large language models are powerful tools, but understanding how and why your code works still matters more than ever. ⚡️ Python devs meet ‘uv’ the new pip for lightning-fast Docker builds: Nick Janetakis dives into switching from pip to uv, a new ultra-fast Python package installer. The result? Dramatically faster Docker image builds, especially for Flask or Django apps. If you're optimizing for CI/CD speed, this swap might be your new secret weapon. 🛠️ Building AI Text Apps with React + Vite + OpenAI: This DZone tutorial breaks down how to spin up an AI-powered text analysis app using React, Vite, and the OpenAI API. Beyond the basics, it covers token management, real-time user interaction, and prompt engineering tips. Ideal if you're exploring LLM integration in frontend workflows. 🔄 Event-Driven Architectures Meet MCP for Maximum Flexibility: If you're exploring ways to simplify asynchronous workflows in complex systems, this intro to Multi-Channel Processing (MCP) shows how it can complement event-driven architectures. It's a high-level overview, but useful if you're mapping patterns for large-scale service orchestration. ⚛️ Preact Signals rethink state with zero virtual DOM fuss: Preact’s signals are gaining traction among performance-first JavaScript developers. This guide explains how they deliver fine-grained reactivity without the overhead of virtual DOM diffing or excessive state management. A strong case for rethinking the state in lean web apps. Want to be featured in WebDevPro? Share your tips or takes, we’re all ears! Workshop: Unpack OWASP Top 10 LLMs with Snyk REGISTER TODAY Join Snyk and OWASP Leader Vandana Verma Sehgal on Tuesday, July 15 at 11:00AM ET for a live session covering: ✓ The top LLM vulnerabilities ✓ Proven best practices for securing AI-generated code ✓ Snyk’s AI-powered tools automate and scale secure dev. See live demos plus earn 1 CPE credit! Advertise with us Interested in reaching our audience? Reply to this email or write to kinnaric@packt.com. Learn more about our sponsorship opportunities here. Packt catalogue: must read dev books📚 📘 Practical Serverless and Microservices with C# on Azure by Gabriel Baptista and Francesco Abbruzzese This book helps C# developers transition to cloud-native thinking by building scalable, event-driven systems using Azure services. It's hands-on, practical, and tailored to real-world production needs. Why pick it up: ✅ Learn how to build serverless APIs with Azure Functions ✅ Apply microservices architecture patterns in C# ✅ Master event-driven workflows using Event Grid and Service Bus Grab your copy! 🎬 That’s your scoop from the dev-verse this week.If your brain’s buzzing with ideas or feedback, hit reply. Until next week. Cheers! Kinnari Chohan, Editor-in-chief SUBSCRIBE FOR MORE AND SHARE IT WITH A FRIEND! *{box-sizing:border-box}body{margin:0;padding:0}a[x-apple-data-detectors]{color:inherit!important;text-decoration:inherit!important}#MessageViewBody a{color:inherit;text-decoration:none}p{line-height:inherit}.desktop_hide,.desktop_hide table{mso-hide:all;display:none;max-height:0;overflow:hidden}.image_block img+div{display:none}sub,sup{font-size:75%;line-height:0}#converted-body .list_block ol,#converted-body .list_block ul,.body [class~=x_list_block] ol,.body [class~=x_list_block] ul,u+.body .list_block ol,u+.body .list_block ul{padding-left:20px} @media (max-width: 100%;display:block}.mobile_hide{min-height:0;max-height:0;max-width: 100%;overflow:hidden;font-size:0}.desktop_hide,.desktop_hide table{display:table!important;max-height:none!important}} @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} } @media only screen and (max-width: 100%;} #pad-desktop {display: none !important;} }
Read more
  • 0
  • 0
Modal Close icon
Modal Close icon