<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Giuseppe Ciullo</title>
    <description>The latest articles on DEV Community by Giuseppe Ciullo (@josephciullo).</description>
    <link>https://dev.to/josephciullo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F560929%2Fbfccfc40-7750-4abe-a28a-48c18d3e5633.jpeg</url>
      <title>DEV Community: Giuseppe Ciullo</title>
      <link>https://dev.to/josephciullo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/josephciullo"/>
    <language>en</language>
    <item>
      <title>The Day AI Argued With MDN (And Lost)</title>
      <dc:creator>Giuseppe Ciullo</dc:creator>
      <pubDate>Tue, 16 Jun 2026 09:33:49 +0000</pubDate>
      <link>https://dev.to/josephciullo/the-day-ai-argued-with-mdn-and-lost-mm7</link>
      <guid>https://dev.to/josephciullo/the-day-ai-argued-with-mdn-and-lost-mm7</guid>
      <description>&lt;p&gt;AI coding assistants have fundamentally changed the way we write software. Today it's perfectly normal to ask ChatGPT, Claude, Cursor, or Copilot to explain an API, generate a React component, review a pull request, or help debug a problem. For many developers, these tools have become part of the daily workflow.&lt;/p&gt;

&lt;p&gt;Yet there's one area where they still struggle more than we'd like to admit: understanding the current state of the web platform.&lt;/p&gt;

&lt;p&gt;Mozilla recently demonstrated this problem in a surprisingly direct way. While evaluating Claude Code on recently released Firefox features, the team discovered that the model confidently claimed Firefox didn't support the Web Serial API and that Mozilla had no plans to implement it. The answer sounded plausible, detailed, and authoritative.&lt;/p&gt;

&lt;p&gt;There was just one issue.&lt;/p&gt;

&lt;p&gt;Firefox had already shipped support for the API.&lt;/p&gt;

&lt;p&gt;That experiment became one of the motivations behind Mozilla's new &lt;strong&gt;MDN MCP Server&lt;/strong&gt;, a tool designed to give AI assistants direct access to MDN documentation and browser compatibility data. More importantly, Mozilla didn't just launch the service—they tested whether it actually improves the quality of AI-generated answers.&lt;/p&gt;

&lt;p&gt;The results are worth paying attention to.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Real Problem Isn't Hallucination
&lt;/h2&gt;

&lt;p&gt;When discussions about AI reliability come up, the conversation usually focuses on hallucinations. But browser compatibility is a slightly different problem.&lt;/p&gt;

&lt;p&gt;The web platform evolves continuously. Browsers ship new APIs, CSS features, HTML capabilities, and compatibility updates every few weeks. Specifications change, Baseline statuses evolve, and features that were experimental yesterday can become production-ready tomorrow.&lt;/p&gt;

&lt;p&gt;Large language models, on the other hand, are trained on snapshots of information. Even highly capable models can only know what was available when they were trained. When they're asked about something that appeared later—or something that wasn't widely represented in their training data—they often have to rely on incomplete information.&lt;/p&gt;

&lt;p&gt;The result isn't always a hallucination in the traditional sense. Sometimes it's simply an answer that would have been correct several months ago but is no longer accurate today.&lt;/p&gt;

&lt;p&gt;As frontend developers, we've all developed the same habit: ask the AI first, then open MDN to verify the answer.&lt;/p&gt;

&lt;p&gt;Mozilla's experiment explored what happens when the AI can consult MDN directly before answering.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mozilla Decided to Test It
&lt;/h2&gt;

&lt;p&gt;Rather than discussing the problem in theory, the MDN team decided to measure it.&lt;/p&gt;

&lt;p&gt;They evaluated Claude Code Opus 4.7 using a set of recently released Firefox 151 features, including support for &lt;code&gt;light-dark()&lt;/code&gt; images, the &lt;code&gt;:buffering&lt;/code&gt; pseudo-class, the &lt;code&gt;shadowrootslotassignment&lt;/code&gt; attribute, and the Web Serial API.&lt;/p&gt;

&lt;p&gt;These aren't the kinds of features you'll find in every tutorial or blog post. They're recent additions to the platform, which makes them particularly useful for testing whether an AI model truly understands the current state of browser support or is relying on older information.&lt;/p&gt;

&lt;p&gt;In other words, Mozilla deliberately chose questions that would expose the gap between what the model remembered and what was actually true.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Web Serial API Example
&lt;/h2&gt;

&lt;p&gt;The most striking result involved the Web Serial API.&lt;/p&gt;

&lt;p&gt;When asked about browser support, Claude Code stated that Firefox didn't support the API. It went even further, claiming that Mozilla had no plans to support it in the future.&lt;/p&gt;

&lt;p&gt;For someone unfamiliar with the feature, the response would have sounded completely reasonable. It contained enough context and confidence to feel trustworthy.&lt;/p&gt;

&lt;p&gt;The problem was that Firefox 151 had already shipped Web Serial support.&lt;/p&gt;

&lt;p&gt;What makes this example particularly interesting isn't simply that the answer was wrong. Developers expect AI systems to make mistakes occasionally. The real issue is that the answer looked credible. If you weren't already familiar with the feature, there would be little reason to question it.&lt;/p&gt;

&lt;p&gt;This is one of the biggest challenges when using AI for frontend development. A response can be coherent, detailed, and technically sophisticated while still being disconnected from reality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why It Happens
&lt;/h2&gt;

&lt;p&gt;Imagine asking an AI assistant a simple question:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Does Firefox support the Web Serial API?

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without access to current documentation, the model has to rely on whatever information was available during training. If support was added recently, the model may not know about it. If the feature wasn't widely discussed, it may have only partial information.&lt;/p&gt;

&lt;p&gt;Unlike a search engine, the model isn't retrieving facts from a database. It's generating the most likely answer based on patterns it has learned.&lt;/p&gt;

&lt;p&gt;That's why these mistakes can be so convincing. The model isn't intentionally inventing information—it is trying to produce a coherent response with incomplete knowledge.&lt;/p&gt;

&lt;p&gt;And because language models are optimized for answering questions, they rarely respond with "I don't know."&lt;/p&gt;

&lt;h2&gt;
  
  
  Enter MCP
&lt;/h2&gt;

&lt;p&gt;To address this problem, Mozilla launched the &lt;strong&gt;MDN MCP Server&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;MCP, or &lt;strong&gt;Model Context Protocol&lt;/strong&gt;, is an open standard that allows AI models to interact with external tools and data sources. Instead of relying entirely on training data, a model can retrieve information when it needs it.&lt;/p&gt;

&lt;p&gt;The difference may sound subtle, but it's significant.&lt;/p&gt;

&lt;p&gt;Without MCP, the workflow looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer → AI Memory → Answer

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With MCP, it becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer → AI → MDN → Answer

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rather than answering solely from memory, the model can consult documentation, retrieve compatibility information, and verify assumptions before generating a response.&lt;/p&gt;

&lt;p&gt;For a domain that changes as quickly as the web platform, that's a major advantage.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Does the MDN MCP Server Provide?
&lt;/h2&gt;

&lt;p&gt;The MDN MCP Server exposes MDN resources in a format specifically designed for AI systems.&lt;/p&gt;

&lt;p&gt;This includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Documentation search&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;MDN documentation content&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Browser Compatibility Data (BCD)&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of searching the web and parsing HTML pages, AI assistants can access structured information directly from one of the most trusted sources in web development.&lt;/p&gt;

&lt;p&gt;The goal isn't to replace documentation. It's to make documentation part of the AI workflow.&lt;/p&gt;

&lt;h2&gt;
  
  
  Mozilla Ran the Tests Again
&lt;/h2&gt;

&lt;p&gt;After enabling the MDN MCP Server, Mozilla repeated the same evaluation.&lt;/p&gt;

&lt;p&gt;This time, Claude Code could retrieve information directly from MDN and Browser Compatibility Data rather than relying entirely on memory.&lt;/p&gt;

&lt;p&gt;The improvement was substantial.&lt;/p&gt;

&lt;p&gt;Recently released features were identified correctly. Browser compatibility information became significantly more reliable. Unsupported assumptions appeared less frequently, and responses aligned much more closely with the current state of the platform.&lt;/p&gt;

&lt;p&gt;In practical terms, the model no longer had to guess. It could verify information before answering.&lt;/p&gt;

&lt;p&gt;That distinction may sound small, but it's arguably the most important benefit MCP provides.&lt;/p&gt;

&lt;h2&gt;
  
  
  It Was Faster Too
&lt;/h2&gt;

&lt;p&gt;One of the most surprising findings had nothing to do with accuracy.&lt;/p&gt;

&lt;p&gt;Mozilla reported that responses generated with the MDN MCP Server enabled were roughly twice as fast.&lt;/p&gt;

&lt;p&gt;At first glance, that seems counterintuitive. Querying an external service sounds like it should introduce additional overhead.&lt;/p&gt;

&lt;p&gt;In practice, the opposite happened.&lt;/p&gt;

&lt;p&gt;Without MCP, the assistant often needed to search the web, open multiple pages, parse HTML content, extract relevant information, and then synthesize a response. With MCP, that information was already available through structured tools designed specifically for machine consumption.&lt;/p&gt;

&lt;p&gt;The model spent less time searching and more time answering.&lt;/p&gt;

&lt;p&gt;The result was faster responses and better information at the same time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Practical Examples
&lt;/h2&gt;

&lt;p&gt;The value of this becomes clear almost immediately in day-to-day frontend work.&lt;/p&gt;

