<?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: Vishal Singh</title>
    <description>The latest articles on DEV Community by Vishal Singh (@vishal_singh_0610).</description>
    <link>https://dev.to/vishal_singh_0610</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%2F4022537%2F35f46679-58b2-4d87-9d1c-c62efd848869.png</url>
      <title>DEV Community: Vishal Singh</title>
      <link>https://dev.to/vishal_singh_0610</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vishal_singh_0610"/>
    <language>en</language>
    <item>
      <title>JavaScript Temporal Reached Stage 4: A Practical Migration Guide Beyond Date</title>
      <dc:creator>Vishal Singh</dc:creator>
      <pubDate>Mon, 10 Aug 2026 06:45:55 +0000</pubDate>
      <link>https://dev.to/vishal_singh_0610/javascript-temporal-reached-stage-4-a-practical-migration-guide-beyond-date-4bjp</link>
      <guid>https://dev.to/vishal_singh_0610/javascript-temporal-reached-stage-4-a-practical-migration-guide-beyond-date-4bjp</guid>
      <description>&lt;p&gt;JavaScript's Date object has carried the web for decades, but almost every experienced developer has a story about it: an off-by-one-day bug, a daylight-saving surprise, a month numbered from zero, or a date-only value that silently became a timestamp.&lt;/p&gt;

&lt;p&gt;In July 2026, the TC39 Temporal proposal reached a Stage 4 draft. That is a major standardisation milestone: the API has completed the proposal process and is ready to become part of the ECMAScript standard.&lt;/p&gt;

&lt;p&gt;But Stage 4 does not mean you can assume every current browser already has Temporal. MDN still marks the API as limited availability. The practical approach is to learn the model now, use feature detection, and add the official polyfill when your support policy requires it.&lt;/p&gt;

&lt;p&gt;This guide explains the mental model, the most useful types, and a safe migration path from Date.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you will learn
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;how Temporal models dates, times, instants, zones, and durations&lt;/li&gt;
&lt;li&gt;which Temporal type fits each common use case&lt;/li&gt;
&lt;li&gt;how to migrate from Date without a risky rewrite&lt;/li&gt;
&lt;li&gt;how to handle current browser support safely&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why Date causes so many bugs
&lt;/h2&gt;

&lt;p&gt;Date tries to represent several different concepts with one mutable object:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;an exact instant on the global timeline&lt;/li&gt;
&lt;li&gt;a calendar date such as a birthday&lt;/li&gt;
&lt;li&gt;a local wall-clock time&lt;/li&gt;
&lt;li&gt;a date and time in a named time zone&lt;/li&gt;
&lt;li&gt;a duration between two values&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those concepts are not interchangeable.&lt;/p&gt;

&lt;p&gt;Consider the string 2026-08-10. It might mean a birthday, a billing date, or midnight in some time zone. Turning it into a Date can introduce a time zone that the original value never had.&lt;/p&gt;

&lt;p&gt;Date also has historical API traps. Months are zero-indexed in the numeric constructor, parsing behaviour has edge cases, and methods can mutate an existing value.&lt;/p&gt;

&lt;p&gt;Temporal solves the modelling problem by using separate immutable types.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Temporal types you should know
&lt;/h2&gt;

&lt;p&gt;You do not need to memorise the whole API. Start by choosing the type that matches the data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Temporal.PlainDate
&lt;/h3&gt;

&lt;p&gt;Use PlainDate for a calendar date with no time and no time zone.&lt;/p&gt;

&lt;p&gt;Good examples include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;birthdays&lt;/li&gt;
&lt;li&gt;public holidays&lt;/li&gt;
&lt;li&gt;invoice due dates&lt;/li&gt;
&lt;li&gt;check-in dates
&lt;/li&gt;
&lt;/ul&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;launchDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Temporal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PlainDate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2026-08-10&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;reviewDate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;launchDate&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="na"&gt;months&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="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;launchDate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// 2026-08-10&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;reviewDate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// 2026-09-10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Temporal values are immutable. add() returns a new value; it does not change launchDate.&lt;/p&gt;

&lt;h3&gt;
  
  
  Temporal.PlainTime
&lt;/h3&gt;

&lt;p&gt;Use PlainTime for a wall-clock time without a date or time zone.&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;openingTime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Temporal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PlainTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;09:30&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;openingTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hour&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 9&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works for a recurring local concept such as "the store opens at 09:30." It does not identify one exact moment globally.&lt;/p&gt;