&lt;p&gt;The Web Serial API example is a perfect illustration. Instead of receiving an answer based on potentially outdated knowledge, you can ask questions about browser support and get responses grounded in current MDN data.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Does Firefox support the Web Serial API?
What browsers can I safely target today?

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same becomes even more interesting when working with modern browser APIs in React.&lt;/p&gt;

&lt;p&gt;Imagine asking an AI assistant:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Using the latest MDN documentation, create a React hook
for the View Transitions API.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because the assistant has access to MDN, it can validate compatibility information before generating code and produce something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useCallback&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;useViewTransition&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;useCallback&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;startViewTransition&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;startViewTransition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;update&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The hook itself isn't particularly complex. What's interesting is the context that accompanies it. The assistant can explain which browsers currently support the API, whether the feature has reached Baseline status, what fallback strategy should be implemented, and whether it's safe to use in production today.&lt;/p&gt;

&lt;p&gt;That's exactly the kind of information that tends to become outdated quickly when a model relies exclusively on training data.&lt;/p&gt;

&lt;p&gt;You can also ask questions such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Using MDN compatibility data, explain whether
requestIdleCallback is safe to use in production.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of answering from memory, the assistant can verify its response against current documentation before making a recommendation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Compatible Clients
&lt;/h2&gt;

&lt;p&gt;Although Mozilla's examples focus on Claude Code, the MDN MCP Server isn't tied to a specific AI vendor.&lt;/p&gt;

&lt;p&gt;Any MCP-compatible client can potentially use it, including Claude Code, Claude Desktop, Cursor, VS Code MCP integrations, Zed, Codex CLI, Antigravity CLI, and other MCP-enabled applications.&lt;/p&gt;

&lt;p&gt;As support for MCP continues to grow, direct access to authoritative documentation may become a standard feature of developer tooling rather than a niche capability.&lt;/p&gt;

&lt;p&gt;For example, adding the MDN MCP Server to Claude Code is as simple as running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;claude mcp add &lt;span class="nt"&gt;--transport&lt;/span&gt; http mdn https://mcp.mdn.mozilla.net/

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Bigger Story
&lt;/h2&gt;

&lt;p&gt;The most important takeaway from Mozilla's experiment isn't that they launched another developer tool.&lt;/p&gt;

&lt;p&gt;It's that they exposed a fundamental limitation of modern AI systems.&lt;/p&gt;

&lt;p&gt;The Web Serial API example demonstrates something every developer should keep in mind: confidence is not the same thing as correctness. An answer can be detailed, coherent, and technically sophisticated while still being wrong.&lt;/p&gt;

&lt;p&gt;For years, conversations about AI have focused on building larger models with more knowledge. Mozilla's experiment suggests a different direction. The future may not belong to models that memorize everything. It may belong to models that know how to retrieve trustworthy information when their knowledge is incomplete.&lt;/p&gt;

&lt;p&gt;That's a subtle distinction, but it has enormous implications for software development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;For a long time, the safest workflow looked something like this: ask the AI, open MDN, and verify everything manually.&lt;/p&gt;

&lt;p&gt;Mozilla's MCP Server doesn't eliminate that responsibility, and it certainly doesn't make AI infallible. Developers should still think critically about the code and recommendations they receive.&lt;/p&gt;

&lt;p&gt;What Mozilla's results suggest, however, is that giving AI systems direct access to authoritative sources can dramatically improve both accuracy and speed. The Web Serial API test showed just how easily a model can be confidently wrong when it's forced to rely solely on memory.&lt;/p&gt;

&lt;p&gt;MCP won't solve every problem. But if the future of AI-assisted development is going to work, it will probably look less like AI replacing documentation and more like AI reading the documentation alongside us.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Orchestrating Scalable Frontends: The Power of the Composition Root</title>
      <dc:creator>Giuseppe Ciullo</dc:creator>
      <pubDate>Fri, 20 Feb 2026 10:39:29 +0000</pubDate>
      <link>https://dev.to/josephciullo/orchestrating-scalable-frontends-the-power-of-the-composition-root-3b0a</link>
      <guid>https://dev.to/josephciullo/orchestrating-scalable-frontends-the-power-of-the-composition-root-3b0a</guid>
      <description>&lt;p&gt;In previous chapters, we built the foundations of our frontend architecture. With Atomic Design, we organized our UI into shared/components, separating reusable, domain-agnostic elements from specific contexts. With Feature-Driven Architecture, we isolated the domain by introducing features/ as autonomous business units.&lt;/p&gt;

&lt;p&gt;But a real-world application isn't just a collection of isolated modules. It is a system where domains must collaborate. The question becomes inevitable: How can we allow features to communicate with each other without destroying the isolation we just built?&lt;/p&gt;

&lt;p&gt;The answer lies in introducing a higher level of orchestration: the Pages layer acting as a Composition Root.&lt;/p&gt;




&lt;h2&gt;
  
  
  Revisiting the Structure
&lt;/h2&gt;

&lt;p&gt;Our architecture, consistent with our previous principles, looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├─ shared/             # Reusable UI &amp;amp; utilities (Atomic Design)
├─ features/           # Isolated domains (Feature-Driven)
│   ├─ cart/
│   └─ checkout/
├─ pages/              # Orchestration &amp;amp; Composition Layer
└─ app/                # Global bootstrapping

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have already defined a fundamental rule: &lt;strong&gt;A feature can depend on &lt;code&gt;shared/&lt;/code&gt;, but it must not know about the existence of other features.&lt;/strong&gt; &lt;code&gt;features/cart&lt;/code&gt; should never import anything from &lt;code&gt;features/checkout&lt;/code&gt;. This is not a technical limitation; it is a design choice that preserves domain independence.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Risk of the "Cannibal Feature" (God Feature)
&lt;/h2&gt;

&lt;p&gt;Why can't we just let features talk to each other? Because refusing a higher orchestration layer exposes us to a fatal risk: &lt;strong&gt;Feature Cannibalization&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In a flat architecture, if the &lt;code&gt;Cart&lt;/code&gt; needs to trigger the &lt;code&gt;Checkout&lt;/code&gt;, a developer will eventually be forced to import the Checkout module into the Cart. At that moment, isolation vanishes. One of the two features "eats" the other, becoming a bloated module—a &lt;strong&gt;God Feature&lt;/strong&gt;—that drags along dependencies, logic, and types that do not belong to it.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Illusion of Simplicity
&lt;/h3&gt;

&lt;p&gt;Eliminating the &lt;code&gt;pages/&lt;/code&gt; layer might seem like a simplification. In reality, we are just hiding complexity. If the &lt;code&gt;Cart&lt;/code&gt; feature contains the navigation logic to the &lt;code&gt;Checkout&lt;/code&gt;, that component is no longer truly reusable. If you wanted to use that &lt;code&gt;Cart&lt;/code&gt; in an informational Sidebar without a checkout tomorrow, you couldn't do it without dragging along the entire payment system.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;The principle is clear:&lt;/strong&gt; A Feature must be "dumb" regarding the global context to be "smart" regarding its business logic.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Pages as a Composition Root
&lt;/h2&gt;

&lt;p&gt;In the book &lt;em&gt;Clean Architecture&lt;/em&gt;, Robert C. Martin introduces the concept of the &lt;strong&gt;Composition Root&lt;/strong&gt;. It is the place where dependencies are assembled and modules are composed. In the frontend, the &lt;strong&gt;Page&lt;/strong&gt; represents this architectural pivot.&lt;/p&gt;

&lt;p&gt;The Page is not just a route container; it is the level where:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Features are instantiated.&lt;/li&gt;
&lt;li&gt;Their contracts (callbacks, events) are connected.&lt;/li&gt;
&lt;li&gt;Responsibilities are coordinated.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The Director and the Actors
&lt;/h3&gt;

&lt;p&gt;Think of the Page as a &lt;strong&gt;Theater Director&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Features&lt;/strong&gt; are the actors: they know how to play their part perfectly, but they don't decide when to enter the stage.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The Page&lt;/strong&gt; is the director: it knows that when Actor A (&lt;code&gt;Cart&lt;/code&gt;) emits an event, it must signal Actor B (&lt;code&gt;Checkout&lt;/code&gt;) to step in.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Hierarchy of Responsibilities
&lt;/h2&gt;

&lt;p&gt;The architecture takes a clear shape based on &lt;strong&gt;decreasing knowledge&lt;/strong&gt;:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Responsibility&lt;/th&gt;
&lt;th&gt;Knowledge Level&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;app/&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Bootstrapping&lt;/td&gt;
&lt;td&gt;Knows everything (Global State, Routing)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;pages/&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Orchestrate&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Knows multiple features, but not their internal logic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;features/&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Domain&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Knows only itself&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;shared/&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Utility&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Domain Agnostic (Knows nothing of business)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The correct flow is always vertical:&lt;br&gt;
&lt;strong&gt;Feature A  ←  Page  →  Feature B&lt;/strong&gt;&lt;br&gt;
(Never: Feature A → Feature B)&lt;/p&gt;


&lt;h2&gt;
  
  
  Substitutability and Maturity
&lt;/h2&gt;

&lt;p&gt;Many codebases start by allowing direct communication between modules. It works while the project is small. Over time, changes propagate unpredictably.&lt;/p&gt;

&lt;p&gt;Introducing an explicit orchestration layer is the moment a project stops being just "functional" and becomes truly &lt;strong&gt;evolvable&lt;/strong&gt;. Imagine wanting to replace the &lt;code&gt;checkout/&lt;/code&gt; domain entirely:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;features/
├─ cart/
├─ checkout/
└─ new-checkout/

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The only change occurs in the &lt;code&gt;pages/&lt;/code&gt; layer. The &lt;code&gt;Cart&lt;/code&gt; remains untouched. This is possible because orchestration is centralized in the composition root, not distributed across features.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Core Principle
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Features solve business problems.&lt;/li&gt;
&lt;li&gt;Pages solve coordination problems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Atomic Design gave us order in the UI. Feature-Driven Architecture gave us domain isolation. The Pages layer gives us &lt;strong&gt;control over the flows&lt;/strong&gt;. Separation is important, but knowing &lt;strong&gt;where to compose&lt;/strong&gt; is even more vital.&lt;/p&gt;




&lt;h3&gt;
  
  
  Next Step: Toward the Page-Level Store
&lt;/h3&gt;

&lt;p&gt;As long as the data flow is linear, composition via props in the Page is sufficient. But what happens when multiple features must stay synchronized in real-time or a complex dashboard requires shared state without violating isolation?&lt;/p&gt;

&lt;p&gt;In the next article, we will explore the &lt;strong&gt;Page-Level Store&lt;/strong&gt;: an ephemeral, page-scoped state that allows fluid communication while keeping domain boundaries intact.&lt;/p&gt;




&lt;p&gt;Connect on &lt;a href="https://www.linkedin.com/in/josephciullo/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; for more updates and insights.&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>webdev</category>
      <category>architecture</category>
      <category>react</category>
    </item>
    <item>
      <title>Feature-Driven Architecture: Designing Scalable Applications</title>
      <dc:creator>Giuseppe Ciullo</dc:creator>
      <pubDate>Mon, 02 Feb 2026 10:02:27 +0000</pubDate>
      <link>https://dev.to/josephciullo/feature-driven-architecture-designing-scalable-applications-2ac6</link>
      <guid>https://dev.to/josephciullo/feature-driven-architecture-designing-scalable-applications-2ac6</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;In the first article of this series, we discussed &lt;strong&gt;Atomic Design&lt;/strong&gt; as a method to build coherent, reusable, and well-composed interfaces.&lt;br&gt;
It’s an extremely effective approach when the main challenge is &lt;strong&gt;organizing the UI&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;But as an application grows, the UI soon stops being the real problem.&lt;/p&gt;

&lt;p&gt;Code increases, features multiply, requirements change faster than we’d like. At that point, new questions arise:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Where does the application logic really live?&lt;/li&gt;
&lt;li&gt;How can we modify one feature without breaking others?&lt;/li&gt;
&lt;li&gt;How can multiple people work on the same codebase without stepping on each other’s toes?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where &lt;strong&gt;architectural scalability&lt;/strong&gt; comes into play.&lt;br&gt;
And it’s exactly where Atomic Design alone is not enough.&lt;/p&gt;


&lt;h2&gt;
  
  
  Scalability is not just performance
&lt;/h2&gt;

&lt;p&gt;When we talk about scalability, we often immediately think about performance, load, or infrastructure.&lt;br&gt;
In reality, &lt;strong&gt;the first scalability problem is the code itself&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;An application doesn’t scale when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every new feature requires changes in multiple places&lt;/li&gt;
&lt;li&gt;Logic is scattered and hard to trace&lt;/li&gt;
&lt;li&gt;Dependencies between parts of the application are implicit and fragile&lt;/li&gt;
&lt;li&gt;Understanding the context of a change is more expensive than the change itself&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short: &lt;strong&gt;it doesn’t scale when cognitive overhead grows faster than the code&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Feature-Driven Architecture exists precisely to address this problem.&lt;/p&gt;


&lt;h2&gt;
  
  
  What a feature really is
&lt;/h2&gt;

&lt;p&gt;A &lt;em&gt;feature&lt;/em&gt; is not a single screen.&lt;br&gt;
It’s not even an isolated function.&lt;/p&gt;

&lt;p&gt;A feature is &lt;strong&gt;a unit of value for the user&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;From an architectural point of view, a feature represents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A clear objective&lt;/li&gt;
&lt;li&gt;A complete behavior&lt;/li&gt;
&lt;li&gt;A well-defined context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When a user says &lt;em&gt;“I want to do X”&lt;/em&gt;, they are usually referring to a feature.&lt;/p&gt;

&lt;p&gt;Thinking in terms of features shifts the focus:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;From technology to &lt;strong&gt;domain&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;From technical layers to &lt;strong&gt;functional value&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And this shift is what enables scalability.&lt;/p&gt;


&lt;h2&gt;
  
  
  Feature-Driven Architecture: the key principle
&lt;/h2&gt;

&lt;p&gt;The core principle is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Organize code around features, not technical layers.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Each feature becomes a &lt;em&gt;cohesive container&lt;/em&gt; that includes everything needed to implement that behavior.&lt;/p&gt;

&lt;p&gt;This doesn’t mean eliminating technical concepts, but &lt;strong&gt;reducing their visibility at a global level&lt;/strong&gt;.&lt;br&gt;
Details stay local to the feature, where they make sense.&lt;/p&gt;

&lt;p&gt;The main advantage:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A feature can evolve independently&lt;/li&gt;
&lt;li&gt;Context is clear and limited&lt;/li&gt;
&lt;li&gt;The system grows by &lt;strong&gt;addition&lt;/strong&gt;, not by &lt;strong&gt;entanglement&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And this is how an architecture scales.&lt;/p&gt;


&lt;h2&gt;
  
  
  Example: the &lt;code&gt;cart&lt;/code&gt; feature
&lt;/h2&gt;

&lt;p&gt;To make this more concrete, here’s an example of how a single feature might be organized:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;features/
└─ cart/
    ├─ components/   # UI elements specific to the cart
    ├─ helpers/      # reusable functions or logic helpers specific to the cart
    ├─ state/        # state management for the cart (local or global)
    ├─ views/        # pages or screens related to the cart
    ├─ types/        # type definitions or interfaces
    ├─ tests/        # tests for cart feature
    ├─ mocks/        # mock data or services for testing/development
    └─ index.ts      # entry point for exposing public parts of the feature
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example &lt;code&gt;index.ts&lt;/code&gt;:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Only expose what should be used outside the feature&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./components&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./helpers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./types&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Do NOT export state, views, tests, or mocks&lt;/span&gt;
&lt;span class="c1"&gt;// These remain internal to the feature&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ⚠️ Important rules for exposing feature parts
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Expose only what is meant to be used outside the feature.&lt;/strong&gt;&lt;br&gt;
Components, helpers, and types are usually safe to export.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Keep everything else private.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;state/&lt;/code&gt; → internal state logic&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;views/&lt;/code&gt; → screens or containers&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;tests/&lt;/code&gt; → testing code&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mocks/&lt;/code&gt; → fake data&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Always use the &lt;code&gt;index.ts&lt;/code&gt; as the single entry point for external usage.&lt;/strong&gt;
This keeps the feature &lt;strong&gt;encapsulated&lt;/strong&gt; and makes the boundaries clear.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Combining Atomic Design and Feature-Driven Architecture
&lt;/h2&gt;

&lt;p&gt;Atomic Design and Feature-Driven Architecture are not mutually exclusive—they can complement each other perfectly.&lt;br&gt;
While features contain the business logic, state, views, and tests, &lt;strong&gt;Atomic Design provides a shared language for building UI components&lt;/strong&gt; that can be reused across multiple features.&lt;/p&gt;

&lt;p&gt;Here’s an example of how the folder structure could look when combining both approaches:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;features/
├─ cart/
│   ├─ components/
│   ├─ helpers/
│   ├─ state/
│   ├─ views/
│   ├─ types/
│   ├─ tests/
│   ├─ mocks/
│   └─ index.ts
├─ checkout/
└─ wishlist/

shared/
├─ components/
│   ├─ atoms/        
│   ├─ molecules/    
│   └─ organisms/    
└─ utils/            # shared utilities, helpers, and services
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key points:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;shared/components/atoms, molecules, organisms&lt;/code&gt; → reusable UI building blocks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;features/&lt;/code&gt; → contains everything a feature needs to work independently&lt;/li&gt;
&lt;li&gt;Features can &lt;strong&gt;use shared atomic components&lt;/strong&gt; while keeping their own feature-specific components inside &lt;code&gt;components/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;This approach keeps &lt;strong&gt;reusability clear, modularity high, and boundaries well defined&lt;/strong&gt;, allowing both UI and business logic to scale independently&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By combining Atomic Design with Feature-Driven Architecture, we get the best of both worlds:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;consistent, reusable UI&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;scalable, autonomous features&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Features and reusability: a mindset shift
&lt;/h2&gt;

&lt;p&gt;One of the most interesting effects of this approach is how it changes the concept of reusability.&lt;/p&gt;

&lt;p&gt;In a Feature-Driven Architecture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A feature is not reusable by default&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Reusability is a conscious choice, not an initial requirement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is very different from how we often think about architecture, especially on the UI side.&lt;/p&gt;

&lt;p&gt;Atomic Design remains extremely useful, but its role changes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It builds &lt;strong&gt;generic, stable elements&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;It doesn’t force reusability where it’s not needed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The feature becomes the place where complexity is &lt;strong&gt;accepted and managed&lt;/strong&gt;.&lt;br&gt;
Shared elements become few, solid, and truly generic.&lt;/p&gt;

&lt;p&gt;Less premature abstraction, more clarity.&lt;/p&gt;




&lt;h2&gt;
  
  
  Scaling the team, not just the code