&lt;h3&gt;
  
  
  Temporal.Instant
&lt;/h3&gt;

&lt;p&gt;Use Instant for an exact point on the timeline.&lt;/p&gt;

&lt;p&gt;This is the closest Temporal equivalent to a Unix timestamp or a Date used as an event timestamp.&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;deployedAt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Temporal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Instant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2026-08-10T06:30:00Z&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;deployedAt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;epochMilliseconds&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instants are useful for logs, database timestamps, audit events, and API data that ends in Z or includes an offset.&lt;/p&gt;

&lt;h3&gt;
  
  
  Temporal.ZonedDateTime
&lt;/h3&gt;

&lt;p&gt;Use ZonedDateTime when the named time zone matters.&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;meeting&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Temporal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ZonedDateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2026-08-10T10:00:00+05:30[Asia/Kolkata]&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;meeting&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;timeZoneId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Asia/Kolkata&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;meeting&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The named zone is important because an offset such as +05:30 and a time zone such as Asia/Kolkata are different kinds of information. Time-zone rules can change, and many regions use daylight saving time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Temporal.Duration
&lt;/h3&gt;

&lt;p&gt;Use Duration for an amount of time.&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;sprint&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Temporal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Duration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;weeks&lt;/span&gt;&lt;span class="p"&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;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;sprint&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt; &lt;span class="c1"&gt;// P2W&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Be careful when converting calendar units into clock units. A day is not always exactly 24 hours in a zone with daylight-saving changes. Temporal makes you provide the context when that context is required.&lt;/p&gt;

&lt;h2&gt;
  
  
  A DST-safe example
&lt;/h2&gt;

&lt;p&gt;Imagine a recurring meeting at 10:00 in New York. Adding one calendar day should keep the meeting at 10:00 local time, even if the UTC offset changes.&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;beforeChange&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Temporal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;ZonedDateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2026-03-07T10:00:00-05:00[America/New_York]&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;nextDay&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;beforeChange&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="na"&gt;days&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="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;nextDay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hour&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 10&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;nextDay&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;offset&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// may change with DST rules&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is exactly why a named time zone is more useful than manually adding 86,400,000 milliseconds.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical migration map
&lt;/h2&gt;

&lt;p&gt;Do not replace every Date in one giant refactor. First classify what each value means.&lt;/p&gt;

&lt;h3&gt;
  
  
  Date-only form values
&lt;/h3&gt;

&lt;p&gt;Old approach:&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;selected&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="nx"&gt;input&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Safer Temporal model:&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;selected&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Temporal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;PlainDate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&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="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An HTML date input returns a date-only string. PlainDate preserves that meaning without introducing midnight or a time zone.&lt;/p&gt;

&lt;h3&gt;
  
  
  API timestamps
&lt;/h3&gt;

&lt;p&gt;If an API returns an exact timestamp:&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;createdAt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Temporal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Instant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;apiResponse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your UI needs a local representation, convert it with an explicit zone:&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;local&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toZonedDateTimeISO&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Asia/Kolkata&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;local&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toLocaleString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Current time
&lt;/h3&gt;

&lt;p&gt;For a timestamp:&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;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Temporal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instant&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the current calendar date in a chosen zone:&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;todayInIndia&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Temporal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plainDateISO&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Asia/Kolkata&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;These two calls answer different questions, which is the point.&lt;/p&gt;

&lt;h3&gt;
  
  
  Calendar arithmetic
&lt;/h3&gt;

&lt;p&gt;Old code often adds milliseconds:&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;tomorrow&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="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a calendar date, write the intent directly:&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;tomorrow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Temporal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plainDateISO&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="na"&gt;days&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Interoperating with existing Date code
&lt;/h2&gt;

&lt;p&gt;Most projects will use Date and Temporal together during migration.&lt;/p&gt;

&lt;p&gt;Convert a Date to an Instant:&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;legacyDate&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;instant&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Temporal&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Instant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;legacyDate&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toISOString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Convert an Instant back to Date:&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;legacyAgain&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="nx"&gt;instant&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;epochMilliseconds&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This boundary is useful when an existing library still expects Date.&lt;/p&gt;

&lt;p&gt;Do not convert a PlainDate to Date unless you decide what time and time zone that calendar date should represent. That decision cannot be inferred safely.&lt;/p&gt;

&lt;h2&gt;
  
  
  Browser support and the polyfill
&lt;/h2&gt;