&lt;/h2&gt;

&lt;p&gt;Another often overlooked aspect of scalability is the &lt;strong&gt;human factor&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When code is organized around features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Responsibilities are easier to assign&lt;/li&gt;
&lt;li&gt;The context is clearer&lt;/li&gt;
&lt;li&gt;Conflicts decrease&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Features become a natural unit for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Planning&lt;/li&gt;
&lt;li&gt;Parallel development&lt;/li&gt;
&lt;li&gt;Testing&lt;/li&gt;
&lt;li&gt;Maintenance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In practice, the architecture begins to reflect the way people &lt;strong&gt;think and work&lt;/strong&gt;.&lt;br&gt;
And that’s one of the strongest signs of a system that truly scales.&lt;/p&gt;




&lt;h2&gt;
  
  
  When it makes sense to adopt this approach
&lt;/h2&gt;

&lt;p&gt;Feature-Driven Architecture is not a silver bullet.&lt;/p&gt;

&lt;p&gt;It makes sense when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The application is expected to grow&lt;/li&gt;
&lt;li&gt;The domain is non-trivial&lt;/li&gt;
&lt;li&gt;Multiple people work on the same codebase&lt;/li&gt;
&lt;li&gt;Change is constant, not exceptional&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In very small applications, the initial overhead might not be justified.&lt;br&gt;
But when complexity is real, &lt;strong&gt;not organizing around features becomes more costly in the long run&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Feature-Driven Architecture teaches us to look beyond a single screen or component: organizing code around independent features reduces the risk of conflicts, isolates contexts, and makes the application clearer and easier to maintain.&lt;/p&gt;

&lt;p&gt;Scalability, in this sense, is not just a technical goal—it’s the &lt;strong&gt;ability of both the code and the team to grow without chaos&lt;/strong&gt;. Each feature becomes a manageable ecosystem that can evolve without compromising other parts of the application.&lt;/p&gt;

&lt;p&gt;In the next article, we’ll explore how to combine multiple features, orchestrate them, and make them work together without losing cohesion—taking a collection of independent units and turning it into a truly scalable frontend.&lt;/p&gt;




&lt;p&gt;Connect on &lt;a href="https://www.linkedin.com/in/josephciullo/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; for more updates and insights.&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>frontend</category>
      <category>softwareengineering</category>
      <category>webdev</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Giuseppe Ciullo</dc:creator>
      <pubDate>Fri, 16 Jan 2026 10:08:41 +0000</pubDate>
      <link>https://dev.to/josephciullo/-26mc</link>
      <guid>https://dev.to/josephciullo/-26mc</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/josephciullo" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F560929%2Fbfccfc40-7750-4abe-a28a-48c18d3e5633.jpeg" alt="josephciullo"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/josephciullo/atomic-design-from-ui-composition-to-real-world-applications-j25" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Atomic Design: From UI Composition to Real-World Applications&lt;/h2&gt;
      &lt;h3&gt;Giuseppe Ciullo ・ Jan 15&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#frontend&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#architecture&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#react&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>frontend</category>
      <category>webdev</category>
      <category>architecture</category>
      <category>react</category>
    </item>
    <item>
      <title>Atomic Design: From UI Composition to Real-World Applications</title>
      <dc:creator>Giuseppe Ciullo</dc:creator>
      <pubDate>Thu, 15 Jan 2026 15:49:07 +0000</pubDate>
      <link>https://dev.to/josephciullo/atomic-design-from-ui-composition-to-real-world-applications-j25</link>
      <guid>https://dev.to/josephciullo/atomic-design-from-ui-composition-to-real-world-applications-j25</guid>
      <description>&lt;p&gt;Atomic Design is one of the most frequently mentioned patterns when talking about frontend architecture.&lt;br&gt;
It’s easy to explain, easy to visualize, and it works really well… &lt;strong&gt;until the application starts to grow&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The problem is not Atomic Design itself, but &lt;strong&gt;the role we assign to it&lt;/strong&gt;.&lt;br&gt;
Using it as an application architecture leads to rigid structures that are hard to test and even harder to evolve.&lt;/p&gt;

&lt;p&gt;In this article we’ll explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what Atomic Design does &lt;strong&gt;really well&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;where its structural limits begin to show&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;how to place it correctly&lt;/strong&gt; inside a modern frontend architecture&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the first chapter of a series dedicated to &lt;strong&gt;frontend application architectures&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Atomic Design is a composition pattern, not an architecture
&lt;/h2&gt;

&lt;p&gt;Atomic Design was created to solve a specific problem:&lt;br&gt;
&lt;strong&gt;building consistent user interfaces by composing small, reusable components&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The model is well known:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Atoms&lt;/li&gt;
&lt;li&gt;Molecules&lt;/li&gt;
&lt;li&gt;Organisms&lt;/li&gt;
&lt;li&gt;Templates&lt;/li&gt;
&lt;li&gt;Pages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All of this answers one question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;How do I build the UI?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It does &lt;strong&gt;not&lt;/strong&gt; answer questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;where does the domain live?&lt;/li&gt;
&lt;li&gt;who orchestrates application flows?&lt;/li&gt;
&lt;li&gt;how does the application scale?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And this is where the misunderstanding often begins.&lt;/p&gt;


&lt;h2&gt;
  
  
  The real-world short circuit
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Organisms that turn into mini applications
&lt;/h3&gt;

&lt;p&gt;A typical “organism” that grows over time often ends up looking like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nf"&gt;fetchData&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;applyBusinessRules&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;manageGlobalState&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="nf"&gt;renderUI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;it is no longer a presentational component&lt;/li&gt;
&lt;li&gt;it becomes hard to test&lt;/li&gt;
&lt;li&gt;it is tightly coupled to a single feature&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The UI turns into the place where &lt;strong&gt;logic accumulates&lt;/strong&gt;, creating a monolith disguised as components.&lt;/p&gt;




&lt;h3&gt;
  
  
  The false Molecule vs Organism problem
&lt;/h3&gt;

&lt;p&gt;Many teams spend time asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Is this component a molecule or an organism?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In practice, this distinction is often &lt;strong&gt;subjective&lt;/strong&gt; and largely irrelevant.&lt;br&gt;
In a healthy architecture, the real question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Does this component know about the domain?&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the answer is yes, &lt;strong&gt;it does not belong in Atomic Design&lt;/strong&gt;, regardless of what you call it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem is not Atomic Design
&lt;/h2&gt;

&lt;p&gt;Atomic Design:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ organizes the UI&lt;/li&gt;
&lt;li&gt;❌ does not define domain boundaries&lt;/li&gt;
&lt;li&gt;❌ does not orchestrate application flows&lt;/li&gt;
&lt;li&gt;❌ does not manage business state&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Expecting it to do so means using it &lt;strong&gt;out of context&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  A proposal: separate UI and application architecture
&lt;/h2&gt;

&lt;p&gt;A sustainable frontend architecture is built on a clear separation between:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;UI Composition&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Application Architecture&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Atomic Design should live &lt;strong&gt;only in the first layer&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Atomic Design as a UI library (with a key rule)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;shared/
 └─ ui/
     ├─ atoms/
     ├─ molecules/
     └─ organisms/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  UI state vs Business state
&lt;/h3&gt;

&lt;p&gt;Components in &lt;code&gt;shared/ui&lt;/code&gt; &lt;strong&gt;may have state&lt;/strong&gt;, but only if it is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ephemeral&lt;/li&gt;
&lt;li&gt;interaction-related&lt;/li&gt;
&lt;li&gt;not a business decision&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Valid examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;isOpen&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;isHovered&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;isActive&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Invalid examples:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;global data&lt;/li&gt;
&lt;li&gt;backend-synchronized state&lt;/li&gt;
&lt;li&gt;application-level cache&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;UI components should &lt;strong&gt;never&lt;/strong&gt; be aware of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Redux / Zustand&lt;/li&gt;
&lt;li&gt;data-fetching libraries&lt;/li&gt;
&lt;li&gt;domain logic&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  Dependency Rule (non-negotiable)
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;Components in &lt;code&gt;shared/ui&lt;/code&gt; must &lt;strong&gt;never import anything from &lt;code&gt;features/&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This single rule:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;prevents hidden coupling&lt;/li&gt;
&lt;li&gt;keeps the UI truly reusable&lt;/li&gt;
&lt;li&gt;preserves architectural clarity over time&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Features as the primary architectural unit
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;features/
 ├─ products/
 ├─ cart/
 └─ checkout/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Features contain:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;business state&lt;/li&gt;
&lt;li&gt;side effects&lt;/li&gt;
&lt;li&gt;orchestration&lt;/li&gt;
&lt;li&gt;UI composition&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where &lt;strong&gt;the intelligence of the application&lt;/strong&gt; lives.&lt;/p&gt;




&lt;h2&gt;
  
  
  Testing strategy: an often underestimated benefit
&lt;/h2&gt;

&lt;p&gt;This separation improves not only the codebase, but &lt;strong&gt;the way we test&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  UI (Atomic Design)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Storybook&lt;/li&gt;
&lt;li&gt;visual regression testing&lt;/li&gt;
&lt;li&gt;visual snapshots&lt;/li&gt;
&lt;li&gt;accessibility testing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Focus:&lt;br&gt;
👉 &lt;em&gt;“Does this component look and behave correctly?”&lt;/em&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Features (Application Architecture)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;integration tests&lt;/li&gt;
&lt;li&gt;flow tests&lt;/li&gt;
&lt;li&gt;interaction between state, APIs, and UI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Focus:&lt;br&gt;
👉 &lt;em&gt;“Does this use case work?”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Separating UI and architecture also means separating &lt;strong&gt;testing responsibilities&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why this approach works
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Atomic Design stays simple&lt;/li&gt;
&lt;li&gt;the UI is predictable and reusable&lt;/li&gt;
&lt;li&gt;features are isolatable&lt;/li&gt;
&lt;li&gt;the domain is readable from the file system&lt;/li&gt;
&lt;li&gt;the application scales without increasing chaos&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each layer has &lt;strong&gt;a clear responsibility&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Atomic Design is not your architecture.&lt;br&gt;
And that’s exactly why it works so well.&lt;/p&gt;

&lt;p&gt;Used as a UI composition pattern, it is an excellent tool.&lt;br&gt;
Used as an application architecture, it becomes a source of complexity.&lt;/p&gt;

&lt;p&gt;In the next article of this series, we’ll dive into a &lt;strong&gt;feature-driven architecture&lt;/strong&gt;, designed to organize logic, state, and domain at scale.&lt;/p&gt;




&lt;p&gt;Connect on &lt;a href="https://www.linkedin.com/in/josephciullo/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; for more updates and insights..&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>webdev</category>
      <category>architecture</category>
      <category>react</category>
    </item>
    <item>
      <title>Still splitting text with .split(" ")?