&lt;p&gt;Before using the global Temporal object, check your runtime support.&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Temporal&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;globalThis&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Native Temporal is available.&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For production code that must work in browsers without native support, use the @js-temporal/polyfill package and follow its current installation documentation.&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Temporal&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;@js-temporal/polyfill&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;A polyfill has bundle-size and compatibility implications, so apply it deliberately. For a small isolated date task, an existing well-tested library may still be the right short-term choice. For new domain modelling, Temporal gives the platform a consistent long-term direction.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common mistakes to avoid
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Using PlainDateTime for a real event
&lt;/h3&gt;

&lt;p&gt;PlainDateTime has a date and clock time but no time zone. "10 August at 10:00" is not one exact global moment until a zone is supplied.&lt;/p&gt;

&lt;p&gt;Use ZonedDateTime or Instant for events that must be coordinated across locations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Storing only a formatted string
&lt;/h3&gt;

&lt;p&gt;A string such as "10 Aug, 11:30 AM" is presentation, not durable data. Store a machine-readable Temporal string or the underlying structured value, then format it for the user.&lt;/p&gt;

&lt;h3&gt;
  
  
  Assuming an offset is a time zone
&lt;/h3&gt;

&lt;p&gt;An offset tells you the relationship to UTC at one moment. A named time zone carries rules for future and historical changes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Comparing objects with normal operators
&lt;/h3&gt;

&lt;p&gt;Temporal objects intentionally avoid ambiguous coercion. Use methods such as Temporal.PlainDate.compare(), equals(), since(), or until().&lt;/p&gt;

&lt;h3&gt;
  
  
  Ignoring availability
&lt;/h3&gt;

&lt;p&gt;Stage 4 is a standards milestone, not proof that all users have upgraded browsers. Test the environments in your support matrix and provide a polyfill or fallback when needed.&lt;/p&gt;

&lt;h2&gt;
  
  
  A simple decision checklist
&lt;/h2&gt;

&lt;p&gt;Before creating a Temporal value, ask:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Is this only a calendar date? Use PlainDate.&lt;/li&gt;
&lt;li&gt;Is this only a clock time? Use PlainTime.&lt;/li&gt;
&lt;li&gt;Is this one exact timestamp? Use Instant.&lt;/li&gt;
&lt;li&gt;Does a named time zone affect the meaning? Use ZonedDateTime.&lt;/li&gt;
&lt;li&gt;Is this an amount of time? Use Duration.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That small modelling decision prevents many bugs before arithmetic or formatting begins.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: clearer intent is the real upgrade
&lt;/h2&gt;

&lt;p&gt;Temporal is valuable not because it has more methods than Date, but because the type tells another developer what the value means.&lt;/p&gt;

&lt;p&gt;A birthday is not a timestamp. A meeting in New York is not just an offset. One calendar day is not always 24 hours.&lt;/p&gt;

&lt;p&gt;Temporal puts those distinctions into the API.&lt;/p&gt;

&lt;p&gt;The safest adoption plan in 2026 is straightforward: classify existing date values, migrate one boundary at a time, use native support when available, and include the polyfill where your browser matrix needs it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://tc39.es/proposal-temporal/" rel="noopener noreferrer"&gt;https://tc39.es/proposal-temporal/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tc39.es/proposal-temporal/docs/" rel="noopener noreferrer"&gt;https://tc39.es/proposal-temporal/docs/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/@js-temporal/polyfill" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/@js-temporal/polyfill&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tags: javascript, webdev, temporal, tutorial&lt;/p&gt;

</description>
      <category>api</category>
      <category>javascript</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Stop Guessing Browser Support: A Practical Guide to Web Platform Baseline in 2026</title>
      <dc:creator>Vishal Singh</dc:creator>
      <pubDate>Mon, 10 Aug 2026 06:09:49 +0000</pubDate>
      <link>https://dev.to/vishal_singh_0610/stop-guessing-browser-support-a-practical-guide-to-web-platform-baseline-in-2026-20bg</link>
      <guid>https://dev.to/vishal_singh_0610/stop-guessing-browser-support-a-practical-guide-to-web-platform-baseline-in-2026-20bg</guid>
      <description>&lt;p&gt;Liquid syntax error: 'raw' tag was never closed&lt;/p&gt;