Intl.Segmenter is the native way to handle words, sentences, and characters — correctly, across languages.
No regex. No hacks. Just smart, locale-aware segmentation.</title>
      <dc:creator>Giuseppe Ciullo</dc:creator>
      <pubDate>Wed, 12 Nov 2025 09:57:57 +0000</pubDate>
      <link>https://dev.to/josephciullo/still-splitting-text-with-split-intlsegmenter-is-the-native-way-to-handle-words-3ckj</link>
      <guid>https://dev.to/josephciullo/still-splitting-text-with-split-intlsegmenter-is-the-native-way-to-handle-words-3ckj</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/josephciullo" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F560929%2Fbfccfc40-7750-4abe-a28a-48c18d3e5633.jpeg" alt="josephciullo"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/josephciullo/stop-splitting-strings-the-wrong-way-discover-intlsegmenter-4667" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Stop Splitting Strings the Wrong Way: Discover Intl.Segmenter&lt;/h2&gt;
      &lt;h3&gt;Giuseppe Ciullo ・ Nov 11&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#programming&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#tutorial&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Stop Splitting Strings the Wrong Way: Discover Intl.Segmenter</title>
      <dc:creator>Giuseppe Ciullo</dc:creator>
      <pubDate>Tue, 11 Nov 2025 11:44:20 +0000</pubDate>
      <link>https://dev.to/josephciullo/stop-splitting-strings-the-wrong-way-discover-intlsegmenter-4667</link>
      <guid>https://dev.to/josephciullo/stop-splitting-strings-the-wrong-way-discover-intlsegmenter-4667</guid>
      <description>&lt;p&gt;How many times have you done this?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;I love pizza and pasta&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ["I", "love", "pizza", "and", "pasta"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks fine — until you deal with punctuation, multiple spaces, or languages that don’t even &lt;em&gt;use&lt;/em&gt; spaces.&lt;br&gt;
Try splitting a French sentence with apostrophes, or a Japanese one with no whitespace at all.&lt;br&gt;
Suddenly &lt;code&gt;.split(" ")&lt;/code&gt; feels more like a guess than a rule.&lt;/p&gt;

&lt;p&gt;That’s where &lt;strong&gt;&lt;code&gt;Intl.Segmenter&lt;/code&gt;&lt;/strong&gt; comes in.&lt;/p&gt;


&lt;h2&gt;
  
  
  What Is &lt;code&gt;Intl.Segmenter&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Intl.Segmenter&lt;/code&gt; is part of the JavaScript Internationalization API.&lt;br&gt;
It splits text into &lt;strong&gt;human-perceived units&lt;/strong&gt; — words, sentences, or characters — using the rules of a specific language.&lt;/p&gt;

&lt;p&gt;In other words, it doesn’t just separate symbols.&lt;br&gt;
It understands &lt;strong&gt;how people actually read and write&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Understanding Granularity
&lt;/h2&gt;

&lt;p&gt;The secret sauce of &lt;code&gt;Intl.Segmenter&lt;/code&gt; lies in its &lt;strong&gt;granularity&lt;/strong&gt; — the level at which text is broken down.&lt;br&gt;
You can choose between three modes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;grapheme&lt;/code&gt;&lt;/strong&gt; → splits text into visible characters (user-perceived symbols)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;word&lt;/code&gt;&lt;/strong&gt; → splits into words, respecting language-specific rules&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;sentence&lt;/code&gt;&lt;/strong&gt; → splits into sentences, automatically detecting punctuation and spacing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each level serves a different purpose:&lt;br&gt;
use &lt;em&gt;graphemes&lt;/em&gt; for counting characters, &lt;em&gt;words&lt;/em&gt; for tokenization, and &lt;em&gt;sentences&lt;/em&gt; for text analysis.&lt;/p&gt;

&lt;p&gt;Here’s the beauty: &lt;strong&gt;the same phrase can be segmented differently depending on the locale&lt;/strong&gt;.&lt;/p&gt;


&lt;h2&gt;
  
  
  Example: One Sentence, Three Languages
&lt;/h2&gt;

&lt;p&gt;Let’s see how &lt;code&gt;Intl.Segmenter&lt;/code&gt; handles the same idea across English, French, and Japanese.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sentences&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;en&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;I love sushi.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;fr&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;J’aime les sushis.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;ja&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;私は寿司が好きです。&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;entries&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;sentences&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;segmenter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Segmenter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;granularity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;word&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;segmenter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;segment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isWordLike&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;segment&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`(&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; words)`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;en [ 'I', 'love', 'sushi' ] (3 words)
fr [ 'J’aime', 'les', 'sushis' ] (3 words)
ja [ '私', 'は', '寿司', 'が', '好き', 'です' ] (6 words)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same sentence.&lt;br&gt;
Different segmentation — perfectly adapted to each language’s rules.&lt;/p&gt;


&lt;h2&gt;
  
  
  Example: Word Segmentation (English)
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pizza, pasta and ice cream!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;segmenter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Segmenter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;granularity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;word&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;segmenter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;segment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isWordLike&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;segment&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;words&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ["Pizza", "pasta", "and", "ice", "cream"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Each element is not just a string — it’s a full object with metadata:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;segment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pizza&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;index&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pizza, pasta and ice cream!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;isWordLike&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Example: Grapheme Segmentation
&lt;/h2&gt;

&lt;p&gt;Need to count or slice user-visible characters correctly?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Café résumé&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;graphemeSegmenter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Segmenter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;granularity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;grapheme&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;graphemes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;graphemeSegmenter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;segment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;segment&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;graphemes&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// ["C", "a", "f", "é", " ", "r", "é", "s", "u", "m", "é"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each accented character counts as &lt;em&gt;one&lt;/em&gt;, not two code units.&lt;br&gt;
Perfect for counters, highlighting, or text selection logic.&lt;/p&gt;


&lt;h2&gt;
  
  
  Example: Sentence Segmentation
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;paragraph&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;I love pizza. Pasta is great too! Let's eat.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sentenceSegmenter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Segmenter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;granularity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sentence&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;segment&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;sentenceSegmenter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;segment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;paragraph&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;segment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;segment&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I love pizza.
Pasta is great too!
Let's eat.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Automatically handles punctuation and spacing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Example: Real-world Use — Word Counter
&lt;/h2&gt;

&lt;p&gt;You can build a &lt;strong&gt;word counter&lt;/strong&gt; that works in any language:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;countWords&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;segmenter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Segmenter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;granularity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;word&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[...&lt;/span&gt;&lt;span class="nx"&gt;segmenter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;segment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)].&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;isWordLike&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;countWords&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pizza, pasta and ice cream!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// 5&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;countWords&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;J’aime le chocolat et le café.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// 6&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;countWords&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;私は寿司が好きです。&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// 6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No regex, no guesswork — fully locale-aware.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Splitting text isn’t just a technical task — it’s a linguistic one.&lt;br&gt;
&lt;code&gt;Intl.Segmenter&lt;/code&gt; gives JavaScript the power to understand &lt;strong&gt;words, sentences, and meaning&lt;/strong&gt;, not just characters.&lt;/p&gt;

&lt;p&gt;No regex. No libraries. No fragile logic.&lt;/p&gt;

&lt;p&gt;To explore more, visit the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Segmenter" rel="noopener noreferrer"&gt;official MDN Web Docs&lt;/a&gt;.&lt;br&gt;
And connect on &lt;a href="https://www.linkedin.com/in/josephciullo/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; for more updates and insights.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>programming</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Giuseppe Ciullo</dc:creator>
      <pubDate>Tue, 30 Sep 2025 09:22:08 +0000</pubDate>
      <link>https://dev.to/josephciullo/-4839</link>
      <guid>https://dev.to/josephciullo/-4839</guid>
      <description>&lt;div class="ltag__link"&gt;
  &lt;a href="/josephciullo" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__pic"&gt;
      &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F560929%2Fbfccfc40-7750-4abe-a28a-48c18d3e5633.jpeg" alt="josephciullo"&gt;
    &lt;/div&gt;
  &lt;/a&gt;
  &lt;a href="https://dev.to/josephciullo/your-join-is-lying-to-you-meet-intllistformat-53fb" class="ltag__link__link"&gt;
    &lt;div class="ltag__link__content"&gt;
      &lt;h2&gt;Your .join(", ") Is Lying to You: Meet Intl.ListFormat&lt;/h2&gt;
      &lt;h3&gt;Giuseppe Ciullo ・ Sep 29&lt;/h3&gt;
      &lt;div class="ltag__link__taglist"&gt;
        &lt;span class="ltag__link__tag"&gt;#javascript&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#frontend&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#programming&lt;/span&gt;
        &lt;span class="ltag__link__tag"&gt;#webdev&lt;/span&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/a&gt;
&lt;/div&gt;


</description>
      <category>javascript</category>
      <category>frontend</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Your .join(", ") Is Lying to You: Meet Intl.ListFormat</title>
      <dc:creator>Giuseppe Ciullo</dc:creator>
      <pubDate>Mon, 29 Sep 2025 07:15:17 +0000</pubDate>
      <link>https://dev.to/josephciullo/your-join-is-lying-to-you-meet-intllistformat-53fb</link>
      <guid>https://dev.to/josephciullo/your-join-is-lying-to-you-meet-intllistformat-53fb</guid>
      <description>&lt;p&gt;How many times have you done this as a front-end developer?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pizza&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pasta&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ice Cream&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// "Pizza, Pasta, Ice Cream"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Looks fine… until you realize something’s wrong: the final &lt;strong&gt;“and”&lt;/strong&gt; is missing.&lt;/p&gt;

&lt;p&gt;So you patch it with &lt;code&gt;slice&lt;/code&gt;, &lt;code&gt;map&lt;/code&gt;, conditionals, maybe even a helper function that grows messier with every project.&lt;/p&gt;

&lt;p&gt;But here’s the thing: you shouldn’t be solving this problem at all. There’s already a native API designed for this: &lt;strong&gt;Intl.ListFormat&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What Is &lt;code&gt;Intl.ListFormat&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Intl.ListFormat&lt;/code&gt; is part of the Internationalization API. Its job is simple: turn an array into a human-friendly string that respects language and cultural conventions.&lt;/p&gt;

&lt;p&gt;No custom utilities, no edge cases, no spaghetti code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Styles and Types: Beyond &lt;code&gt;.join()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Unlike &lt;code&gt;.join()&lt;/code&gt;, &lt;code&gt;Intl.ListFormat&lt;/code&gt; gives you &lt;strong&gt;control over style, meaning, and locale&lt;/strong&gt;. Even small differences matter: a comma before “and” (Oxford comma), using “&amp;amp;” instead of “and”, or changing “and” to “or”.&lt;/p&gt;




&lt;h2&gt;
  
  
  Punctuation Matters: Automatic Commas and Localization
&lt;/h2&gt;

&lt;p&gt;One of the benefits of &lt;code&gt;Intl.ListFormat&lt;/code&gt; is automatic &lt;strong&gt;punctuation&lt;/strong&gt;  according to the locale. Small details like commas before “and” (the Oxford comma in American English) or the absence of it in British English are not something you have to implement manually anymore.&lt;/p&gt;

&lt;p&gt;For example, in &lt;code&gt;en-US&lt;/code&gt;, the list &lt;code&gt;"Pizza, Pasta, and Ice Cream"&lt;/code&gt; includes the Oxford comma, making it clear and unambiguous. In &lt;code&gt;en-GB&lt;/code&gt;, the same list becomes &lt;code&gt;"Pizza, Pasta and Ice Cream"&lt;/code&gt;, dropping the extra comma as per British conventions.&lt;/p&gt;

&lt;p&gt;Even when you use types like &lt;code&gt;unit&lt;/code&gt; or &lt;code&gt;disjunction&lt;/code&gt;, &lt;code&gt;Intl.ListFormat&lt;/code&gt; automatically inserts commas where needed and uses the appropriate conjunction (or none, if the type doesn’t require one). This &lt;strong&gt;removes a whole class of small localization bugs&lt;/strong&gt; that would otherwise require custom logic.&lt;/p&gt;

&lt;p&gt;In short, &lt;code&gt;Intl.ListFormat&lt;/code&gt; not only formats the words in a list but also &lt;strong&gt;ensures your punctuation matches the expectations of your users’ language&lt;/strong&gt;, making your app feel more polished and professional.&lt;/p&gt;




&lt;h2&gt;
  
  
  Examples
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;foods&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pizza&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Pasta&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Ice Cream&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// Long + conjunction (default, en-US)&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ListFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;long&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;conjunction&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;foods&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// "Pizza, Pasta, and Ice Cream"&lt;/span&gt;
&lt;span class="c1"&gt;// Oxford comma before 'and'&lt;/span&gt;

&lt;span class="c1"&gt;// Long + conjunction (en-GB)&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ListFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en-GB&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;long&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;conjunction&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;foods&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// "Pizza, Pasta and Ice Cream"&lt;/span&gt;
&lt;span class="c1"&gt;// No Oxford comma in British English&lt;/span&gt;

&lt;span class="c1"&gt;// Short + conjunction&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ListFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;short&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;conjunction&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;foods&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// "Pizza, Pasta, &amp;amp; Ice Cream"&lt;/span&gt;
&lt;span class="c1"&gt;// Compact style, using "&amp;amp;"&lt;/span&gt;

&lt;span class="c1"&gt;// Long + disjunction&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ListFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;long&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;disjunction&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;foods&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// "Pizza, Pasta, or Ice Cream"&lt;/span&gt;
&lt;span class="c1"&gt;// Shows "or" instead of "and"&lt;/span&gt;

&lt;span class="c1"&gt;// Unit style (no conjunction, items treated as a unit)&lt;/span&gt;
&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;ListFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;unit&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; 
&lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;foods&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// "Pizza, Pasta, Ice Cream"&lt;/span&gt;
&lt;span class="c1"&gt;// Simple comma-separated listing&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how small changes in &lt;strong&gt;locale, style, or type&lt;/strong&gt; completely affect the output. These are the details that make lists readable, natural, and culturally correct.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real-World Use Cases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;E-commerce → “Available in pizza, pasta, &amp;amp; ice cream.”&lt;/li&gt;
&lt;li&gt;Social apps → “Liked by Anna, John, &amp;amp; 3 others.”&lt;/li&gt;
&lt;li&gt;Dynamic lists → When you don’t know in advance how many items will show up.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In all these cases, &lt;code&gt;.join()&lt;/code&gt; falls short. &lt;code&gt;Intl.ListFormat&lt;/code&gt; handles these tiny but important differences for you.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Every time you render a list, you’re not just outputting text — &lt;strong&gt;you’re communicating&lt;/strong&gt;.&lt;br&gt;
And communication lives in details: a comma in the right place, the correct “and” or “or”, a style that feels natural to the user’s language.&lt;/p&gt;

&lt;p&gt;Those details are what make your app feel &lt;strong&gt;professional&lt;/strong&gt; instead of &lt;strong&gt;hacked together&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;To dive deeper into &lt;code&gt;Intl.ListFormat&lt;/code&gt; and explore additional features, visit the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat" rel="noopener noreferrer"&gt;official MDN Web Docs&lt;/a&gt;. There, you'll find comprehensive documentation and practical examples to help you master this powerful API.&lt;/p&gt;




&lt;p&gt;Connect on &lt;a href="https://www.linkedin.com/in/josephciullo/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt; for more updates and insights.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>frontend</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Simplify Currency Formatting in React: A Zero-Dependency Solution with Intl API</title>
      <dc:creator>Giuseppe Ciullo</dc:creator>
      <pubDate>Tue, 25 Feb 2025 09:56:58 +0000</pubDate>
      <link>https://dev.to/josephciullo/simplify-currency-formatting-in-react-a-zero-dependency-solution-with-intl-api-3kok</link>
      <guid>https://dev.to/josephciullo/simplify-currency-formatting-in-react-a-zero-dependency-solution-with-intl-api-3kok</guid>
      <description>&lt;p&gt;Currency formatting is a crucial aspect of many web applications, especially in e-commerce or financial dashboards. A clear and intuitive interface helps users quickly understand costs, avoiding ambiguities due to differences in currency or numerical formats. Let's see how to create a React component to display monetary amounts using &lt;code&gt;Intl.NumberFormat&lt;/code&gt;, avoiding external dependencies and keeping the code lightweight and performant.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is &lt;code&gt;Intl.NumberFormat&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;Intl.NumberFormat&lt;/code&gt; API is the native method for formatting numbers based on user localization. With this API, we can handle currency formatting efficiently without relying on additional libraries. Its advantages include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Compatibility with modern browsers without the need for external libraries&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support for multiple currencies and formatting styles&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reduced bundle size, improving performance and reducing application load times.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How &lt;code&gt;Intl.NumberFormat&lt;/code&gt; Works
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;Intl.NumberFormat&lt;/code&gt; API works by taking a locale and an optional set of formatting options to produce a localized string representation of a number. When instantiated, it creates a formatter that applies the specified rules, such as currency, percentage, or decimal formatting. Under the hood, it leverages the JavaScript &lt;code&gt;Intl&lt;/code&gt; (Internationalization) object to ensure proper number formatting based on the selected locale.&lt;/p&gt;

&lt;p&gt;For example, different locales format the same number in distinct ways:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;usdFormatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;NumberFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;currency&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USD&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;eurFormatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;NumberFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;de-DE&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;currency&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;EUR&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;usdFormatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1234.56&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// "$1,234.56"&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;eurFormatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1234.56&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// "1.234,56 €"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By utilizing this approach, applications can seamlessly adapt to various user preferences and regional conventions without requiring external dependencies.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Use &lt;code&gt;Intl.NumberFormat&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Using &lt;code&gt;Intl.NumberFormat&lt;/code&gt; in your application is simple. You initialize a new instance with a locale and a set of options, then call &lt;code&gt;.format(value)&lt;/code&gt; to get the formatted output. The API allows for extensive customization, making it versatile for different use cases.&lt;/p&gt;

&lt;p&gt;Here’s how to format a number as a currency value in US dollars:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;NumberFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;currency&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USD&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1234.56&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// "$1,234.56"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Beyond currency formatting, you can adjust properties like &lt;code&gt;minimumFractionDigits&lt;/code&gt; and &lt;code&gt;maximumFractionDigits&lt;/code&gt; to control decimal precision:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;preciseFormatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;NumberFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;currency&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USD&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;minimumFractionDigits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;maximumFractionDigits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;preciseFormatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;1234.5&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// "$1,234.500"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For more details and advanced usage, refer to the official &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat" rel="noopener noreferrer"&gt;MDN documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the &lt;code&gt;CurrencyFormatter&lt;/code&gt; Component
&lt;/h2&gt;

&lt;p&gt;Let’s create a simple React component that leverages &lt;code&gt;Intl.NumberFormat&lt;/code&gt; to format monetary values according to the selected currency and locale.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CurrencyFormatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currency&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USD&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formattedValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;NumberFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;currency&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;formattedValue&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;CurrencyFormatter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using the Component
&lt;/h3&gt;

&lt;p&gt;After creating our &lt;code&gt;CurrencyFormatter&lt;/code&gt; component, we can easily use it within a React application. This allows us to display monetary amounts clearly and professionally without writing redundant code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;CurrencyFormatter&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./CurrencyFormatter&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Price:&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;strong&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;CurrencyFormatter&lt;/span&gt; &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="mf"&gt;1999.99&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="na"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"EUR"&lt;/span&gt; &lt;span class="na"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"it-IT"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Additional Customizations
&lt;/h2&gt;

&lt;p&gt;If we &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat" rel="noopener noreferrer"&gt;&lt;/a&gt;need more control over the formatting, we can add optional parameters such as the minimum and maximum number of decimal digits. This allows us to adapt the display to different contexts where the component will be used.&lt;/p&gt;

&lt;p&gt;With this customization, we ensure that monetary values are displayed with the desired level of precision, enhancing the user experience and usability of the application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;CurrencyFormatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;currency&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;USD&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;minimumFractionDigits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;maximumFractionDigits&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formattedValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;NumberFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;currency&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;currency&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;minimumFractionDigits&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;maximumFractionDigits&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;formattedValue&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Using &lt;code&gt;Intl.NumberFormat&lt;/code&gt; to format currencies is an efficient, high-performance, and dependency-free solution. This approach allows us to ensure the correct display of currencies based on user localization without adding unnecessary weight to our project.&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>frontend</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Crush Date and Time Formatting Natively: Unleash the Hidden Power of Intl.DateTimeFormat</title>
      <dc:creator>Giuseppe Ciullo</dc:creator>
      <pubDate>Fri, 10 Jan 2025 10:32:03 +0000</pubDate>
      <link>https://dev.to/josephciullo/crush-date-and-time-formatting-natively-unleash-the-hidden-power-of-intldatetimeformat-4b2g</link>
      <guid>https://dev.to/josephciullo/crush-date-and-time-formatting-natively-unleash-the-hidden-power-of-intldatetimeformat-4b2g</guid>
      <description>&lt;h2&gt;
  
  
  Introduction to Native &lt;code&gt;Intl&lt;/code&gt; APIs
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;Intl&lt;/code&gt; APIs in JavaScript are a powerful and native solution for handling localization and formatting of data such as dates and numbers in various languages. Unlike many third-party libraries, these APIs offer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;High performance&lt;/strong&gt;: Integrated into the JavaScript engine.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Smaller bundle sizes&lt;/strong&gt;: Eliminates the need for external dependencies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Global support&lt;/strong&gt;: Includes localization for a wide range of languages and regions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Unlike external libraries, native APIs do not require updates or maintenance by the developer. Additionally, they are optimized for the underlying JavaScript engine, providing a lighter and faster approach to localization and formatting.&lt;/p&gt;

&lt;p&gt;In this article, we will focus on &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt;, an API dedicated to formatting dates and times based on the desired localization. We will see how this API can replace popular libraries such as Moment.js, date-fns, or Day.js for formatting needs, offering a modern and native alternative.&lt;/p&gt;




&lt;h2&gt;
  
  
  Description of &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; is a class that allows for localized formatting of dates and times. It provides advanced features such as support for different localizations, customizable formats, and handling of alternative calendars and time zones.&lt;/p&gt;




&lt;h2&gt;
  
  
  Creating a Formatter
&lt;/h2&gt;

&lt;p&gt;A formatter is an instance of &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; that stores a specific configuration for date formatting. By using a formatter, you can repeatedly apply the same format to different dates, making your code more efficient and readable.&lt;/p&gt;

&lt;p&gt;To create a formatter, use the &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; constructor with the desired parameters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;locale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;locale&lt;/code&gt;&lt;/strong&gt;: A string defining the localization (e.g., "en-US" for American English, "it-IT" for Italian).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;options&lt;/code&gt;&lt;/strong&gt;: An optional object to specify date components (e.g., &lt;code&gt;weekday&lt;/code&gt;, &lt;code&gt;month&lt;/code&gt;, &lt;code&gt;year&lt;/code&gt;, etc.).&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While it is common to save the formatter instance in a variable for reuse, this step is not strictly required. The &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; constructor can be invoked directly to format dates inline, as shown below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;month&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;long&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;day&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;span class="c1"&gt;// Output: "December 19, 2024"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, creating a formatter instance becomes particularly useful when the same format needs to be applied to multiple dates, improving code consistency and avoiding redundancy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;month&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;long&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;day&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt; &lt;span class="c1"&gt;// Output: "December 19, 2024"&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2023&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt; &lt;span class="c1"&gt;// Output: "June 15, 2023"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Basic Examples: Getting Started with &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Explore the simplicity and power of &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; with these foundational examples. We'll demonstrate how to create a formatter for default and custom formats that can be reused across your application.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Default Formatting&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;If no options are provided, the formatter uses the default format of the selected locale.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// Output: "12/19/2024"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. &lt;strong&gt;Custom Formatting&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Customize the output by specifying the desired options.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;weekday&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;long&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;month&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;long&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;day&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// Output: "Thursday, December 19, 2024"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Advanced Examples: Unlocking the Full Potential of &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Take your date and time formatting to the next level with advanced scenarios, such as handling multiple localizations, alternative calendars, and time zones. These examples showcase the versatility and adaptability of &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; in complex applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;strong&gt;Formatting with Alternative Calendars&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;islamicFormatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ar-SA-u-ca-islamic&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;islamicFormatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt; &lt;span class="c1"&gt;// Output: Date in the Islamic calendar&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. &lt;strong&gt;Handling Time Zones&lt;/strong&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;UTC&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// Ensure the date is set in UTC&lt;/span&gt;

&lt;span class="c1"&gt;// Formatter for UTC&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;utcFormatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;timeZone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;UTC&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;month&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;short&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;day&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2-digit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;hour&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2-digit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;minute&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2-digit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;timeZoneName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;short&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;utcFormatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; 
&lt;span class="c1"&gt;// Output: "Dec 19, 2024, 03:30 PM UTC"&lt;/span&gt;

&lt;span class="c1"&gt;// Formatter for Tokyo time zone&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tokyoFormatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ja-JP&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;timeZone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Asia/Tokyo&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;month&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;short&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;day&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2-digit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;hour&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2-digit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;minute&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2-digit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;timeZoneName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;short&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;tokyoFormatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; 
&lt;span class="c1"&gt;// Output: "2024/12/20 00:30 JST"&lt;/span&gt;

&lt;span class="c1"&gt;// Formatter for Berlin time zone&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;berlinFormatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;de-DE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;timeZone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Europe/Berlin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;month&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;short&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;day&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2-digit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;hour&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2-digit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;minute&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2-digit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;timeZoneName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;short&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;berlinFormatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; 
&lt;span class="c1"&gt;// Output: "19. Dez. 2024, 16:30 MEZ"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  TypeScript and &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Using &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; with TypeScript ensures type safety and better development experience. The TypeScript definitions for &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; are built-in, providing autocomplete and documentation for its methods and properties.&lt;/p&gt;

&lt;p&gt;Here's an example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formatter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DateTimeFormat&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;month&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;long&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;day&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formattedDate&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;formatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formattedDate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Output: "December 19, 2024"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The strict typing helps avoid runtime errors by catching potential issues at compile time, such as incorrect options or method calls.&lt;/p&gt;




&lt;h2&gt;
  
  
  Comparison with Popular Libraries
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why Consider &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt;?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Lightweight&lt;/strong&gt;: It is native and does not require external libraries, reducing bundle size.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Performance&lt;/strong&gt;: Often faster than solutions based on libraries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Built-in Localization&lt;/strong&gt;: Natively supports various languages and calendars.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Example: Simple Formatting
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;With &lt;code&gt;Moment.js&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;moment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;moment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;moment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2024-12-19&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dddd, MMMM Do YYYY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;With &lt;code&gt;date-fns&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;format&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;date-fns&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;EEEE, MMMM do yyyy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;With &lt;code&gt;Day.js&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;dayjs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dayjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;dayjs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2024-12-19&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dddd, MMMM D, YYYY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;With &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;formatter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Intl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DateTimeFormat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en-US&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;weekday&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;long&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;month&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;long&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;day&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;formatter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;19&lt;/span&gt;&lt;span class="p"&gt;)));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While external libraries might offer syntactic sugar, the native API provides equivalent functionality without sacrificing flexibility or efficiency.The slightly longer syntax of the native API is a small trade-off for its benefits in maintainability, performance, and simplicity.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; provides a robust, native solution for date and time formatting, making it an excellent alternative to popular libraries like Moment.js, date-fns, and Day.js. With its high performance, built-in localization, and simplified maintenance, it's a valuable tool for modern JavaScript applications.&lt;/p&gt;