</description>
      <category>css</category>
      <category>frontend</category>
      <category>web</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Why Lighthouse and Real-User Core Web Vitals Show Different Results</title>
      <dc:creator>Vishal Singh</dc:creator>
      <pubDate>Wed, 22 Jul 2026 08:34:57 +0000</pubDate>
      <link>https://dev.to/vishal_singh_0610/why-lighthouse-and-real-user-core-web-vitals-show-different-results-16jj</link>
      <guid>https://dev.to/vishal_singh_0610/why-lighthouse-and-real-user-core-web-vitals-show-different-results-16jj</guid>
      <description>&lt;p&gt;You run Lighthouse and get a green performance score. Then you open PageSpeed Insights and the Core Web Vitals assessment says your page needs improvement.&lt;/p&gt;

&lt;p&gt;Or the opposite happens: Lighthouse reports a slow page, while real-user data looks healthy.&lt;/p&gt;

&lt;p&gt;Nothing is necessarily broken. The two results answer different questions.&lt;/p&gt;

&lt;p&gt;Lighthouse gives you lab data from one controlled test. Chrome UX Report, usually called CrUX, gives you field data collected from real Chrome users. Understanding that difference can save hours of debugging the wrong problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lab data: a controlled experiment
&lt;/h2&gt;

&lt;p&gt;Lighthouse loads a page using predefined device and network conditions. A typical mobile run applies CPU and network throttling and usually behaves like a new visitor with a cold cache.&lt;/p&gt;

&lt;p&gt;This makes Lighthouse useful because the test can be repeated. You can change your code, run it again, and compare the results under similar conditions.&lt;/p&gt;

&lt;p&gt;Lighthouse is particularly useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;finding render-blocking resources&lt;/li&gt;
&lt;li&gt;identifying large images or JavaScript bundles&lt;/li&gt;
&lt;li&gt;diagnosing main-thread work&lt;/li&gt;
&lt;li&gt;detecting layout shifts during the initial load&lt;/li&gt;
&lt;li&gt;catching performance regressions before deployment&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But a Lighthouse result is still one test from one environment. It is not a survey of every person visiting your website.&lt;/p&gt;

&lt;h2&gt;
  
  
  Field data: what real users experienced
&lt;/h2&gt;

&lt;p&gt;CrUX collects performance measurements from eligible real Chrome users. PageSpeed Insights uses this dataset in its field-data section.&lt;/p&gt;

&lt;p&gt;Instead of testing one simulated device, field data includes a distribution of real visits across different:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;phones and computers&lt;/li&gt;
&lt;li&gt;network speeds&lt;/li&gt;
&lt;li&gt;locations&lt;/li&gt;
&lt;li&gt;cache states&lt;/li&gt;
&lt;li&gt;browsing sessions&lt;/li&gt;
&lt;li&gt;user behaviours&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CrUX generally reports a rolling 28-day view and evaluates Core Web Vitals at the 75th percentile. In simple terms, the reported value is intended to represent an experience that at least 75% of visits met or beat.&lt;/p&gt;

&lt;p&gt;This makes field data the better answer to: “What experience are our users actually getting?”&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the numbers disagree
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. The tested device is not your users' devices
&lt;/h3&gt;

&lt;p&gt;A Lighthouse mobile test simulates a particular level of CPU and network performance. Your visitors may use faster devices, slower devices, or a completely different mix.&lt;/p&gt;

&lt;p&gt;One lab run cannot reproduce that entire distribution.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Lighthouse often tests a cold load
&lt;/h3&gt;

&lt;p&gt;A lab test commonly loads the page without the benefit of previously cached assets. Returning users may already have fonts, scripts and images cached.&lt;/p&gt;

&lt;p&gt;This can make Lighthouse look worse than field data. The reverse can happen when real users face slow networks, overloaded devices or third-party content that did not appear in the lab run.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Real users interact with the page
&lt;/h3&gt;

&lt;p&gt;A default Lighthouse audit focuses heavily on the initial page load. Real visitors scroll, open menus, accept cookie banners, load more content and use interactive components.&lt;/p&gt;

&lt;p&gt;This difference is especially important for CLS and INP.&lt;/p&gt;

&lt;p&gt;A page may have no obvious layout shift during loading but shift later when a lazy-loaded component, advertisement or embedded widget appears. CrUX can capture that real experience even when a basic Lighthouse run does not.&lt;/p&gt;

&lt;p&gt;Similarly, Interaction to Next Paint depends on actual interactions. A load-only test cannot reproduce every slow click, tap or keyboard action your users encounter.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. You may be comparing a URL with an entire origin
&lt;/h3&gt;