&lt;p&gt;To dive deeper into &lt;code&gt;Intl.DateTimeFormat&lt;/code&gt; and explore additional features, visit the official &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat" rel="noopener noreferrer"&gt;MDN Web Docs&lt;/a&gt;. There, you'll find comprehensive documentation and practical examples to help you master this powerful API.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Supercharge Your Web Animations: Optimize requestAnimationFrame Like a Pro</title>
      <dc:creator>Giuseppe Ciullo</dc:creator>
      <pubDate>Thu, 26 Sep 2024 14:05:10 +0000</pubDate>
      <link>https://dev.to/josephciullo/supercharge-your-web-animations-optimize-requestanimationframe-like-a-pro-22i5</link>
      <guid>https://dev.to/josephciullo/supercharge-your-web-animations-optimize-requestanimationframe-like-a-pro-22i5</guid>
      <description>&lt;p&gt;Smooth and performant animations are essential in modern web applications. However, managing them improperly can overload the browser’s main thread, causing poor performance and janky animations. &lt;code&gt;requestAnimationFrame&lt;/code&gt; (rAF) is a browser API designed to sync animations with the display's refresh rate, ensuring smoother motion compared to alternatives like &lt;code&gt;setTimeout&lt;/code&gt;. But using rAF efficiently requires careful planning, especially when handling multiple animations.&lt;/p&gt;