&lt;p&gt;PageSpeed Insights shows URL-level field data when enough data is available. When it is not, it may fall back to origin-level data.&lt;/p&gt;

&lt;p&gt;That means you could accidentally compare:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lighthouse data for one specific page&lt;/li&gt;
&lt;li&gt;CrUX data representing many pages across the domain&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Always check whether the field section says “This URL” or “Origin” before investigating a mismatch.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Field data is historical; Lighthouse is happening now
&lt;/h3&gt;

&lt;p&gt;Lighthouse tests the current version of the page. CrUX uses a rolling window of recent user experiences.&lt;/p&gt;

&lt;p&gt;After deploying a performance improvement, your Lighthouse result can improve immediately while CrUX changes gradually as new visits replace older data.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. The page is not identical for every visitor
&lt;/h3&gt;

&lt;p&gt;A/B tests, ads, consent banners, personalisation, authentication state and third-party scripts can change what gets loaded.&lt;/p&gt;

&lt;p&gt;Lighthouse may see one version while different groups of users see something else. Even repeated Lighthouse runs can fluctuate when the page or underlying conditions change.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which result should you trust?
&lt;/h2&gt;

&lt;p&gt;Trust field data when judging the experience your real users receive and whether your site meets Core Web Vitals in practice.&lt;/p&gt;

&lt;p&gt;Use Lighthouse to diagnose problems, reproduce controlled scenarios and prevent new regressions.&lt;/p&gt;

&lt;p&gt;It is not field data versus Lighthouse. A useful workflow needs both:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Field data tells you that a real problem exists and how widespread it may be.&lt;/li&gt;
&lt;li&gt;Lab data helps you understand, reproduce and fix specific causes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The overall Lighthouse performance score is also not the same thing as the Core Web Vitals assessment. Compare the individual metrics—LCP, INP and CLS—rather than expecting the two headline results to match.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical debugging workflow
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Read the field-data label
&lt;/h3&gt;

&lt;p&gt;In PageSpeed Insights, confirm whether the CrUX result represents the exact URL or the whole origin.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Compare individual metrics
&lt;/h3&gt;

&lt;p&gt;Identify whether the disagreement is mainly in LCP, INP or CLS. Each metric points toward different causes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Re-run Lighthouse consistently
&lt;/h3&gt;

&lt;p&gt;Use the same test mode, device category and environment. Run it more than once and look for a pattern instead of treating one score as absolute truth.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Investigate what the lab test misses
&lt;/h3&gt;

&lt;p&gt;If field data is worse, examine real user journeys:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;scroll through the full page&lt;/li&gt;
&lt;li&gt;interact with menus and forms&lt;/li&gt;
&lt;li&gt;test consent banners and embedded widgets&lt;/li&gt;
&lt;li&gt;check slower devices and networks&lt;/li&gt;
&lt;li&gt;investigate post-load layout shifts&lt;/li&gt;
&lt;li&gt;collect your own Real User Monitoring data when possible&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The web-vitals JavaScript library can help collect field measurements and attribution information from your own users.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 5: Use Lighthouse diagnostics to fix reproducible causes
&lt;/h3&gt;

&lt;p&gt;If the lab and field metrics point in the same direction, Lighthouse audits can help locate heavy resources, long tasks, delayed content and layout-shift culprits.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Monitor after deployment
&lt;/h3&gt;

&lt;p&gt;Confirm the immediate improvement in a controlled test, then watch field data over time. CrUX will not fully reflect a deployment immediately because its reporting window includes earlier visits.&lt;/p&gt;

&lt;h2&gt;
  
  
  A simple way to remember it
&lt;/h2&gt;

&lt;p&gt;Lighthouse is a crash test performed under controlled conditions.&lt;/p&gt;

&lt;p&gt;CrUX is information collected from cars being driven by real people on real roads.&lt;/p&gt;

&lt;p&gt;The crash test helps engineers find weaknesses. The road data shows what drivers actually experience. You need both to build something reliable.&lt;/p&gt;

&lt;p&gt;The next time Lighthouse and Core Web Vitals disagree, do not ask which tool is wrong. Ask what population, time window, device conditions and user journey each result represents.&lt;/p&gt;

&lt;p&gt;Sources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://web.dev/articles/lab-and-field-data-differences" rel="noopener noreferrer"&gt;https://web.dev/articles/lab-and-field-data-differences&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://web.dev/articles/vitals-tools" rel="noopener noreferrer"&gt;https://web.dev/articles/vitals-tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.chrome.com/docs/lighthouse/performance/performance-scoring" rel="noopener noreferrer"&gt;https://developer.chrome.com/docs/lighthouse/performance/performance-scoring&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://web.dev/articles/optimize-cls" rel="noopener noreferrer"&gt;https://web.dev/articles/optimize-cls&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webperf</category>
      <category>webdev</category>
      <category>lighthouse</category>
      <category>corewebvitals</category>
    </item>
    <item>
      <title>Grok Build Is Now Open Source: What Developers Can Learn from Its Coding-Agent Architecture</title>
      <dc:creator>Vishal Singh</dc:creator>
      <pubDate>Mon, 20 Jul 2026 10:15:56 +0000</pubDate>
      <link>https://dev.to/vishal_singh_0610/grok-build-is-now-open-source-what-developers-can-learn-from-its-coding-agent-architecture-1gko</link>
      <guid>https://dev.to/vishal_singh_0610/grok-build-is-now-open-source-what-developers-can-learn-from-its-coding-agent-architecture-1gko</guid>
      <description>&lt;p&gt;AI coding tools are often discussed as black boxes: you give them a task, they inspect a repository, run commands, edit files, and return a result. Grok Build is now a useful exception.&lt;/p&gt;

&lt;p&gt;SpaceXAI has open-sourced Grok Build, its terminal-based coding agent and full-screen TUI. The public repository exposes the harness behind the product, so developers can inspect how context is assembled, model responses are parsed, tools are dispatched, and long-running work is managed.&lt;/p&gt;

&lt;h2&gt;
  
  
  What has been open-sourced?
&lt;/h2&gt;

&lt;p&gt;The published Rust code includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the agent loop that connects model responses to tool calls&lt;/li&gt;
&lt;li&gt;tools for reading, editing, searching, and running commands&lt;/li&gt;
&lt;li&gt;the terminal UI, including plan review and inline diffs&lt;/li&gt;
&lt;li&gt;the extension system for skills, plugins, hooks, MCP servers, and subagents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This matters because an AI coding agent is more than a model. The surrounding harness decides what context the model sees, which actions it can take, how failures are handled, and how a developer stays in control.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three useful takeaways for developers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Context assembly is a product feature
&lt;/h3&gt;

&lt;p&gt;A coding agent must decide which files, instructions, tool results, and previous decisions belong in the next model request. Better context is not simply more context; it is the right information at the right time.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Tool execution needs a feedback loop
&lt;/h3&gt;

&lt;p&gt;The model can propose an edit or command, but the harness must execute it, capture the result, surface errors, and feed useful evidence back into the next step. Reliability comes from this loop, not from one perfect prompt.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Extensibility should have clear boundaries
&lt;/h3&gt;

&lt;p&gt;Grok Build supports skills, plugins, hooks, MCP servers, subagents, AGENTS.md instructions, and configuration. The architecture is a good reference for anyone building an internal developer agent that must adapt to different repositories and workflows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Can you run it yourself?
&lt;/h2&gt;

&lt;p&gt;The repository contains the Rust source for the Grok CLI/TUI and its agent runtime. You can compile it locally, and the official announcement says it can be pointed at local inference through &lt;code&gt;config.toml&lt;/code&gt;. Prebuilt installers are also available for macOS, Linux, and Windows.&lt;/p&gt;

&lt;p&gt;One important distinction: an open-source agent harness does not automatically make every hosted model or service free. The code, model access, authentication, and usage costs are separate layers, so check the current terms before choosing a setup.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this release is worth studying
&lt;/h2&gt;

&lt;p&gt;Even if you do not plan to switch coding assistants, the repository is valuable as a real-world reference for agent loops, terminal UX, tool dispatch, sandboxing, memory, and extensibility.&lt;/p&gt;

&lt;p&gt;Open-source coding agents make an important question easier to answer: not only "What can the model do?" but also "How does the system decide, act, verify, and recover?"&lt;/p&gt;

&lt;p&gt;Would you explore the Grok Build source to learn from the architecture, contribute your own extension, or run it with local inference?&lt;/p&gt;

&lt;h2&gt;
  
  
  Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://x.ai/news/grok-build-open-source" rel="noopener noreferrer"&gt;Grok Build is now open source&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/xai-org/grok-build" rel="noopener noreferrer"&gt;xai-org/grok-build on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>ai</category>
      <category>opensource</category>
      <category>programming</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