&lt;p&gt;In this article, we will explore how to optimize &lt;code&gt;requestAnimationFrame&lt;/code&gt; by centralizing animation management, introducing FPS control, and keeping the browser’s main thread responsive.&lt;/p&gt;




&lt;h3&gt;
  
  
  Understanding FPS and Why It Matters
&lt;/h3&gt;

&lt;p&gt;Frames per second (FPS) is crucial when discussing animation performance. Most screens refresh at 60 FPS, meaning that &lt;code&gt;requestAnimationFrame&lt;/code&gt; is called 60 times per second. To maintain smooth animations, the browser must complete its work within about 16.67 milliseconds per frame.&lt;/p&gt;

&lt;p&gt;If too many tasks run during a single frame, the browser might miss its target frame time, causing stuttering or dropped frames. Lowering the FPS for certain animations can help reduce the load on the main thread, providing a balance between performance and smoothness.&lt;/p&gt;

&lt;h3&gt;
  
  
  Centralized Animation Manager with FPS Control for Better Performance
&lt;/h3&gt;

&lt;p&gt;To manage animations more efficiently, we can centralize their handling with a shared loop rather than having multiple &lt;code&gt;requestAnimationFrame&lt;/code&gt; calls scattered throughout the code. A centralized approach minimizes redundant calls and makes it easier to add FPS control.&lt;/p&gt;

&lt;p&gt;The following &lt;code&gt;AnimationManager&lt;/code&gt; class allows us to register and unregister animation tasks while controlling the target FPS. By default, we aim for 60 FPS, but this can be adjusted for performance needs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AnimationManager&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Set&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;FrameRequestCallback&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;fps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Target FPS&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;lastFrameTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;animationId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Store the animation frame ID&lt;/span&gt;

  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentTime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;deltaTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;currentTime&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastFrameTime&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Ensure the tasks only run if enough time has passed to meet the target FPS&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;deltaTime&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fps&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;task&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;currentTime&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastFrameTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;currentTime&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;animationId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;requestAnimationFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;};&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;registerTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FrameRequestCallback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;animationId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;requestAnimationFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Start the loop if this is the first task&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;unregisterTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FrameRequestCallback&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;delete&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;task&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;animationId&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nf"&gt;cancelAnimationFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;animationId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Stop the loop if no tasks remain&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;animationId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Reset the ID&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;animationManager&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;AnimationManager&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this setup, we calculate the &lt;code&gt;deltaTime&lt;/code&gt; between frames to determine if enough time has passed for the next update based on the target FPS. This allows us to throttle the frequency of updates to ensure the browser’s main thread isn’t overloaded.&lt;/p&gt;




&lt;h3&gt;
  
  
  Practical Example: Animating Multiple Elements with Different Properties
&lt;/h3&gt;

&lt;p&gt;Let’s create an example where we animate three boxes, each with a different animation: one scales, another changes color, and the third rotates.&lt;/p&gt;

&lt;p&gt;Here’s the HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"animate-box-1"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"animated-box"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"animate-box-2"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"animated-box"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"animate-box-3"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"animated-box"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here’s the CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.animated-box&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#3498db&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nl"&gt;transition&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;transform&lt;/span&gt; &lt;span class="m"&gt;0.1s&lt;/span&gt; &lt;span class="n"&gt;ease&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we’ll add JavaScript to animate each box with a different property. One will scale, another will change its color, and the third will rotate.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Adding Linear Interpolation (lerp)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Linear interpolation (lerp) is a common technique used in animations to smoothly transition between two values. It helps create a gradual and smooth progression, making it ideal for scaling, moving, or changing properties over time. The function takes three parameters: a starting value, an ending value, and a normalized time (t), which determines how far along the transition is.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;lerp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Scaling Animation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We start by creating a function to animate the scaling of the first box:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;animateScale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;scaleBox&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HTMLDivElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;startScale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;endScale&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;scaleT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;scaleT&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scaleT&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;scaleT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentScale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;lerp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;startScale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;endScale&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;scaleT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;scaleBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transform&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`scale(&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;currentScale&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scaleT&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;animationManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unregisterTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;animationManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scale&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3: Color Animation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next, we animate the color change of the second box:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;animateColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;colorBox&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HTMLDivElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;startColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;endColor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;colorT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;color&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;colorT&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;colorT&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;colorT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;floor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;lerp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;startColor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;endColor&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;colorT&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
    &lt;span class="nx"&gt;colorBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;backgroundColor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`rgb(&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;currentColor&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, 100, 100)`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;colorT&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;animationManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unregisterTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;animationManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;color&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4: Rotation Animation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally, we create the function to rotate the third box:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;animateRotation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;rotateBox&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HTMLDivElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;startRotation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;endRotation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;rotationT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;rotationT&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="nx"&gt;speed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Increment progress&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rotationT&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;rotationT&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;currentRotation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;lerp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;startRotation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;endRotation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;rotationT&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="nx"&gt;rotateBox&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transform&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`rotate(&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;currentRotation&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;deg)`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="c1"&gt;// Unregister task once the animation completes&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rotationT&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;animationManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unregisterTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;animationManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;registerTask&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 5: Starting the Animations&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Finally, we can start the animations for all three boxes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Selecting the elements&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scaleBox&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#animate-box-1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;HTMLDivElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;colorBox&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#animate-box-2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;HTMLDivElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rotateBox&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;#animate-box-3&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;HTMLDivElement&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Starting the animations&lt;/span&gt;
&lt;span class="nf"&gt;animateScale&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;scaleBox&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;1.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.02&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Scaling animation&lt;/span&gt;
&lt;span class="nf"&gt;animateColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;colorBox&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.01&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Color change animation&lt;/span&gt;
&lt;span class="nf"&gt;animateRotation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;rotateBox&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;360&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.005&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Rotation animation&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Note on the Main Thread
&lt;/h3&gt;

&lt;p&gt;When using &lt;code&gt;requestAnimationFrame&lt;/code&gt;, it’s essential to keep in mind that animations run on the browser’s main thread. Overloading the main thread with too many tasks can cause the browser to miss animation frames, resulting in stuttering. This is why optimizing your animations with tools like a centralized animation manager and FPS control can help maintain smoothness, even with multiple animations.&lt;/p&gt;




&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Managing animations efficiently in JavaScript requires more than just using &lt;code&gt;requestAnimationFrame&lt;/code&gt;. By centralizing animations and controlling the FPS, you can ensure smoother, more performant animations while keeping the main thread responsive. In this example, we showed how to handle multiple animations with a single &lt;code&gt;AnimationManager&lt;/code&gt;, demonstrating how to optimize for both performance and usability. While we focused on maintaining a consistent FPS for simplicity, this approach can be expanded to handle different FPS values for various animations, though that was beyond the scope of this article.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Github Repo:&lt;/strong&gt; &lt;a href="https://github.com/JBassx/rAF-optimization" rel="noopener noreferrer"&gt;https://github.com/JBassx/rAF-optimization&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;StackBlitz:&lt;/strong&gt; &lt;a href="https://www.stackblitz.com/%7E/github.com/JBassx/rAF-optimization" rel="noopener noreferrer"&gt;https://www.stackblitz.com/~/github.com/JBassx/rAF-optimization&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LinkedIn:&lt;/strong&gt; &lt;a href="https://www.linkedin.com/in/josephciullo/" rel="noopener noreferrer"&gt;https://www.linkedin.com/in/josephciullo/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>typescript</category>
    </item>
  </channel>
</rss>
