<?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: Othmane Nemli</title>
    <description>The latest articles on DEV Community by Othmane Nemli (@othmane_nemli).</description>
    <link>https://dev.to/othmane_nemli</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%2F658411%2F4d1fed4b-9c59-48b6-8aee-e1d7643c05d6.png</url>
      <title>DEV Community: Othmane Nemli</title>
      <link>https://dev.to/othmane_nemli</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/othmane_nemli"/>
    <language>en</language>
    <item>
      <title>Laravel Context: The Hidden Information That Follows Your Code</title>
      <dc:creator>Othmane Nemli</dc:creator>
      <pubDate>Sun, 27 Sep 2026 17:33:15 +0000</pubDate>
      <link>https://dev.to/othmane_nemli/laravel-context-the-hidden-information-that-follows-your-code-1mo8</link>
      <guid>https://dev.to/othmane_nemli/laravel-context-the-hidden-information-that-follows-your-code-1mo8</guid>
      <description>&lt;p&gt;When working with Laravel, we usually pass data explicitly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;auth&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;user&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;UserExampleService&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;process&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or we add information directly to a log:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Log&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Processing order'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'order_id'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;id&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;But what if you have some information that should be available throughout the current execution?&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a trace ID&lt;/li&gt;
&lt;li&gt;the current URL&lt;/li&gt;
&lt;li&gt;a tenant ID&lt;/li&gt;
&lt;li&gt;an operation name&lt;/li&gt;
&lt;li&gt;information needed by logging&lt;/li&gt;
&lt;li&gt;information that should follow a queued job&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where Laravel's &lt;strong&gt;Context&lt;/strong&gt; feature becomes interesting.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Laravel Context?
&lt;/h2&gt;

&lt;p&gt;Laravel Context provides a place to store information that belongs to the &lt;strong&gt;current execution&lt;/strong&gt; of your application.&lt;/p&gt;

&lt;p&gt;You can add data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Context&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'trace_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'abc-123'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And retrieve it somewhere else:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$traceId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'trace_id'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The interesting part is that you don't have to keep passing &lt;code&gt;$traceId&lt;/code&gt; through every method.&lt;/p&gt;

&lt;p&gt;The information lives in the current context and can be consumed by other parts of the application.&lt;/p&gt;

&lt;p&gt;Laravel specifically describes Context as a way to capture, retrieve, and share information across requests, jobs, and commands. It also integrates that information with application logs.&lt;/p&gt;




&lt;h2&gt;
  
  
  The simplest example
&lt;/h2&gt;

&lt;p&gt;Imagine middleware generating a trace ID for every request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Context&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Str&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'trace_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Str&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;uuid&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;toString&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now somewhere deep inside your application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$traceId&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'trace_id'&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;No controller parameter.&lt;/li&gt;
&lt;li&gt;No service parameter.&lt;/li&gt;
&lt;li&gt;No global variable.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The data is simply part of the current context.&lt;/p&gt;




&lt;h2&gt;
  
  
  The really useful part: logging
&lt;/h2&gt;

&lt;p&gt;Context becomes particularly useful when combined with logging.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="s1"&gt;'trace_id'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Str&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;uuid&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;toString&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="s1"&gt;'url'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;url&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;Then later:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Log&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'User authenticated'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'user_id'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;id&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 log entry can contain both the information explicitly passed to the log and the information stored in Context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User authenticated
{
    "user_id": 27,
    "trace_id": "e04e1a11-...",
    "url": "https://dev.to/login"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful because you can establish information once and have it accompany subsequent log entries instead of manually adding it everywhere.&lt;/p&gt;




&lt;h2&gt;
  
  
  But here's where Context gets interesting
&lt;/h2&gt;

&lt;p&gt;Imagine this happens:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HTTP Request
     │
     |--- Controller
     │      │
     │      |--- Service
     │             │
     |             |--- context
     │             |--- Dispatch Job
     │
     v
 Job Payload (Context captured, dehydrated, and stored within payload)
     │
     v
 Queu
     │
     v
 Worker
     │
     v hydarte -&amp;gt; restore Context
     │
     v
Job Execution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Normally, the HTTP request and the queued job are two different executions.&lt;/p&gt;

&lt;p&gt;So how would the job know about the context created during the original request?&lt;/p&gt;

&lt;p&gt;Laravel handles this for you, when a job is dispatched, Laravel captures the current context and stores it with the job's payload.&lt;/p&gt;

&lt;p&gt;When the worker starts processing the job, that context is restored into the current execution, Laravel calls these two stages &lt;strong&gt;dehydrating&lt;/strong&gt; and &lt;strong&gt;hydrating&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'trace_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'abc-123'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;ProcessPodcast&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$podcast&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can result in the job seeing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'trace_id'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// "abc-123"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And therefore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Log&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Processing podcast'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can still contain the original trace information. That's a surprisingly powerful feature for debugging distributed workflows.&lt;/p&gt;

&lt;p&gt;So &lt;em&gt;Context&lt;/em&gt; is not a global variable shared between processes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Gere's the interesting part
&lt;/h3&gt;

&lt;p&gt;Laravel's queue worker is a long-running process, it processes one job, then another:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Worker
 │
 |--- Job A
 │
 |--- Job B
 │
 |--- Job C
 │
 |--- Job D
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If Context were simply stored globally and never cleaned up, you could have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Job A
trace_id = abc-123

Job B
trace_id = abc-123  (this is bad)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Laravel therefore has lifecycle management around the worker (registerWorker()). The queue service provider's worker &lt;a href="https://github.com/laravel/framework/blob/13.x/src/Illuminate/Queue/QueueServiceProvider.php#L247" rel="noopener noreferrer"&gt;reset logic&lt;/a&gt; flushes shared logging context and clears scoped instances between jobs, among other cleanup operations.&lt;/p&gt;




&lt;h2&gt;
  
  
  Context can also be hidden
&lt;/h2&gt;

&lt;p&gt;Not everything you put into Context should appear in your logs.Laravel provides &lt;strong&gt;hidden context&lt;/strong&gt; for exactly this purpose:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;addHidden&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'internal_hidden_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;getHidden&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'internal_hidden_id'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// 123&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'internal_hidden_id'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// null&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hidden context isn't appended to log entries and uses a separate API.&lt;/p&gt;

&lt;p&gt;This gives you two different kinds of context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Context
|-- Normal data
│   |--- Can be included in logs
│
|-- Hidden data
    |--- Available to your application, but not included in logs.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That distinction becomes especially useful when context contains internal information that shouldn't become part of your application logs.&lt;/p&gt;

&lt;p&gt;Laravel itself uses hidden Context internally.&lt;/p&gt;

&lt;p&gt;In &lt;a href="https://github.com/laravel/framework/blob/13.x/src/Illuminate/Queue/CallQueuedHandler.php#L357-L361" rel="noopener noreferrer"&gt;CallQueuedHandler&lt;/a&gt;, Laravel can store information such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="err"&gt;laravel_unique_job_cache_store&lt;/span&gt;
&lt;span class="err"&gt;laravel_unique_job_key&lt;/span&gt;
&lt;span class="err"&gt;laravel_unique_job_lock_owner&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Why?&lt;/em&gt; There is a situation where Laravel may not be able to unserialize a queued job because a model is missing.&lt;/p&gt;

&lt;p&gt;In that case, Laravel still needs enough information to release the unique-job lock.&lt;/p&gt;

&lt;p&gt;The handler retrieves those values from the hidden Context and uses them to restore/release the lock&lt;/p&gt;




&lt;h2&gt;
  
  
  Context can have a lifecycle
&lt;/h2&gt;

&lt;p&gt;Laravel also lets you hook into the moment context crosses the queue boundary.&lt;/p&gt;

&lt;p&gt;Typically, you should register &lt;code&gt;dehydrating&lt;/code&gt;/&lt;code&gt;hydrated&lt;/code&gt; callbacks within the &lt;code&gt;boot&lt;/code&gt; method of your application's &lt;code&gt;AppServiceProvider&lt;/code&gt; class:&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;dehydrating&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Repository&lt;/span&gt; &lt;span class="nv"&gt;$context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Prepare context before it is attached to a job&lt;/span&gt;
    &lt;span class="nv"&gt;$context&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addHidden&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'locale'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Config&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'app.locale'&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;And:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;hydrated&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Repository&lt;/span&gt; &lt;span class="nv"&gt;$context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Restore or use context when the job starts&lt;/span&gt;
     &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$context&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;hasHidden&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'locale'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Config&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'app.locale'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$context&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getHidden&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'locale'&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;This means Context isn't simply a static array sitting somewhere.&lt;/p&gt;

&lt;p&gt;Laravel gives you hooks around the transition from one execution environment to another.&lt;/p&gt;

&lt;p&gt;One important detail from the Laravel documentation: inside these callbacks, you should modify the &lt;code&gt;$context&lt;/code&gt; repository provided to the callback rather than calling the &lt;code&gt;Context&lt;/code&gt; facade itself.&lt;/p&gt;




&lt;h2&gt;
  
  
  Context is more than key/value storage
&lt;/h2&gt;

&lt;p&gt;There are some useful features beyond &lt;code&gt;add()&lt;/code&gt; and &lt;code&gt;get()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example, you can store a stack:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'breadcrumbs'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'checkout'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'breadcrumbs'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'payment'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'breadcrumbs'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also retrieve a value and remove it at the same time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;pull&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'key'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or remember a value only when it doesn't already exist:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$permissions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;remember&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s1"&gt;'user-permissions'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;permissions&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;Laravel also provides &lt;code&gt;has&lt;/code&gt;, &lt;code&gt;missing&lt;/code&gt;, &lt;code&gt;forget&lt;/code&gt;, &lt;code&gt;only&lt;/code&gt;, &lt;code&gt;except&lt;/code&gt;, and corresponding hidden-context methods.&lt;/p&gt;

&lt;p&gt;You don't need all of these every day. The important thing is understanding what Context is designed for.&lt;/p&gt;




&lt;h2&gt;
  
  
  When should you use it?
&lt;/h2&gt;

&lt;p&gt;Context is particularly interesting when information belongs to an &lt;strong&gt;execution flow&lt;/strong&gt;, rather than to a particular function.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Request
   │
   |--- Middleware
   │
   |--- Controller
   │
   |--- Service
   │
   |--- Event
   │
   |--- Queue Job
   │
   |-- Logs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A value 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;trace_id = abc-123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can describe the entire operation rather than one particular method; That's where Context shines, so instead of doing this everywhere:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nf"&gt;processOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$traceId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can keep the trace information in Context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'trace_id'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and let the framework carry it through the execution flow.&lt;/p&gt;




&lt;h2&gt;
  
  
  One important rule
&lt;/h2&gt;

&lt;p&gt;Context is not a replacement for normal application data, don't put everything into it, a useful mental model is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Arguments describe what a function needs. Context describes what is happening around the current execution.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nf"&gt;processOrder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$order&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;makes sense because &lt;code&gt;$order&lt;/code&gt; is an input to the operation.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'trace_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$traceId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;makes sense because the trace ID describes the execution surrounding that operation.&lt;/p&gt;




&lt;h2&gt;
  
  
  At the end, is it another Laravel key/value?
&lt;/h2&gt;

&lt;p&gt;The API itself is simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&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 interesting part is what Laravel does with that information.&lt;/p&gt;

&lt;p&gt;It can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;attach it to logs,&lt;/li&gt;
&lt;li&gt;carry it from an HTTP request into a queued job,&lt;/li&gt;
&lt;li&gt;restore it when the job starts,&lt;/li&gt;
&lt;li&gt;keep hidden data separate from log data,&lt;/li&gt;
&lt;li&gt;and give your application hooks around that transfer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the next time you see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'trace_id'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$traceId&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;don't think of it as just another Laravel key/value store, think of it as &lt;strong&gt;metadata attached to an execution flow&lt;/strong&gt;, and that's what makes Laravel Context much more interesting than it first appears.&lt;/p&gt;

&lt;p&gt;Sources:&lt;br&gt;
&lt;a href="https://laravel.com/framework/docs/13.x/context" rel="noopener noreferrer"&gt;Context Doc&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
    </item>
    <item>
      <title>Vite+ — Chapter 5: Should You Use Vite+?</title>
      <dc:creator>Othmane Nemli</dc:creator>
      <pubDate>Sat, 26 Sep 2026 13:56:21 +0000</pubDate>
      <link>https://dev.to/othmane_nemli/vite-chapter-5-should-you-use-vite-4l8b</link>
      <guid>https://dev.to/othmane_nemli/vite-chapter-5-should-you-use-vite-4l8b</guid>
      <description>&lt;p&gt;We've reached the final chapter.&lt;/p&gt;

&lt;p&gt;Now comes the question every developer eventually asks when evaluating a new tool:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Should I actually use it?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The answer depends on your project.&lt;/p&gt;

&lt;p&gt;Vite+ isn't something you need to add to every JavaScript application just because it exists.&lt;/p&gt;

&lt;p&gt;Instead, it's worth understanding &lt;strong&gt;what problems it solves, what it changes, and whether those problems actually exist in your project.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  1. First: What Is Vite+ Really?
&lt;/h2&gt;

&lt;p&gt;Let's summarize the entire series in one sentence:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Vite+ is an integrated JavaScript toolchain built around Vite and other modern tools from the VoidZero ecosystem.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It brings together tools 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;Vite
Vitest
Rolldown
tsdown
Oxlint
Oxfmt
Vite Task
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and exposes them through the &lt;code&gt;vp&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp dev
vp &lt;span class="nb"&gt;test
&lt;/span&gt;vp check
vp build
vp run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important part isn't simply having fewer commands.&lt;/p&gt;

&lt;p&gt;The bigger idea is having a more integrated development environment.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. The Problem Vite+ Is Trying to Solve
&lt;/h2&gt;

&lt;p&gt;Modern JavaScript projects often look 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;                    package manager
                          │
          ┌───────────────┼───────────────┐
          │               │               │
        Vite            Vitest        TypeScript
          │               │               │
       Build             Test          Type check
          │               │               │
       ESLint           Prettier       Task runner
          │               │               │
          └───────────────┴───────────────┘
                          │
                         CI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each tool can be good at its job.&lt;/p&gt;

&lt;p&gt;The problem is the &lt;strong&gt;connections between them&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;You eventually have to answer questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which tool should I use?&lt;/li&gt;
&lt;li&gt;Which configuration file controls it?&lt;/li&gt;
&lt;li&gt;Which version should I install?&lt;/li&gt;
&lt;li&gt;How do these tools interact?&lt;/li&gt;
&lt;li&gt;How should CI run them?&lt;/li&gt;
&lt;li&gt;How should they work in a monorepo?&lt;/li&gt;
&lt;li&gt;Which tasks depend on each other?&lt;/li&gt;
&lt;li&gt;Which results can be cached?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Vite+ tries to reduce some of that complexity.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. When Vite+ Makes Sense
&lt;/h2&gt;

&lt;p&gt;There are several situations where Vite+ can be particularly interesting.&lt;/p&gt;

&lt;h3&gt;
  
  
  Growing projects
&lt;/h3&gt;

&lt;p&gt;Maybe your application started small.&lt;/p&gt;

&lt;p&gt;You had:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
package.json
vite.config.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then six months later:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
tests/
packages/
scripts/
apps/
.github/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The project has grown.&lt;/p&gt;

&lt;p&gt;Now you're maintaining:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;development tooling&lt;/li&gt;
&lt;li&gt;tests&lt;/li&gt;
&lt;li&gt;formatting&lt;/li&gt;
&lt;li&gt;linting&lt;/li&gt;
&lt;li&gt;builds&lt;/li&gt;
&lt;li&gt;CI&lt;/li&gt;
&lt;li&gt;multiple packages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where a unified toolchain can become more valuable.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Teams That Want Consistency
&lt;/h2&gt;

&lt;p&gt;Imagine a team of 20 developers.&lt;/p&gt;

&lt;p&gt;Developer A runs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run lint
npm run &lt;span class="nb"&gt;test
&lt;/span&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Developer B runs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pnpm lint
pnpm &lt;span class="nb"&gt;test
&lt;/span&gt;pnpm build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Developer C has a custom script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./scripts/check-everything.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And CI has:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;some completely different collection of commands
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It works, but it creates cognitive overhead.&lt;/p&gt;

&lt;p&gt;With Vite+, the team can establish a simpler vocabulary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp check
vp &lt;span class="nb"&gt;test
&lt;/span&gt;vp build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;New developers have fewer project-specific commands to memorize.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Monorepos
&lt;/h2&gt;

&lt;p&gt;This is probably one of the most interesting scenarios.&lt;/p&gt;

&lt;p&gt;Suppose your repository contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apps/
├── web/
├── admin/
└── docs/

packages/
├── ui/
├── utils/
├── api/
└── config/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;package dependencies&lt;/li&gt;
&lt;li&gt;task dependencies&lt;/li&gt;
&lt;li&gt;build ordering&lt;/li&gt;
&lt;li&gt;caching&lt;/li&gt;
&lt;li&gt;parallel execution&lt;/li&gt;
&lt;li&gt;CI optimization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where &lt;code&gt;vp run&lt;/code&gt; and Vite Task become much more relevant.&lt;/p&gt;

&lt;p&gt;Instead of treating every package as an isolated project, the task system can reason about the repository as a whole.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can operate across the task graph rather than simply executing one script in one directory.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. When Vite+ May Not Be Necessary
&lt;/h2&gt;

&lt;p&gt;Now let's look at the other side.&lt;/p&gt;

&lt;p&gt;Imagine you're building:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-portfolio/
├── src/
├── public/
├── package.json
└── vite.config.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one application&lt;/li&gt;
&lt;li&gt;one developer&lt;/li&gt;
&lt;li&gt;a handful of dependencies&lt;/li&gt;
&lt;li&gt;a simple deployment pipeline&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your current workflow might already be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run dev
npm run &lt;span class="nb"&gt;test
&lt;/span&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And everything works.&lt;/p&gt;

&lt;p&gt;In that situation, introducing another layer may not provide enough value to justify changing your workflow.&lt;/p&gt;

&lt;p&gt;That's an important lesson when evaluating developer tools:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A tool doesn't need to solve a problem you don't have.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  7. Don't Adopt Tools Just Because They're New
&lt;/h2&gt;

&lt;p&gt;This is especially important with developer tooling.&lt;/p&gt;

&lt;p&gt;A new tool can be:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;technically interesting&lt;/li&gt;
&lt;li&gt;faster&lt;/li&gt;
&lt;li&gt;beautifully designed&lt;/li&gt;
&lt;li&gt;backed by a respected team&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and still not be necessary for your project.&lt;/p&gt;

&lt;p&gt;Before adopting Vite+, ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What problem am I trying to solve?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What new tool should I install?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first question leads to better engineering decisions.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. What About Existing Vite Projects?
&lt;/h2&gt;

&lt;p&gt;This is probably the most common question.&lt;/p&gt;

&lt;p&gt;Suppose you already have a Vite application.&lt;/p&gt;

&lt;p&gt;You might have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-app/
├── src/
├── public/
├── package.json
├── vite.config.ts
├── vitest.config.ts
├── eslint.config.js
└── prettier.config.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do you need to throw everything away?&lt;/p&gt;

&lt;p&gt;No.&lt;/p&gt;

&lt;p&gt;Vite+ is designed to work with existing projects and provides migration tooling.&lt;/p&gt;

&lt;p&gt;The migration workflow can be started with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The migration process can help bring an existing project toward the Vite+ setup, but you should still review the changes carefully. The project is in beta, and complex repositories may require manual adjustments. (&lt;a href="https://voidzero.dev/posts/announcing-vite-plus-beta" rel="noopener noreferrer"&gt;voidzero.dev&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;Migration should therefore be treated as an engineering change, not just a dependency update.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Migration Is More Than Changing Commands
&lt;/h2&gt;

&lt;p&gt;Imagine your current project has:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ESLint
Prettier
Vitest
Vite
TypeScript
custom scripts
GitHub Actions
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Moving to Vite+ potentially changes several parts of your workflow.&lt;/p&gt;

&lt;p&gt;You should check:&lt;/p&gt;

&lt;h3&gt;
  
  
  Development
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;behave as expected?&lt;/p&gt;

&lt;h3&gt;
  
  
  Tests
&lt;/h3&gt;

&lt;p&gt;Do your existing tests work with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Formatting
&lt;/h3&gt;

&lt;p&gt;Does your codebase produce the formatting you expect?&lt;/p&gt;

&lt;h3&gt;
  
  
  Linting
&lt;/h3&gt;

&lt;p&gt;Do existing lint rules still behave as expected?&lt;/p&gt;

&lt;h3&gt;
  
  
  CI
&lt;/h3&gt;

&lt;p&gt;Does your pipeline still produce the same artifacts?&lt;/p&gt;

&lt;h3&gt;
  
  
  Builds
&lt;/h3&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;produce the expected output?&lt;/p&gt;

&lt;p&gt;A successful migration isn't simply:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Command completed successfully
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The project still behaves correctly.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  10. Vite+ Is Still Evolving
&lt;/h2&gt;

&lt;p&gt;This point is important.&lt;/p&gt;

&lt;p&gt;Vite+ is currently a &lt;strong&gt;beta&lt;/strong&gt; project.&lt;/p&gt;

&lt;p&gt;That means you should expect the project to evolve before reaching its stable 1.0 release. The official announcement describes Vite+ as being developed toward a 1.0 release and invites developers to try the beta and provide feedback. (&lt;a href="https://voidzero.dev/posts/announcing-vite-plus-beta" rel="noopener noreferrer"&gt;voidzero.dev&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;For developers, this has two sides.&lt;/p&gt;

&lt;p&gt;You get to experiment with a modern toolchain early.&lt;/p&gt;

&lt;p&gt;But you also need to accept that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;APIs can evolve&lt;/li&gt;
&lt;li&gt;configuration can change&lt;/li&gt;
&lt;li&gt;documentation can change&lt;/li&gt;
&lt;li&gt;workflows can be refined&lt;/li&gt;
&lt;li&gt;bugs can still appear&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's normal for beta software.&lt;/p&gt;




&lt;h2&gt;
  
  
  11. Beta Doesn't Mean "Don't Use It"
&lt;/h2&gt;

&lt;p&gt;Beta software isn't automatically unusable.&lt;/p&gt;

&lt;p&gt;It simply means you should understand the risk.&lt;/p&gt;

&lt;p&gt;There is a big difference between:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Trying Vite+ on a side project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Replacing the entire toolchain
of a mission-critical production system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The amount of validation you need should match the importance of the project.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;h3&gt;
  
  
  Experiment
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Personal project
     ↓
Try Vite+
     ↓
See how it feels
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Team project
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Evaluate
   ↓
Prototype
   ↓
Test CI
   ↓
Test production build
   ↓
Document workflow
   ↓
Adopt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second process takes longer.&lt;/p&gt;

&lt;p&gt;That's appropriate because the cost of failure is higher.&lt;/p&gt;




&lt;h2&gt;
  
  
  12. What About Performance?
&lt;/h2&gt;

&lt;p&gt;Performance is one of the reasons modern JavaScript tooling is evolving.&lt;/p&gt;

&lt;p&gt;VoidZero is building tools such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Rolldown&lt;/li&gt;
&lt;li&gt;Oxc&lt;/li&gt;
&lt;li&gt;Vite&lt;/li&gt;
&lt;li&gt;Vitest&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;with an emphasis on performance and integration.&lt;/p&gt;

&lt;p&gt;Some of the lower-level tools are implemented in Rust, including the Oxc toolchain and Rolldown.&lt;/p&gt;

&lt;p&gt;But there's an important distinction:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A faster individual tool doesn't automatically make your entire development workflow faster.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Your real development experience depends on many things:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tool speed
+
Project size
+
Configuration
+
Dependency graph
+
Task scheduling
+
Caching
+
CI environment
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So don't evaluate Vite+ only by looking at benchmark numbers.&lt;/p&gt;

&lt;p&gt;Try it on a project that resembles your real workload.&lt;/p&gt;




&lt;h2&gt;
  
  
  13. Developer Experience Matters Too
&lt;/h2&gt;

&lt;p&gt;Performance is only one part of developer experience.&lt;/p&gt;

&lt;p&gt;Consider how often developers type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run dev
npm run lint
npm run format
npm run &lt;span class="nb"&gt;test
&lt;/span&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now compare that with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp dev
vp check
vp &lt;span class="nb"&gt;test
&lt;/span&gt;vp build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The difference isn't enormous.&lt;/p&gt;

&lt;p&gt;But over hundreds of days, small sources of friction add up.&lt;/p&gt;

&lt;p&gt;More importantly, a consistent interface can make a project easier to explain.&lt;/p&gt;

&lt;p&gt;For a new developer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;How do I check the project?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;How do I run tests?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;How do I build it?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple conventions are valuable.&lt;/p&gt;




&lt;h2&gt;
  
  
  14. But Don't Ignore Your Existing Ecosystem
&lt;/h2&gt;

&lt;p&gt;Every project has dependencies outside its main build tool.&lt;/p&gt;

&lt;p&gt;You might use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Storybook
Playwright
Cypress
Tailwind
Next.js
Nuxt
custom deployment tools
internal scripts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Not every project will benefit equally from moving toward Vite+.&lt;/p&gt;

&lt;p&gt;You should check compatibility with the tools that matter to your specific application.&lt;/p&gt;

&lt;p&gt;For example, don't start a migration by asking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Can Vite+ replace everything?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Can Vite+ improve the parts of our workflow that currently cause problems?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's a much safer approach.&lt;/p&gt;




&lt;h2&gt;
  
  
  15. A Practical Evaluation Strategy
&lt;/h2&gt;

&lt;p&gt;If you're considering Vite+, don't immediately migrate your biggest production repository.&lt;/p&gt;

&lt;p&gt;Start small.&lt;/p&gt;

&lt;h4&gt;
  
  
  Step 1 — Pick a representative project
&lt;/h4&gt;

&lt;p&gt;Choose something that has enough complexity to expose real problems.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;hello-world/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and not necessarily:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;our-most-important-production-system/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Something in between is ideal.&lt;/p&gt;




&lt;h4&gt;
  
  
  Step 2 — Establish a baseline
&lt;/h4&gt;

&lt;p&gt;Before migrating, measure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Install time
Build time
Test time
CI time
Developer workflow
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Current:

Install → 35s
Tests   → 50s
Build   → 80s
CI      → 4m 20s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you have something to compare against.&lt;/p&gt;




&lt;h4&gt;
  
  
  Step 3 — Migrate
&lt;/h4&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Review the changes.&lt;/p&gt;

&lt;p&gt;Then run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp check
vp &lt;span class="nb"&gt;test
&lt;/span&gt;vp build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h4&gt;
  
  
  Step 4 — Test CI
&lt;/h4&gt;

&lt;p&gt;Don't stop at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="s2"&gt;"It works on my laptop."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the actual CI workflow.&lt;/p&gt;

&lt;p&gt;Check:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dependency installation&lt;/li&gt;
&lt;li&gt;tests&lt;/li&gt;
&lt;li&gt;linting&lt;/li&gt;
&lt;li&gt;formatting&lt;/li&gt;
&lt;li&gt;build output&lt;/li&gt;
&lt;li&gt;caching&lt;/li&gt;
&lt;li&gt;deployment artifacts&lt;/li&gt;
&lt;/ul&gt;




&lt;h4&gt;
  
  
  Step 5 — Compare
&lt;/h4&gt;

&lt;p&gt;Now you have real information.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                    Before       After

Install             35s          30s
Tests               50s          40s
Build               80s          55s
CI                  4m20s        3m10s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These numbers are only an example.&lt;/p&gt;

&lt;p&gt;Your results may be completely different.&lt;/p&gt;

&lt;p&gt;The point is to measure &lt;strong&gt;your project&lt;/strong&gt;, not someone else's benchmark.&lt;/p&gt;




&lt;h2&gt;
  
  
  16. The Most Important Lesson
&lt;/h2&gt;

&lt;p&gt;After all five chapters, there's one idea I think is worth remembering.&lt;/p&gt;

&lt;p&gt;Vite+ isn't primarily interesting because:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vp dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is shorter than:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's not the real story.&lt;/p&gt;

&lt;p&gt;The interesting part is the integration.&lt;/p&gt;

&lt;p&gt;Think about the entire workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Vite+
                   │
        ┌──────────┼──────────┐
        │          │          │
      Develop    Test       Check
        │          │          │
       Vite      Vitest    Oxlint/Oxfmt
        │
      Build
        │
    Rolldown
        │
        ▼
   Task system
        │
        ▼
   Monorepo / CI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal is to make these pieces work together as one development environment.&lt;/p&gt;

&lt;p&gt;That's the bigger idea.&lt;/p&gt;




&lt;h2&gt;
  
  
  17. Vite+ Doesn't Make Individual Tools Disappear
&lt;/h2&gt;

&lt;p&gt;This is another important distinction.&lt;/p&gt;

&lt;p&gt;When you run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vitest doesn't suddenly stop existing.&lt;/p&gt;

&lt;p&gt;When you run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vite and Rolldown don't stop existing.&lt;/p&gt;

&lt;p&gt;When you run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;the underlying checking tools still matter.&lt;/p&gt;

&lt;p&gt;Vite+ provides the integration layer.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;             Your project
                  │
                  ▼
                Vite+
                  │
       ┌──────────┼──────────┐
       ▼          ▼          ▼
     Vite       Vitest     Oxc tools
       │          │          │
       └──────────┼──────────┘
                  ▼
             Task system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is why understanding the individual tools from Chapter 2 was important.&lt;/p&gt;

&lt;p&gt;Vite+ doesn't remove the concepts.&lt;/p&gt;

&lt;p&gt;It connects them.&lt;/p&gt;

&lt;h2&gt;
  
  
  19. To wrap things up
&lt;/h2&gt;

&lt;p&gt;JavaScript tooling has become incredibly powerful.&lt;/p&gt;

&lt;p&gt;But that power also created complexity.&lt;/p&gt;

&lt;p&gt;We have excellent tools for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;development&lt;/li&gt;
&lt;li&gt;bundling&lt;/li&gt;
&lt;li&gt;testing&lt;/li&gt;
&lt;li&gt;linting&lt;/li&gt;
&lt;li&gt;formatting&lt;/li&gt;
&lt;li&gt;packaging&lt;/li&gt;
&lt;li&gt;task execution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The challenge is making all of them work together without creating unnecessary maintenance work.&lt;/p&gt;

&lt;p&gt;That's the space Vite+ is trying to address.&lt;/p&gt;

&lt;p&gt;Whether it becomes the standard way teams build JavaScript applications remains something the ecosystem will determine over time.&lt;/p&gt;

&lt;p&gt;For developers, the interesting part is the direction:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;More integrated tooling
        ↓
Less configuration
        ↓
Better coordination
        ↓
Faster feedback
        ↓
Simpler workflows
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's worth paying attention to.&lt;/p&gt;

&lt;p&gt;You don't need to migrate every project tomorrow.&lt;/p&gt;

&lt;p&gt;You don't need to replace tools that already work.&lt;/p&gt;

&lt;p&gt;But if you're building a new project, maintaining a growing monorepo, or regularly fighting with your JavaScript toolchain, Vite+ is certainly a project worth understanding and evaluating.&lt;/p&gt;

&lt;p&gt;And now, when you see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp dev
vp check
vp &lt;span class="nb"&gt;test
&lt;/span&gt;vp build
vp run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you know what's happening behind those commands.&lt;/p&gt;

&lt;p&gt;And that's the real story behind Vite+.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed following this series and that it helped answer your questions and gave you a clearer understanding of the topic. Thanks for reading, and I hope you found it useful!&lt;/p&gt;

&lt;p&gt;OT&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>viteplus</category>
      <category>vite</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Vite+ — Chapter 4: Vite+ at Scale — Monorepos, Tasks, Caching, and CI</title>
      <dc:creator>Othmane Nemli</dc:creator>
      <pubDate>Sat, 26 Sep 2026 12:08:38 +0000</pubDate>
      <link>https://dev.to/othmane_nemli/vite-chapter-4-vite-at-scale-monorepos-tasks-caching-and-ci-2pmh</link>
      <guid>https://dev.to/othmane_nemli/vite-chapter-4-vite-at-scale-monorepos-tasks-caching-and-ci-2pmh</guid>
      <description>&lt;p&gt;In the previous chapter, we used Vite+ for a normal application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp dev
vp check
vp &lt;span class="nb"&gt;test
&lt;/span&gt;vp build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That workflow is already useful.&lt;/p&gt;

&lt;p&gt;But there's another situation where Vite+ becomes much more interesting:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What happens when your project becomes a lot bigger?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Imagine that one application becomes five, then you add shared UI components, then shared utilities, then a design system, then internal libraries.&lt;/p&gt;

&lt;p&gt;Eventually, your repository might look 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;company-project/
├── apps/
│   ├── web/
│   ├── admin/
│   └── docs/
│
├── packages/
│   ├── ui/
│   ├── utils/
│   ├── config/
│   └── api/
│
└── package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a &lt;strong&gt;monorepo&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And this is where running every task all the time can become expensive.&lt;/p&gt;

&lt;p&gt;Vite+ includes Vite Task specifically to handle dependency-aware task execution and caching in monorepos.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. What Is a Monorepo?
&lt;/h2&gt;

&lt;p&gt;Before talking about Vite+, let's understand the problem.&lt;/p&gt;

&lt;p&gt;A monorepo is simply a repository containing multiple projects or packages.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-company/
│
├── apps/
│   ├── web/
│   └── mobile/
│
└── packages/
    ├── ui/
    ├── utils/
    └── types/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we might have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;web&lt;/code&gt; → the main website&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mobile&lt;/code&gt; → a mobile application&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ui&lt;/code&gt; → shared UI components&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;utils&lt;/code&gt; → shared utilities&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;types&lt;/code&gt; → shared TypeScript types&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The advantage is that everything lives together.&lt;/p&gt;

&lt;p&gt;A developer can change a shared package and immediately test the applications that use it.&lt;/p&gt;

&lt;p&gt;But this also creates a new problem:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Which tasks actually need to run?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  2. The Dependency Problem
&lt;/h2&gt;

&lt;p&gt;Let's say we have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;web
 │
 └── ui
      │
      └── utils
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;web depends on ui
ui depends on utils
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now imagine you change something inside:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;packages/utils/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Should we rebuild everything? Maybe.&lt;/p&gt;

&lt;p&gt;But what if you only changed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apps/docs/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do we really need to rebuild &lt;code&gt;web&lt;/code&gt;? Probably not.&lt;/p&gt;

&lt;p&gt;A large monorepo can contain hundreds of tasks.&lt;/p&gt;

&lt;p&gt;Running all of them after every small change wastes time.&lt;/p&gt;

&lt;p&gt;This is where a task system becomes important.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. What Is a Task?
&lt;/h2&gt;

&lt;p&gt;A task is simply something your project needs to do.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;build
test
lint
typecheck
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A package might have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vite build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vitest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"oxlint"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are tasks, in a small application, running them manually isn't difficult.&lt;/p&gt;

&lt;p&gt;In a monorepo, however, you might have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;20 packages
×
4 tasks
=
80 possible tasks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the task runner has a much bigger job.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Enter &lt;code&gt;vp run&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Vite+ provides:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command can run package scripts and monorepo tasks while understanding dependencies between them. It also supports task caching.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can think of this as saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Run the build tasks that are relevant to this project."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead of manually navigating through every package.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Task Dependencies
&lt;/h2&gt;

&lt;p&gt;Let's use a simple example.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;packages/utils
       ↓
packages/ui
       ↓
apps/web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The relationships are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;utils
  ↓
ui
  ↓
web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;web&lt;/code&gt; needs &lt;code&gt;ui&lt;/code&gt;, and &lt;code&gt;ui&lt;/code&gt; needs &lt;code&gt;utils&lt;/code&gt;, then the build order matters.&lt;/p&gt;

&lt;p&gt;You can't necessarily build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and you can't build:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;utils
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The dependency graph is therefore:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;utils
  │
  ▼
 ui
  │
  ▼
web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A task runner can use this graph to determine what needs to happen first.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Why Dependency-Aware Execution Matters
&lt;/h2&gt;

&lt;p&gt;Imagine your repository contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apps/
├── web
├── admin
└── docs

packages/
├── ui
├── utils
├── api
└── config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;web → ui → utils
admin → ui → utils
docs → ui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;utils&lt;/code&gt; changes, both &lt;code&gt;web&lt;/code&gt; and &lt;code&gt;admin&lt;/code&gt; may be affected.&lt;/p&gt;

&lt;p&gt;But &lt;code&gt;docs&lt;/code&gt; might not depend directly on &lt;code&gt;utils&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A dependency-aware task runner can use those relationships instead of blindly running everything.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;utils changed
     │
     ├── ui
     │    ├── web
     │    └── admin
     │
     └── unrelated packages
          ↓
        skip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the important idea.&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Caching
&lt;/h2&gt;

&lt;p&gt;Now we reach one of the most useful features.&lt;/p&gt;

&lt;p&gt;Imagine you run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp run build &lt;span class="c"&gt;# takes 45 seconds&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you run the exact same command again.&lt;/p&gt;

&lt;p&gt;If nothing relevant changed, rebuilding everything from scratch is unnecessary.&lt;/p&gt;

&lt;p&gt;This is where caching comes in.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;First run

Source code
    ↓
Build
    ↓
45 seconds
    ↓
Save result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Second run

Same inputs
    ↓
Cache lookup
    ↓
Reuse previous result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of "45 seconds", you can potentially get a result much faster.&lt;/p&gt;

&lt;p&gt;Vite+ describes &lt;code&gt;vp run&lt;/code&gt; as providing caching and dependency-aware scheduling for monorepo tasks.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. What Does the Cache Actually Mean?
&lt;/h2&gt;

&lt;p&gt;A common misunderstanding is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The cache means Vite+ never runs the command again."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's not quite right.&lt;/p&gt;

&lt;p&gt;The important question is whether the task's relevant inputs have changed.&lt;/p&gt;

&lt;p&gt;Think about:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Input
 ↓
Task
 ↓
Output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
package.json
tsconfig.json
environment
     ↓
   build
     ↓
   dist/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the inputs are unchanged, the previous result may be reusable.&lt;/p&gt;

&lt;p&gt;If an important input changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/Button.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then the task may need to run again.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Same inputs
    ↓
Cache hit
    ↓
Reuse result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Changed inputs
    ↓
Cache miss
    ↓
Run task again
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the basic idea behind task caching.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. Cache Hits and Cache Misses
&lt;/h2&gt;

&lt;p&gt;You'll often hear two terms:&lt;/p&gt;

&lt;h3&gt;
  
  
  Cache hit
&lt;/h3&gt;

&lt;p&gt;The previous result can be reused.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;web#build — cache hit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Cache miss
&lt;/h3&gt;

&lt;p&gt;The task needs to run again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;web#build — cache miss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;First run:

utils#build   → cache miss
ui#build      → cache miss
web#build     → cache miss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything has to run.&lt;/p&gt;

&lt;p&gt;Then you run it again without changing anything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Second run:

utils#build   → cache hit
ui#build      → cache hit
web#build     → cache hit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact behavior depends on the task inputs and configuration, but this is the mental model developers should have.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. Why This Matters in CI
&lt;/h2&gt;

&lt;p&gt;Now let's move from your laptop to CI.&lt;/p&gt;

&lt;p&gt;A typical CI pipeline might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer pushes code
        ↓
     GitHub
        ↓
     CI starts
        ↓
    Install deps
        ↓
      Check
        ↓
      Test
        ↓
      Build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without caching, every CI run may repeat expensive work.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Install     → 30 sec
Lint        → 20 sec
Tests       → 60 sec
Build       → 90 sec
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's already several minutes.&lt;/p&gt;

&lt;p&gt;Now imagine a repository with dozens of packages, the wasted time adds up quickly.&lt;/p&gt;




&lt;h2&gt;
  
  
  11. Vite+ and GitHub Actions
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://viteplus.dev/guide/ci" rel="noopener noreferrer"&gt;Vite+&lt;/a&gt; provides an official GitHub Action called &lt;a href="https://github.com/voidzero-dev/setup-vp" rel="noopener noreferrer"&gt;setup-vp&lt;/a&gt; for installing Vite+ in GitHub Actions. The current repository documentation recommends pinning the action to an exact release or commit rather than using the old floating &lt;code&gt;v1&lt;/code&gt; tag.&lt;/p&gt;

&lt;p&gt;A simplified example looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;CI&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;

    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v4&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;voidzero-dev/setup-vp@&amp;lt;setup-vp-version&amp;gt;&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;22'&lt;/span&gt;
          &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vp install&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vp check&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vp test&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vp build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important part isn't the exact YAML,, it's the workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GitHub Actions
      ↓
   setup-vp
      ↓
   vp install
      ↓
   vp check
      ↓
   vp test
      ↓
   vp build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same &lt;code&gt;vp&lt;/code&gt; commands you use locally can be used in CI. That consistency is valuable.&lt;/p&gt;




&lt;h2&gt;
  
  
  12. Local Development and CI Use the Same Interface
&lt;/h2&gt;

&lt;p&gt;One thing I particularly like about this approach is that developers don't have to learn a completely different system for CI.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp check
vp &lt;span class="nb"&gt;test
&lt;/span&gt;vp build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vp check&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vp test&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vp build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The commands are the same.&lt;/p&gt;

&lt;p&gt;That means when something fails in CI, you can often reproduce the same command locally.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of trying to understand:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;some-custom-ci-script.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;that internally calls several other tools.&lt;/p&gt;




&lt;h2&gt;
  
  
  13. A Monorepo Example
&lt;/h2&gt;

&lt;p&gt;Let's imagine a real project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;acme/
├── apps/
│   ├── storefront/
│   └── dashboard/
│
├── packages/
│   ├── ui/
│   ├── auth/
│   ├── api-client/
│   └── utils/
│
├── package.json
└── vite.config.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dependencies might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 ┌── ui ────────┐
                 │              │
storefront ──────┤              │
                 │              ▼
                 └── api-client
                       │
                       ▼
                     utils
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dashboard
    │
    ├── ui
    │
    └── auth
          │
          ▼
        utils
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now imagine you modify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;packages/utils/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Several projects could be affected.&lt;/p&gt;

&lt;p&gt;A task runner can use the dependency graph to determine the appropriate execution order.&lt;/p&gt;

&lt;p&gt;Instead of manually figuring out:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1. Build utils
2. Build api-client
3. Build ui
4. Build storefront
5. Build auth
6. Build dashboard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can use the task system to coordinate those tasks.&lt;/p&gt;




&lt;h2&gt;
  
  
  14. Parallelism
&lt;/h2&gt;

&lt;p&gt;There's another important idea here:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Not every task needs to run sequentially.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;storefront
    ↓
   ui

dashboard
    ↓
   auth
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The two branches are independent.&lt;/p&gt;

&lt;p&gt;Conceptually, they can be processed 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;          ui ────────&amp;gt; storefront
         /
Start ──
         \
          auth ──────&amp;gt; dashboard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ui
 ↓
storefront
 ↓
auth
 ↓
dashboard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;a task system can execute independent work concurrently where appropriate.&lt;/p&gt;

&lt;p&gt;This becomes increasingly important as the repository grows.&lt;/p&gt;

&lt;p&gt;The goal is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Don't make one task wait for another task if there is no dependency between them.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  15. &lt;code&gt;vp run&lt;/code&gt; Is More Than &lt;code&gt;npm run&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;At first, you might look at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Isn't that basically the same as &lt;code&gt;npm run build&lt;/code&gt;?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For a simple project, the difference may not feel dramatic.&lt;/p&gt;

&lt;p&gt;But in a monorepo, the task system adds concepts such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;dependency-aware execution&lt;/li&gt;
&lt;li&gt;task graphs&lt;/li&gt;
&lt;li&gt;caching&lt;/li&gt;
&lt;li&gt;filtering&lt;/li&gt;
&lt;li&gt;parallel execution&lt;/li&gt;
&lt;li&gt;task-level configuration&lt;/li&gt;
&lt;/ul&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is primarily: &lt;strong&gt;Run this script&lt;/strong&gt;&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can be thought of as: &lt;strong&gt;Run the appropriate build tasks across the project while understanding their relationships and cached results.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That distinction becomes important at scale.&lt;/p&gt;




&lt;h2&gt;
  
  
  16. Filtering Tasks
&lt;/h2&gt;

&lt;p&gt;Large monorepos don't always need everything to run.&lt;/p&gt;

&lt;p&gt;Sometimes you only want to work with one package.&lt;/p&gt;

&lt;p&gt;For example, you might want to run a task for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apps/storefront
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;rather than the entire repository.&lt;/p&gt;

&lt;p&gt;Vite+ supports filtering in its task workflow, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp run &lt;span class="nt"&gt;--filter&lt;/span&gt; storefront build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact filters you use depend on your workspace structure and task configuration.&lt;/p&gt;

&lt;p&gt;The important idea is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Whole repository
       ↓
     filter
       ↓
Relevant packages
       ↓
Relevant tasks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is particularly useful when working locally.&lt;/p&gt;




&lt;h2&gt;
  
  
  17. One Configuration for the Whole Toolchain
&lt;/h2&gt;

&lt;p&gt;We saw in Chapter 3 that Vite+ can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vite.config.ts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;as a central configuration file.&lt;/p&gt;

&lt;p&gt;For a larger repository, that becomes even more useful.&lt;/p&gt;

&lt;p&gt;The configuration can include:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&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="s1"&gt;vite-plus&lt;/span&gt;&lt;span class="dl"&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="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;

  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/**/*.test.ts&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;lint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;ignorePatterns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dist/**&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;fmt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;semi&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;span class="na"&gt;singleQuote&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;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;tasks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;generate:icons&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;command&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;node scripts/generate-icons.js&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="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;This means the same configuration surface can describe parts of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Development
     ↓
Testing
     ↓
Linting
     ↓
Formatting
     ↓
Task execution
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The current Vite+ repository documents this unified configuration approach.&lt;/p&gt;




&lt;h2&gt;
  
  
  18. But Caching Isn't Magic
&lt;/h2&gt;

&lt;p&gt;This is important.&lt;/p&gt;

&lt;p&gt;Caching sounds simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Nothing changed
    ↓
Use cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Real projects are more complicated.&lt;/p&gt;

&lt;p&gt;A task can read files you didn't expect.&lt;/p&gt;

&lt;p&gt;A build can generate files.&lt;/p&gt;

&lt;p&gt;A tool can modify something inside &lt;code&gt;node_modules&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Environment variables can affect output.&lt;/p&gt;

&lt;p&gt;Generated files can become inputs to another task.&lt;/p&gt;

&lt;p&gt;This means cache correctness depends on correctly understanding the task's inputs and outputs.&lt;/p&gt;

&lt;p&gt;The Vite+ project has continued improving task-cache reliability, and its release history includes fixes around automatically tracked inputs and caching behavior.&lt;/p&gt;

&lt;p&gt;So when introducing caching to a large repository, you should still verify that tasks are configured correctly.&lt;/p&gt;




&lt;h2&gt;
  
  
  19. Don't Treat Cache Hits as Guaranteed
&lt;/h2&gt;

&lt;p&gt;This is another useful lesson.&lt;/p&gt;

&lt;p&gt;You might expect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;followed by:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to always produce 100% cache hits.&lt;/p&gt;

&lt;p&gt;But real-world projects can have tasks that modify their own inputs or produce files that affect the task fingerprint.&lt;/p&gt;

&lt;p&gt;The Vite+ issue tracker has documented examples of cache misses caused by generated files and dependency/runtime cache directories.&lt;/p&gt;

&lt;p&gt;This doesn't mean caching isn't useful.&lt;/p&gt;

&lt;p&gt;It means developers should understand what the cache is actually tracking.&lt;/p&gt;

&lt;p&gt;A good mental model is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Caching is a correctness feature first and a performance feature second.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If the system cannot prove that the previous result is still valid, rerunning the task is safer than incorrectly reusing an old result.&lt;/p&gt;




&lt;h2&gt;
  
  
  20. A Practical CI Pipeline
&lt;/h2&gt;

&lt;p&gt;For a monorepo, you might eventually have something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Pull Request
                      │
                      ▼
                 Install deps
                      │
                      ▼
                   vp check
                      │
                      ▼
                   vp test
                      │
                      ▼
                  vp run build
                      │
                      ▼
                Deploy / Publish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important thing is that developers and CI share the same vocabulary.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp check
vp &lt;span class="nb"&gt;test
&lt;/span&gt;vp run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vp check&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vp test&lt;/span&gt;
&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;vp run build&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That reduces the gap between:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"It works on my machine."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Why does CI use completely different commands?"&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  21. When Does This Actually Matter?
&lt;/h2&gt;

&lt;p&gt;If you're building a small personal website:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 app
5 components
1 package
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you probably won't notice a huge difference.&lt;/p&gt;

&lt;p&gt;You can happily use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp dev
vp &lt;span class="nb"&gt;test
&lt;/span&gt;vp build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and move on.&lt;/p&gt;

&lt;p&gt;But imagine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10 applications
30 packages
100 developers
hundreds of tasks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now task execution becomes a real engineering problem.&lt;/p&gt;

&lt;p&gt;You care about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What changed?&lt;/li&gt;
&lt;li&gt;What needs rebuilding?&lt;/li&gt;
&lt;li&gt;What can run in parallel?&lt;/li&gt;
&lt;li&gt;What can use a previous result?&lt;/li&gt;
&lt;li&gt;What should CI execute?&lt;/li&gt;
&lt;li&gt;How can local and CI workflows stay consistent?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's the environment where Vite Task and &lt;code&gt;vp run&lt;/code&gt; become much more important.&lt;/p&gt;




&lt;h2&gt;
  
  
  22. The Big Picture
&lt;/h2&gt;

&lt;p&gt;Let's compare the two situations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Small application
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Developer
   │
   ├── vp dev
   ├── vp check
   ├── vp test
   └── vp build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple.&lt;/p&gt;

&lt;h3&gt;
  
  
  Large monorepo
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                         Vite+
                           │
                    ┌──────┴──────┐
                    │             │
                  Local           CI
                    │             │
                  vp run        vp run
                    │             │
              ┌─────┴─────┐   ┌──┴───┐
              │           │   │      │
            Tasks      Cache  Tasks  Cache
              │           │   │      │
              └─────┬─────┘   └──┬───┘
                    │             │
                    └──────┬──────┘
                           │
                    Dependency graph
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where Vite+ starts looking less like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"A nicer command for Vite."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and more like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A unified development and task-execution environment for a modern JavaScript repository.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  23. Ssummary
&lt;/h2&gt;

&lt;p&gt;In this chapter, we moved from a single application to large repositories, the main concepts were:&lt;/p&gt;

&lt;h3&gt;
  
  
  Monorepos
&lt;/h3&gt;

&lt;p&gt;Multiple applications and packages living in one repository.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tasks
&lt;/h3&gt;

&lt;p&gt;Operations 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;build
test
lint
typecheck
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Dependency graphs
&lt;/h3&gt;

&lt;p&gt;Understanding which packages depend on which other packages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Caching
&lt;/h3&gt;

&lt;p&gt;Reusing previous task results when the relevant inputs haven't changed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Parallel execution
&lt;/h3&gt;

&lt;p&gt;Running independent tasks at the same time.&lt;/p&gt;

&lt;h3&gt;
  
  
  CI
&lt;/h3&gt;

&lt;p&gt;Using the same &lt;code&gt;vp&lt;/code&gt; workflow locally and in GitHub Actions.&lt;/p&gt;

&lt;p&gt;The important command to remember is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a small project, you might barely notice it.&lt;/p&gt;

&lt;p&gt;For a large monorepo, it can become one of the most important parts of the Vite+ workflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  What comes next ?
&lt;/h2&gt;

&lt;p&gt;We've now covered a lot of things, that leaves one big question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Should you actually use Vite+?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's easy to get excited about a new toolchain, but every tool has trade-offs.&lt;/p&gt;

&lt;p&gt;In next chapter; we'll look at:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When Vite+ makes sense&lt;/li&gt;
&lt;li&gt;When it might be unnecessary&lt;/li&gt;
&lt;li&gt;Migrating an existing project&lt;/li&gt;
&lt;li&gt;The benefits and trade-offs&lt;/li&gt;
&lt;li&gt;The beta/early-stage considerations&lt;/li&gt;
&lt;li&gt;How to decide whether Vite+ fits your project&lt;/li&gt;
&lt;li&gt;What to consider before adopting it in a team&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That will bring the series together and give you a practical answer to the question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Should I use Vite+?"&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>viteplus</category>
      <category>javascript</category>
      <category>vite</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Vite+ — Chapter 3: Vite+ in Practice</title>
      <dc:creator>Othmane Nemli</dc:creator>
      <pubDate>Fri, 25 Sep 2026 16:33:45 +0000</pubDate>
      <link>https://dev.to/othmane_nemli/vite-chapter-3-vite-in-practice-km7</link>
      <guid>https://dev.to/othmane_nemli/vite-chapter-3-vite-in-practice-km7</guid>
      <description>&lt;p&gt;In the previous chapter, we looked at &lt;strong&gt;&lt;a href="https://dev.to/othmane_nemli/vite-chapter-2-whats-inside-vite-1n2k"&gt;what Vite+ is made of&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We saw that Vite+ brings together tools such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vite&lt;/li&gt;
&lt;li&gt;Vitest&lt;/li&gt;
&lt;li&gt;Rolldown&lt;/li&gt;
&lt;li&gt;tsdown&lt;/li&gt;
&lt;li&gt;Oxlint&lt;/li&gt;
&lt;li&gt;Oxfmt&lt;/li&gt;
&lt;li&gt;Vite Task&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But knowing what these tools are is only half the story.&lt;/p&gt;

&lt;p&gt;The more interesting question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;What does developing a real project with Vite+ actually look like?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's what we'll explore in this chapter.&lt;/p&gt;

&lt;p&gt;We'll create a project, start the development server, run checks and tests, and finally create a production build.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Installing Vite+
&lt;/h2&gt;

&lt;p&gt;Vite+ provides a &lt;code&gt;vp&lt;/code&gt; command-line interface.&lt;/p&gt;

&lt;p&gt;The official beta installation method is different depending on your operating system.&lt;/p&gt;

&lt;h3&gt;
  
  
  macOS / Linux
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://vite.plus | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Windows
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;irm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https://vite.plus/ps1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After installation, you can check that the command is available:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should now have access to the &lt;code&gt;vp&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;Think of &lt;code&gt;vp&lt;/code&gt; as the main doorway into your JavaScript project.&lt;/p&gt;

&lt;p&gt;Instead of remembering which tool should handle each part of your workflow, you can use the same command-line interface.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Creating a New Project
&lt;/h2&gt;

&lt;p&gt;Let's create our first Vite+ project.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Interactive mode&lt;/span&gt;
vp create
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vite+ ships with these built-in templates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp vite:monorepo &lt;span class="c"&gt;#creates a new monorepo&lt;/span&gt;
vp vite:application &lt;span class="c"&gt;#creates a new application&lt;/span&gt;
vp vite:library &lt;span class="c"&gt;#creates a new library&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://viteplus.dev/guide/create#examples" rel="noopener noreferrer"&gt;For more examples&lt;/a&gt; and options&lt;/p&gt;

&lt;p&gt;Vite+ will guide you through creating a project from a template.&lt;/p&gt;

&lt;p&gt;Once the project has been created, move into it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;my-project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The exact project name depends on what you choose during the creation process.&lt;/p&gt;

&lt;p&gt;At this point, you have a project that can use the Vite+ workflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Installing Dependencies
&lt;/h2&gt;

&lt;p&gt;Normally, JavaScript developers might use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm/pnpm/yarn/bun &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vite+ provides its own entry point for this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="c"&gt;# this command will be executed automatically by vp&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vite+ can work with different package managers and can detect the package-manager setup used by the project.&lt;/p&gt;

&lt;p&gt;This is one of the ideas behind Vite+:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You don't necessarily need to change the underlying tools. Vite+ provides a consistent interface over them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So the goal isn't:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Everyone must stop using npm."&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The goal is closer to:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"Developers shouldn't need to care which command is responsible for every individual part of the workflow."&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Starting the Development Server
&lt;/h2&gt;

&lt;p&gt;Now let's start developing.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Under the hood, this uses Vite's development server.&lt;/p&gt;

&lt;p&gt;You'll get the familiar Vite development experience, including fast module updates when you change your source code.&lt;/p&gt;

&lt;p&gt;By default the project comes with a counter componenent&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apps/website/src
├── counter.ts
├── main.tsx
└── styles.css
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Edit &lt;code&gt;main.tsx&lt;/code&gt;:&lt;br&gt;
change "Get started" by "Welcome Vite+" and save the file&lt;/p&gt;

&lt;p&gt;Your browser updates without requiring you to manually rebuild the whole application.&lt;/p&gt;

&lt;p&gt;That's the Vite experience you already know.&lt;/p&gt;

&lt;p&gt;Vite+ doesn't try to replace that experience.&lt;/p&gt;

&lt;p&gt;It gives you a consistent command for accessing it:&lt;a href="https://viteplus.dev/guide/dev" rel="noopener noreferrer"&gt;vp dev&lt;/a&gt;&lt;/p&gt;


&lt;h2&gt;
  
  
  5. Checking Your Code
&lt;/h2&gt;

&lt;p&gt;Now let's say you've written some code.&lt;/p&gt;

&lt;p&gt;Before committing it, you usually want to check:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Is the code formatted?&lt;/li&gt;
&lt;li&gt;Are there lint errors?&lt;/li&gt;
&lt;li&gt;Are there type errors?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Traditionally, you might have several commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run format
npm run lint
npm run typecheck
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With Vite+, these checks can be combined:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The current Vite+ workflow combines formatting, linting, and type checking.&lt;/p&gt;

&lt;p&gt;So instead of remembering three different commands, your workflow can become:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's a small difference for a small project.&lt;/p&gt;

&lt;p&gt;But imagine a team with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;10 developers&lt;/li&gt;
&lt;li&gt;20 repositories&lt;/li&gt;
&lt;li&gt;several applications&lt;/li&gt;
&lt;li&gt;shared packages&lt;/li&gt;
&lt;li&gt;CI pipelines&lt;/li&gt;
&lt;li&gt;multiple environments&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A consistent command becomes much more useful.&lt;/p&gt;

&lt;p&gt;More info &lt;a href="https://viteplus.dev/guide/check" rel="noopener noreferrer"&gt;vp check&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Running Tests
&lt;/h2&gt;

&lt;p&gt;Let's say we have a test:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;it&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="s1"&gt;vitest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nf"&gt;describe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;addition&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;adds two numbers&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&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="nf"&gt;toBe&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="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Normally, you might run Vitest directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vitest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With Vite+:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vite+ runs the tests through Vitest.&lt;/p&gt;

&lt;p&gt;Again, notice the pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Development → vp dev
Checks       → vp check
Tests        → vp test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You don't need to memorize which underlying tool powers each command.&lt;/p&gt;

&lt;p&gt;You just learn the Vite+ workflow. more info &lt;a href="https://viteplus.dev/guide/test" rel="noopener noreferrer"&gt;vp test&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  7. Building for Production
&lt;/h2&gt;

&lt;p&gt;When your application is ready to deploy, you need a production build.&lt;/p&gt;

&lt;p&gt;With Vite+, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fablaupmakvlj3hphgu43.png" class="article-body-image-wrapper"&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.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fablaupmakvlj3hphgu43.png" alt="vp Build" width="748" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The application is built for production using Vite and Rolldown.&lt;/p&gt;

&lt;p&gt;The important distinction is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vp dev
   ↓
Development environment

vp build
   ↓
Production build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During development, you want speed and fast feedback.&lt;/p&gt;

&lt;p&gt;During production, you want optimized output that can be deployed.&lt;/p&gt;

&lt;p&gt;Vite+ gives you a consistent interface for both.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Previewing the Production Build
&lt;/h2&gt;

&lt;p&gt;After building the application, you can preview the result with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp preview
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This lets you check the production build locally before deploying it.&lt;/p&gt;

&lt;p&gt;A simple workflow could therefore look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Develop your application.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the code.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the tests.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp build
vp preview
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://viteplus.dev/guide/build" rel="noopener noreferrer"&gt;Build and preview&lt;/a&gt; the production version.&lt;/p&gt;




&lt;h2&gt;
  
  
  9. The Workflow Starts to Look Different
&lt;/h2&gt;

&lt;p&gt;At this point, we can summarize the basic workflow:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What you want to do&lt;/th&gt;
&lt;th&gt;Vite+ command&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Create a project&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vp create&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Install dependencies&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vp install&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Start development&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vp dev&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Check code&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vp check&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Run tests&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vp test&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build for production&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vp build&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Preview production&lt;/td&gt;
&lt;td&gt;&lt;code&gt;vp preview&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;This is where the idea behind Vite+ becomes easier to understand.&lt;/p&gt;

&lt;p&gt;It isn't about replacing every individual tool.&lt;/p&gt;

&lt;p&gt;It's about creating a &lt;strong&gt;consistent interface&lt;/strong&gt; for the development workflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  10. What About Existing Projects?
&lt;/h2&gt;

&lt;p&gt;You might be thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"This sounds nice, but I already have a project."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's an important use case.&lt;/p&gt;

&lt;p&gt;Vite+ provides:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is intended to help &lt;a href="https://viteplus.dev/guide/migrate" rel="noopener noreferrer"&gt;migrate&lt;/a&gt; an existing project to the Vite+ workflow.&lt;/p&gt;

&lt;p&gt;For example, imagine an existing project already has:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-app/
├── package.json
├── vite.config.ts
├── vitest.config.ts
├── eslint.config.js
├── prettier.config.js
└── src/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of creating everything again, you can run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vite+ can bring parts of the existing configuration into its unified setup.&lt;/p&gt;

&lt;p&gt;The current migration process shows what it plans to change, but complex projects may still require manual follow-up. The official documentation recommends reviewing the migration guide before using it on a production project.&lt;/p&gt;

&lt;p&gt;So migration should not be thought of as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Run one command and everything magically changes."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's better to think of it as:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Vite+ helps you move an existing project toward the unified workflow."&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  11. One Configuration File
&lt;/h2&gt;

&lt;p&gt;Another interesting part of Vite+ is configuration.&lt;/p&gt;

&lt;p&gt;A Vite+ project can use &lt;code&gt;vite.config.ts&lt;/code&gt; as the central configuration point.&lt;/p&gt;

&lt;p&gt;For 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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineConfig&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="s1"&gt;vite-plus&lt;/span&gt;&lt;span class="dl"&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="nf"&gt;defineConfig&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;

  &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;include&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;src/**/*.test.ts&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;lint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;ignorePatterns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;dist/**&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;fmt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;semi&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;span class="na"&gt;singleQuote&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;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;Notice what is happening here.&lt;/p&gt;

&lt;p&gt;The same configuration can contain settings for different parts of the development workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vite.config.ts
      │
      ├── Vite
      ├── Vitest
      ├── Oxlint
      ├── Oxfmt
      └── Vite Task
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The goal is to reduce the number of separate configuration files you need to understand and maintain. The Vite+ repository documents this unified configuration approach.&lt;/p&gt;

&lt;p&gt;For me, I prefer to use separate files, for readability and quick access.&lt;/p&gt;




&lt;h2&gt;
  
  
  12. And Then There's &lt;code&gt;vp run&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;So far, we've looked at the obvious commands.&lt;/p&gt;

&lt;p&gt;But one command becomes especially interesting when a project grows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://viteplus.dev/guide/run" rel="noopener noreferrer"&gt;vp run&lt;/a&gt; can execute &lt;code&gt;package.json&lt;/code&gt; scripts and Vite Task workflows, including dependency-aware task execution and caching.&lt;/p&gt;

&lt;p&gt;Imagine a monorepo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-company/
├── apps/
│   ├── web/
│   └── admin/
│
└── packages/
    ├── ui/
    ├── utils/
    └── config/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now imagine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;web
 ↓
ui
 ↓
utils
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;utils&lt;/code&gt; changes, some tasks need to run again.&lt;/p&gt;

&lt;p&gt;But if nothing relevant changed, running everything again wastes time.&lt;/p&gt;

&lt;p&gt;This is where task caching becomes useful.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vite+ can understand task relationships and reuse cached results where appropriate.&lt;/p&gt;

&lt;p&gt;That's much more interesting in large repositories than in a tiny demo application.&lt;/p&gt;

&lt;p&gt;And that leads directly into the next stage of our series.&lt;/p&gt;

&lt;h4&gt;
  
  
  Note:
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;vpr&lt;/code&gt; is available as a standalone shorthand for &lt;code&gt;vp run&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  13. A Realistic Daily Workflow
&lt;/h2&gt;

&lt;p&gt;After everything we've seen, a developer's day might look something like this:&lt;/p&gt;

&lt;h3&gt;
  
  
  Start working
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Make changes
&lt;/h3&gt;

&lt;p&gt;Write your application code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check everything
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Run tests
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Build before deployment
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Preview the result
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp preview
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The commands are simple.&lt;/p&gt;

&lt;p&gt;That's intentional.&lt;/p&gt;

&lt;p&gt;The complexity is moved away from remembering dozens of unrelated commands and toward having one consistent toolchain.&lt;/p&gt;




&lt;h2&gt;
  
  
  14. The Bigger Picture
&lt;/h2&gt;

&lt;p&gt;Let's step back for a moment.&lt;/p&gt;

&lt;p&gt;Without a unified workflow, you might have something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm
 │
 ├── Vite
 ├── Vitest
 ├── ESLint
 ├── Prettier
 ├── TypeScript
 ├── task runner
 └── package scripts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With Vite+:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                 Vite+
                   │
       ┌───────────┼───────────┐
       │           │           │
     Build       Test        Check
       │           │           │
     Vite       Vitest     Oxlint/Oxfmt
       │
    Rolldown
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The underlying technologies are still there.&lt;/p&gt;

&lt;p&gt;What's different is the way you interact with them.&lt;/p&gt;

&lt;p&gt;Instead of thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which tool handles this?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;you can increasingly think:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which &lt;code&gt;vp&lt;/code&gt; command handles this?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's the central idea of Vite+ in practice.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Next?
&lt;/h2&gt;

&lt;p&gt;In &lt;strong&gt;Chapter 4&lt;/strong&gt;, we'll move beyond a single application.&lt;/p&gt;

&lt;p&gt;We'll look at &lt;strong&gt;Vite+ at scale&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Monorepos&lt;/li&gt;
&lt;li&gt;Task dependencies&lt;/li&gt;
&lt;li&gt;Caching&lt;/li&gt;
&lt;li&gt;Parallel execution&lt;/li&gt;
&lt;li&gt;CI/CD&lt;/li&gt;
&lt;li&gt;Shared configuration&lt;/li&gt;
&lt;li&gt;Why &lt;code&gt;vp run&lt;/code&gt; becomes much more valuable as a repository grows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's where Vite+ starts solving problems that are difficult to see in a small project.&lt;/p&gt;

</description>
      <category>viteplus</category>
      <category>frontend</category>
      <category>javascript</category>
      <category>web</category>
    </item>
    <item>
      <title>Vite+ — Chapter 2: What’s Inside Vite+?</title>
      <dc:creator>Othmane Nemli</dc:creator>
      <pubDate>Fri, 25 Sep 2026 15:09:36 +0000</pubDate>
      <link>https://dev.to/othmane_nemli/vite-chapter-2-whats-inside-vite-1n2k</link>
      <guid>https://dev.to/othmane_nemli/vite-chapter-2-whats-inside-vite-1n2k</guid>
      <description>&lt;p&gt;In the first chapter, we looked at &lt;strong&gt;&lt;a href="https://dev.to/othmane_nemli/vite-chapter-1-why-do-we-need-another-javascript-tool-13l"&gt;why Vite+ exists&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The short version was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Modern JavaScript projects use many excellent tools, but connecting and maintaining all those tools can become complicated.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Vite+ tries to bring several of those tools together behind one workflow.&lt;/p&gt;

&lt;p&gt;But this raises another question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is actually inside Vite+?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp dev
vp &lt;span class="nb"&gt;test
&lt;/span&gt;vp check
vp build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;what happens behind those commands?&lt;/p&gt;

&lt;p&gt;Let's open the toolbox.&lt;/p&gt;




&lt;h2&gt;
  
  
  Vite+ is not one giant tool
&lt;/h2&gt;

&lt;p&gt;The first thing to understand is that Vite+ isn't a single replacement for everything.&lt;/p&gt;

&lt;p&gt;It brings together several tools, each with a specific job.&lt;/p&gt;

&lt;p&gt;A simplified view 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;                    Vite+
                      |
       +--------------+--------------+
       |              |              |
   Development      Quality        Testing
       |              |              |
      Vite       Oxlint / Oxfmt   Vitest
       |
    Building
       |
   Rolldown

       +-----------------------------+
       |
    Libraries
       |
    tsdown

       +-----------------------------+
       |
     Tasks
       |
   Vite Task
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each tool solves a different problem.&lt;/p&gt;

&lt;p&gt;The important part is that Vite+ gives you a consistent way to work with them.&lt;/p&gt;

&lt;p&gt;Let's go through them one by one.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Vite — Development
&lt;/h2&gt;

&lt;p&gt;Let's start with the tool most developers already know.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vite&lt;/strong&gt; is primarily a development server and build tool.&lt;/p&gt;

&lt;p&gt;If you're building a React application, for example, you might have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├── App.tsx
├── main.tsx
└── components/
    └── Button.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You want to write code and immediately see the result in your browser.&lt;/p&gt;

&lt;p&gt;That's where Vite comes in.&lt;/p&gt;

&lt;p&gt;You can start your development server with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Under the hood, Vite is doing the work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is Vite useful?
&lt;/h3&gt;

&lt;p&gt;Imagine you change:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Button&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&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;p&gt;to:&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="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;Button&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="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Hello World&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&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;p&gt;You don't want to stop the server, rebuild the entire application, and restart the browser every time you change a line.&lt;/p&gt;

&lt;p&gt;Vite provides a fast development experience with features such as &lt;strong&gt;Hot Module Replacement (HMR)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In simple terms:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;You change code
      ↓
Vite notices
      ↓
Browser updates
      ↓
You keep working
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is why Vite has become such a common part of modern frontend development.&lt;/p&gt;

&lt;p&gt;With Vite+, you still get Vite.&lt;/p&gt;

&lt;p&gt;Vite+ doesn't replace it.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Vitest — Testing
&lt;/h2&gt;

&lt;p&gt;Writing code is only half of the job.&lt;/p&gt;

&lt;p&gt;We also need to make sure it works.&lt;/p&gt;

&lt;p&gt;That's where &lt;strong&gt;Vitest&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;Suppose you have this function:&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;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&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;b&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="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;b&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;You could write a test:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;test&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;vitest&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;adds two numbers&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;expect&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="mi"&gt;2&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="nf"&gt;toBe&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="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vite+ uses Vitest as its testing tool.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Vitest instead of something else?
&lt;/h3&gt;

&lt;p&gt;You might already know tools such as Jest.&lt;/p&gt;

&lt;p&gt;The important thing here isn't to decide which test runner is "the best."&lt;/p&gt;

&lt;p&gt;The interesting part is that Vitest works very naturally with the Vite ecosystem.&lt;/p&gt;

&lt;p&gt;That means your development and testing environments can share much of the same configuration and behavior.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Development
     ↓
   Vite

Testing
     ↓
  Vitest

        ↓
Shared ecosystem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This integration is one of the reasons Vitest fits naturally into Vite+.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Rolldown — Bundling
&lt;/h2&gt;

&lt;p&gt;Now we get to a term that can sound intimidating:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;bundler&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Don't worry. The idea is simple.&lt;/p&gt;

&lt;p&gt;Your application might contain hundreds or thousands of files:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;src/
├── main.ts
├── App.tsx
├── components/
│   ├── Button.tsx
│   ├── Modal.tsx
│   └── Header.tsx
├── utils/
│   ├── date.ts
│   └── format.ts
└── ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser doesn't necessarily need to receive all those files exactly as they exist in your source code.&lt;/p&gt;

&lt;p&gt;A bundler analyzes the relationships between your files and produces optimized output for production.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your source code
       ↓
    Bundler
       ↓
Production files
       ↓
     Browser
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Traditionally, Vite has used Rollup for production builds.&lt;/p&gt;

&lt;p&gt;Vite+ includes &lt;strong&gt;Rolldown&lt;/strong&gt;, a newer bundler written in Rust and designed to provide a high-performance bundling foundation for the Vite ecosystem.&lt;/p&gt;

&lt;p&gt;You don't necessarily need to interact with Rolldown directly.&lt;/p&gt;

&lt;p&gt;You can simply run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and let the toolchain handle it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does a bundler matter?
&lt;/h3&gt;

&lt;p&gt;Imagine your application has:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;10,000 lines of source code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You don't want to manually decide:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which files should be included?"&lt;/p&gt;

&lt;p&gt;"Which modules depend on each other?"&lt;/p&gt;

&lt;p&gt;"Can these files be combined?"&lt;/p&gt;

&lt;p&gt;"Can unused code be removed?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The bundler handles these kinds of problems.&lt;/p&gt;

&lt;p&gt;It builds a dependency graph:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;App
├── Header
├── Dashboard
│   ├── Chart
│   └── Table
└── Utils
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then it can produce optimized output.&lt;/p&gt;

&lt;p&gt;This is one of the areas where build performance becomes important, especially for large projects.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. tsdown — Building libraries
&lt;/h2&gt;

&lt;p&gt;Applications aren't the only thing developers build.&lt;/p&gt;

&lt;p&gt;Sometimes you're creating a library.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-ui-library
my-auth-library
my-api-client
my-utils
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Suppose you have:&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;formatDate&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="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You want other developers to install your package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;my-utils
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now your build process has different requirements.&lt;/p&gt;

&lt;p&gt;You may need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript output&lt;/li&gt;
&lt;li&gt;TypeScript declarations&lt;/li&gt;
&lt;li&gt;different module formats&lt;/li&gt;
&lt;li&gt;package metadata&lt;/li&gt;
&lt;li&gt;optimized output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where &lt;strong&gt;tsdown&lt;/strong&gt; comes into the Vite+ ecosystem.&lt;/p&gt;

&lt;p&gt;You can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp pack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to package a library.&lt;/p&gt;

&lt;p&gt;The important distinction is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Application
    ↓
vp build

Library
    ↓
vp pack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The two workflows have different goals.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. Oxlint — Linting
&lt;/h2&gt;

&lt;p&gt;Now let's talk about code quality.&lt;/p&gt;

&lt;p&gt;Imagine someone writes:&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;getUser&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;user&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;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&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 code might work.&lt;/p&gt;

&lt;p&gt;But there may be problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;unused variables&lt;/li&gt;
&lt;li&gt;suspicious patterns&lt;/li&gt;
&lt;li&gt;accidental bugs&lt;/li&gt;
&lt;li&gt;inconsistent code&lt;/li&gt;
&lt;li&gt;practices your team doesn't allow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A &lt;strong&gt;linter&lt;/strong&gt; looks for these kinds of issues.&lt;/p&gt;

&lt;p&gt;Vite+ uses &lt;strong&gt;Oxlint&lt;/strong&gt; for linting.&lt;/p&gt;

&lt;p&gt;You can think of it as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Your code
   ↓
Oxlint
   ↓
Potential problems
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can include linting as part of the overall project check.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why another linter?
&lt;/h3&gt;

&lt;p&gt;You might be thinking:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"But we already have ESLint."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Yes.&lt;/p&gt;

&lt;p&gt;ESLint is still widely used and has a huge ecosystem.&lt;/p&gt;

&lt;p&gt;Oxlint takes a different approach and focuses heavily on performance.&lt;/p&gt;

&lt;p&gt;It is part of the broader &lt;strong&gt;Oxc&lt;/strong&gt; toolchain and is written in Rust.&lt;/p&gt;

&lt;p&gt;For Vite+, the important idea is not:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"ESLint is bad."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It's:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"What if common development tooling could be extremely fast and integrated into one toolchain?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That's the philosophy behind choosing tools such as Oxlint.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. Oxfmt — Formatting
&lt;/h2&gt;

&lt;p&gt;Linting and formatting are related, but they aren't the same thing.&lt;/p&gt;

&lt;p&gt;A linter asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Is there something potentially wrong with this code?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A formatter asks:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Can we make the code follow a consistent style?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example, these are functionally similar:&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;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&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;and:&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;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But most teams want everyone to use the same formatting rules.&lt;/p&gt;

&lt;p&gt;That's where &lt;strong&gt;Oxfmt&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;You can think of it as the formatting part of the workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Source code
    ↓
Oxfmt
    ↓
Consistent formatting
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, this is similar to what developers have traditionally used Prettier for.&lt;/p&gt;




&lt;h2&gt;
  
  
  Linting vs formatting
&lt;/h2&gt;

&lt;p&gt;If you're new to frontend development, this distinction is worth remembering.&lt;/p&gt;

&lt;h3&gt;
  
  
  Formatting
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"Make the code look consistent."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Example:&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;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;becomes:&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;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;John&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;h3&gt;
  
  
  Linting
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;"Look for patterns that might be problematic."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For example:&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;unusedVariable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A linter can tell you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;unusedVariable is never used
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Oxfmt  → How the code looks

Oxlint → Potential problems in the code
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both can be part of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  7. Vite Task — Running tasks
&lt;/h2&gt;

&lt;p&gt;Now we get to a part that becomes more interesting as your project grows.&lt;/p&gt;

&lt;p&gt;Most projects have tasks.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;build
test
lint
typecheck
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You might define them in &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"..."&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a small project, that's enough.&lt;/p&gt;

&lt;p&gt;But imagine a monorepo with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apps/
  web/
  admin/

packages/
  ui/
  auth/
  utils/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now tasks have relationships.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ui
 ↓
web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the UI package changes, the web application may need to be rebuilt.&lt;/p&gt;

&lt;p&gt;This is where a task runner becomes useful.&lt;/p&gt;

&lt;p&gt;Vite+ includes &lt;strong&gt;Vite Task&lt;/strong&gt; for task execution and caching.&lt;/p&gt;




&lt;h2&gt;
  
  
  Task dependencies
&lt;/h2&gt;

&lt;p&gt;Let's make this concrete.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;packages/ui
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is used by:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apps/web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;packages/ui/Button.tsx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The dependency graph is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ui
 ↓
web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A smart task runner can understand:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The web application depends on UI, so the web build may need to run."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But suppose another package didn't change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;packages/utils
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If nothing relevant changed there, rebuilding everything may be unnecessary.&lt;/p&gt;

&lt;p&gt;That's where task graphs and caching become useful.&lt;/p&gt;




&lt;h2&gt;
  
  
  Caching
&lt;/h2&gt;

&lt;p&gt;Caching sounds complicated, but the basic idea is very simple.&lt;/p&gt;

&lt;p&gt;Imagine you run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The build takes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;30 seconds
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You run it again without changing anything.&lt;/p&gt;

&lt;p&gt;Why should you spend another 30 seconds doing exactly the same work?&lt;/p&gt;

&lt;p&gt;A cache can remember the previous result.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;First run:

Source
  ↓
Build
  ↓
Result
  ↓
Cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Second run:

Source
  ↓
Anything relevant changed?
  ↓
No
  ↓
Reuse result
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This becomes particularly valuable in large repositories and CI.&lt;/p&gt;

&lt;p&gt;We'll go much deeper into this in Chapter 4.&lt;/p&gt;




&lt;h2&gt;
  
  
  8. Runtime and package management
&lt;/h2&gt;

&lt;p&gt;There's another part of the developer experience that is easy to overlook:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;the environment itself.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A project might expect:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Node.js 22
pnpm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;while another project expects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Node.js 20
npm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Vite+ also provides commands and workflows for managing the runtime and package manager environment.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp &lt;span class="nb"&gt;env&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can be used as part of this workflow.&lt;/p&gt;

&lt;p&gt;The goal is to make the environment used by the project more explicit and reproducible.&lt;/p&gt;

&lt;p&gt;This matters because:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Works on my machine."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;is one of the oldest problems in software development.&lt;/p&gt;




&lt;h2&gt;
  
  
  Putting the pieces together
&lt;/h2&gt;

&lt;p&gt;Now we can see what sits behind the simple &lt;code&gt;vp&lt;/code&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;                         Vite+
                           |
        +------------------+------------------+
        |                  |                  |
    Development         Quality            Testing
        |                  |                  |
       Vite         Oxlint + Oxfmt         Vitest
        |
     Building
        |
    Rolldown

        |
    Libraries
        |
     tsdown

        |
      Tasks
        |
   Vite Task
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of learning every tool separately on day one, you can interact with them through a common workflow.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ development&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ testing&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ code quality&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ production build&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp pack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ library packaging&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;→ project tasks&lt;/p&gt;




&lt;h2&gt;
  
  
  But should you care which tool is underneath?
&lt;/h2&gt;

&lt;p&gt;Yes.&lt;/p&gt;

&lt;p&gt;Even though Vite+ gives you a unified interface, you shouldn't treat it as magic.&lt;/p&gt;

&lt;p&gt;If something goes wrong with your tests, knowing that Vite+ uses Vitest helps you investigate.&lt;/p&gt;

&lt;p&gt;If your build has an issue, understanding Vite and Rolldown helps.&lt;/p&gt;

&lt;p&gt;If linting reports something unexpected, knowing that Oxlint is involved gives you a direction for debugging.&lt;/p&gt;

&lt;p&gt;This is especially important for senior developers.&lt;/p&gt;

&lt;p&gt;A good abstraction hides unnecessary complexity.&lt;/p&gt;

&lt;p&gt;It shouldn't hide useful knowledge.&lt;/p&gt;




&lt;h2&gt;
  
  
  The important mental model
&lt;/h2&gt;

&lt;p&gt;Don't think:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Vite+ = one giant replacement for everything
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Vite+ = an integrated workflow

             ↓

     +-------+-------+
     |       |       |
    Vite   Vitest  Oxlint
     |       |       |
 Rolldown  Tests   Oxfmt
     |
   tsdown
     |
 Vite Task
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each component has a job.&lt;/p&gt;

&lt;p&gt;Vite+ connects those components.&lt;/p&gt;




&lt;h2&gt;
  
  
  What we've learned
&lt;/h2&gt;

&lt;p&gt;At this point, you don't need to remember every detail.&lt;/p&gt;

&lt;p&gt;Just remember this:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Simple explanation&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Vite&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Develop and build web applications&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Vitest&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Test your code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Rolldown&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Bundle your application&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;tsdown&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Package libraries&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Oxlint&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Find potential code problems&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Oxfmt&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Format your code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Vite Task&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Run tasks and reuse cached results&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;And Vite+ provides the common workflow around them.&lt;/p&gt;




&lt;h2&gt;
  
  
  One last question
&lt;/h2&gt;

&lt;p&gt;Now that we know what's inside Vite+, there's still a practical question:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What does using it actually feel like?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It's one thing to read:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp dev
vp &lt;span class="nb"&gt;test
&lt;/span&gt;vp check
vp build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's another thing to create a project and use those commands yourself.&lt;/p&gt;

&lt;p&gt;So in the next chapter, we'll stop talking about the pieces individually.&lt;/p&gt;

&lt;p&gt;We'll build something.&lt;/p&gt;

&lt;p&gt;We'll look at:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a project
      ↓
Install dependencies
      ↓
Start development
      ↓
Write code
      ↓
Run tests
      ↓
Check the project
      ↓
Build for production
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's where Vite+ starts becoming something you can actually use rather than just something you understand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next chapter: Vite+ in Practice — From Your First Project to Production&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>frontend</category>
      <category>viteplus</category>
      <category>web</category>
    </item>
    <item>
      <title>Vite+ — Chapter 1: Why Do We Need Another JavaScript Tool?</title>
      <dc:creator>Othmane Nemli</dc:creator>
      <pubDate>Thu, 24 Sep 2026 10:53:45 +0000</pubDate>
      <link>https://dev.to/othmane_nemli/vite-chapter-1-why-do-we-need-another-javascript-tool-13l</link>
      <guid>https://dev.to/othmane_nemli/vite-chapter-1-why-do-we-need-another-javascript-tool-13l</guid>
      <description>&lt;p&gt;If you've worked with modern JavaScript projects, you've probably seen a &lt;code&gt;package.json&lt;/code&gt; that looks something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"dev"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vite"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vite build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"test"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vitest"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"lint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"oxlint"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"format"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"oxfmt"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"typecheck"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"tsc --noEmit"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At first, this doesn't look complicated.&lt;/p&gt;

&lt;p&gt;You have a command for development, one for building, one for testing, and a few for keeping the code clean.&lt;/p&gt;

&lt;p&gt;But there's something hiding behind these commands.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your project is now depending on several different tools, configurations, versions, and conventions.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And that's the problem Vite+ is trying to address.&lt;/p&gt;




&lt;h2&gt;
  
  
  The JavaScript toolchain keeps growing
&lt;/h2&gt;

&lt;p&gt;Let's say you're starting a new TypeScript application.&lt;/p&gt;

&lt;p&gt;You might begin with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TypeScript
Vite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you want tests:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TypeScript
Vite
Vitest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You add linting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TypeScript
Vite
Vitest
Oxlint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then formatting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TypeScript
Vite
Vitest
Oxlint
Oxfmt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then perhaps you have a monorepo:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apps/
  web/
  admin/

packages/
  ui/
  utils/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you also need to think about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How should packages depend on each other?&lt;/li&gt;
&lt;li&gt;Which tasks need to run first?&lt;/li&gt;
&lt;li&gt;Can some tasks run in parallel?&lt;/li&gt;
&lt;li&gt;Can completed tasks be cached?&lt;/li&gt;
&lt;li&gt;What should CI run?&lt;/li&gt;
&lt;li&gt;Which Node.js version should everyone use?&lt;/li&gt;
&lt;li&gt;Which package manager should the repository use?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these problems are particularly new.&lt;/p&gt;

&lt;p&gt;But together, they create something we don't always talk about:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;toolchain complexity.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The tools aren't the problem
&lt;/h2&gt;

&lt;p&gt;This is important.&lt;/p&gt;

&lt;p&gt;Vite isn't the problem.&lt;/p&gt;

&lt;p&gt;Vitest isn't the problem.&lt;/p&gt;

&lt;p&gt;Oxlint isn't the problem.&lt;/p&gt;

&lt;p&gt;Your package manager isn't the problem.&lt;/p&gt;

&lt;p&gt;In fact, these tools exist because they solve real problems.&lt;/p&gt;

&lt;p&gt;The issue is that &lt;strong&gt;we have to connect them ourselves&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Think about a typical development workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Development
    ↓
Vite

Testing
    ↓
Vitest

Linting
    ↓
Oxlint

Formatting
    ↓
Oxfmt

Building
    ↓
Vite / Rolldown

Library packaging
    ↓
tsdown

Tasks
    ↓
Task runner

Runtime + packages
    ↓
Node + npm/pnpm/Yarn/Bun
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each piece makes sense on its own.&lt;/p&gt;

&lt;p&gt;But someone has to make the whole thing work together.&lt;/p&gt;

&lt;p&gt;That "someone" is usually the development team.&lt;/p&gt;




&lt;h2&gt;
  
  
  What happens when the project grows?
&lt;/h2&gt;

&lt;p&gt;Imagine a small team with five developers.&lt;/p&gt;

&lt;p&gt;The project is simple.&lt;/p&gt;

&lt;p&gt;Everyone knows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run dev
npm run &lt;span class="nb"&gt;test
&lt;/span&gt;npm run lint
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No big deal.&lt;/p&gt;

&lt;p&gt;Now the team grows.&lt;/p&gt;

&lt;p&gt;The project becomes a monorepo.&lt;/p&gt;

&lt;p&gt;You have multiple applications and shared packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-company/
├── apps/
│   ├── web/
│   └── admin/
│
└── packages/
    ├── ui/
    ├── auth/
    └── utils/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now running everything becomes more complicated.&lt;/p&gt;

&lt;p&gt;Maybe &lt;code&gt;web&lt;/code&gt; depends on &lt;code&gt;ui&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ui
 ↓
web
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;ui&lt;/code&gt; changes, &lt;code&gt;web&lt;/code&gt; may need to be rebuilt.&lt;/p&gt;

&lt;p&gt;But if &lt;code&gt;auth&lt;/code&gt; didn't change, why should everything related to &lt;code&gt;auth&lt;/code&gt; run again?&lt;/p&gt;

&lt;p&gt;Now you're thinking about:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;task dependencies
caching
parallel execution
CI performance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is where the development toolchain starts becoming a project of its own.&lt;/p&gt;




&lt;h2&gt;
  
  
  And then there's CI
&lt;/h2&gt;

&lt;p&gt;Your local machine might run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm run &lt;span class="nb"&gt;test
&lt;/span&gt;npm run lint
npm run build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But your CI pipeline needs to do the same thing.&lt;/p&gt;

&lt;p&gt;So now you have another layer of configuration.&lt;/p&gt;

&lt;p&gt;Your repository might contain:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package.json
vite.config.ts
vitest.config.ts
eslint.config.js
prettier.config.js
.github/workflows/...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, this is perfectly normal.&lt;/p&gt;

&lt;p&gt;But every additional configuration file is another thing developers need to understand and maintain.&lt;/p&gt;

&lt;p&gt;And sometimes your local environment and CI don't behave exactly the same.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Local:
Node 22

CI:
Node 20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or perhaps developers use pnpm while another repository uses npm.&lt;/p&gt;

&lt;p&gt;The tools themselves aren't necessarily difficult.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The integration is.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  So, what is Vite+?
&lt;/h2&gt;

&lt;p&gt;This is where Vite+ comes in.&lt;/p&gt;

&lt;p&gt;Vite+ is designed as a &lt;strong&gt;unified toolchain for web development&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of assembling your development environment piece by piece, Vite+ brings several tools together behind a single &lt;code&gt;vp&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;starts development.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;runs tests.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;runs formatting, linting, and type checking.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;builds the project.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;handles project tasks, including dependency-aware execution and caching.&lt;/p&gt;

&lt;p&gt;The goal is not simply to give you shorter commands.&lt;/p&gt;

&lt;p&gt;The bigger idea is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Give developers one consistent workflow for the things they do every day.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Is Vite+ just a new Vite?
&lt;/h2&gt;

&lt;p&gt;No.&lt;/p&gt;

&lt;p&gt;This is probably the most important thing to understand before continuing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vite and Vite+ are different things.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Vite is primarily a development server and build tool.&lt;/p&gt;

&lt;p&gt;Vite+ is a broader toolchain that brings together several technologies, including:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Vite
Vitest
Rolldown
tsdown
Oxlint
Oxfmt
Vite Task
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It also manages runtime and package-manager workflows.&lt;/p&gt;

&lt;p&gt;You can think about it 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;Vite
  ↓
Development + application build


Vite+
  ↓
Development
Testing
Linting
Formatting
Building
Library packaging
Task execution
Caching
Runtime/package management
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So Vite+ isn't replacing Vite.&lt;/p&gt;

&lt;p&gt;It is building a larger workflow around it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why not just keep using separate tools?
&lt;/h2&gt;

&lt;p&gt;That's a completely reasonable question.&lt;/p&gt;

&lt;p&gt;And honestly, you might not need Vite+.&lt;/p&gt;

&lt;p&gt;If your project is small, stable, and your team is happy with its current setup, there may be little reason to change it.&lt;/p&gt;

&lt;p&gt;The interesting question is what happens when you have to maintain this setup across many projects.&lt;/p&gt;

&lt;p&gt;Imagine having:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Project A
  Vite
  Vitest
  ESLint
  Prettier

Project B
  Vite
  Jest
  ESLint
  Prettier

Project C
  Vite
  Vitest
  Oxlint
  Oxfmt
  Turborepo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now developers need to remember different commands and different conventions depending on the repository.&lt;/p&gt;

&lt;p&gt;Vite+ is trying to reduce that variation.&lt;/p&gt;

&lt;p&gt;Its documentation describes the goal as avoiding the need for developers to repeatedly assemble their toolchain by hand and giving teams a more consistent setup across projects.&lt;/p&gt;




&lt;h2&gt;
  
  
  A simple mental model
&lt;/h2&gt;

&lt;p&gt;Here's the easiest way I currently think about Vite+:&lt;/p&gt;

&lt;p&gt;Without Vite+:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        You
         |
   ----------------
   |   |   |   |  |
  Vite Vitest Lint Format ...
   |   |   |   |
   -----------+----
              |
         Your scripts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With Vite+:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;        You
         |
       vp
         |
   -----------------
   |   |   |   |   |
 Vite Test Lint Format
         |
      Tasks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The tools are still there.&lt;/p&gt;

&lt;p&gt;The difference is &lt;strong&gt;who is responsible for connecting them&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why does this matter to a developer?
&lt;/h2&gt;

&lt;p&gt;Because developers should ideally spend their time solving product problems, not repeatedly solving tooling problems.&lt;/p&gt;

&lt;p&gt;You don't want your morning to start with:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Why is the formatter using a different version on CI?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Which command do I need to run before opening a PR?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Why did this package rebuild when nothing changed?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"How do I set up this repository on a new machine?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;These are small problems.&lt;/p&gt;

&lt;p&gt;But small problems repeated across dozens of developers and hundreds of builds become expensive.&lt;/p&gt;

&lt;p&gt;Vite+ is trying to make these workflows more predictable.&lt;/p&gt;




&lt;h2&gt;
  
  
  What does Vite+ actually change?
&lt;/h2&gt;

&lt;p&gt;The easiest way to understand the difference is through commands.&lt;/p&gt;

&lt;p&gt;A Vite+ project can have a workflow like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Develop&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Check the code&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Run tests&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Build for production&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Run project tasks&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp pack
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Package a library&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These commands are backed by different tools, but they share a common interface.&lt;/p&gt;

&lt;p&gt;That consistency is the real feature.&lt;/p&gt;




&lt;h2&gt;
  
  
  But isn't this just hiding the complexity?
&lt;/h2&gt;

&lt;p&gt;To some extent, yes.&lt;/p&gt;

&lt;p&gt;And that's not necessarily a bad thing.&lt;/p&gt;

&lt;p&gt;Think about Git.&lt;/p&gt;

&lt;p&gt;You can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;without understanding every internal detail of Git's object database.&lt;/p&gt;

&lt;p&gt;Or you can use Docker without understanding every detail of Linux namespaces.&lt;/p&gt;

&lt;p&gt;Good developer tools often provide a simple interface while allowing you to go deeper when necessary.&lt;/p&gt;

&lt;p&gt;Vite+ follows a similar idea.&lt;/p&gt;

&lt;p&gt;A junior developer can start with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vp dev
vp &lt;span class="nb"&gt;test
&lt;/span&gt;vp check
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;while a senior developer can investigate what is actually happening underneath.&lt;/p&gt;

&lt;p&gt;And that's exactly what the next articles in this series will do.&lt;/p&gt;




&lt;h2&gt;
  
  
  The bigger idea
&lt;/h2&gt;

&lt;p&gt;The interesting thing about Vite+ isn't the &lt;code&gt;vp&lt;/code&gt; command itself.&lt;/p&gt;

&lt;p&gt;It's the philosophy behind it.&lt;/p&gt;

&lt;p&gt;Modern web development has become incredibly powerful, but also increasingly fragmented.&lt;/p&gt;

&lt;p&gt;We have excellent tools for almost everything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Development → Vite
Testing → Vitest
Bundling → Rolldown
Libraries → tsdown
Linting → Oxlint
Formatting → Oxfmt
Tasks → Vite Task
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The challenge is making all of these tools behave like &lt;strong&gt;one development workflow&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That's what Vite+ is attempting to provide.&lt;/p&gt;

&lt;p&gt;The official announcement describes it as a single entry point to web development, combining these tools into one tested stack while remaining compatible with the broader Vite ecosystem.&lt;/p&gt;




&lt;h2&gt;
  
  
  One important detail: Vite+ is still evolving
&lt;/h2&gt;

&lt;p&gt;At the time of writing, Vite+ is in beta.&lt;/p&gt;

&lt;p&gt;The project describes it as stable but not yet complete, with additional work planned toward 1.0, including remote caching, broader framework/plugin compatibility, more migration targets, and improvements to documentation and diagnostics.&lt;/p&gt;

&lt;p&gt;So this series isn't about saying:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Everyone should replace their current setup with Vite+."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead, the goal is to understand &lt;strong&gt;what it is, what problem it solves, and where it makes sense&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Once you understand that, you can decide whether it is useful for your project.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's next?
&lt;/h2&gt;

&lt;p&gt;Now that we understand &lt;strong&gt;why Vite+ exists&lt;/strong&gt;, let's open the toolbox.&lt;/p&gt;

&lt;p&gt;In the next chapter, we'll look at the individual pieces:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Vite
Vitest
Rolldown
tsdown
Oxlint
Oxfmt
Vite Task
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;What does each one do?&lt;/p&gt;

&lt;p&gt;Why do we need it?&lt;/p&gt;

&lt;p&gt;And how does it fit into Vite+?&lt;/p&gt;

&lt;p&gt;That's where things start getting more interesting.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Next chapter: Vite+ From the Inside — Understanding the Tools Behind &lt;code&gt;vp&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>viteplus</category>
      <category>javascript</category>
      <category>frontend</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Laravel's New whereBinary(): Simple Case-Sensitive Queries in MySQL</title>
      <dc:creator>Othmane Nemli</dc:creator>
      <pubDate>Tue, 22 Sep 2026 15:54:57 +0000</pubDate>
      <link>https://dev.to/othmane_nemli/laravels-new-wherebinary-simple-case-sensitive-queries-in-mysql-2mih</link>
      <guid>https://dev.to/othmane_nemli/laravels-new-wherebinary-simple-case-sensitive-queries-in-mysql-2mih</guid>
      <description>&lt;p&gt;If you have worked with Laravel and MySQL for a while, you have probably run into this situation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'john'&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;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You expect this to find only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;john
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But depending on your MySQL collation, it may also match:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;John
JOHN
JoHn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This happens because many MySQL string comparisons are case-insensitive by default.&lt;/p&gt;

&lt;p&gt;Laravel 13.x now has a small but useful addition to the Query Builder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nf"&gt;whereBinary&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It gives us a clean way to tell the database:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Compare this value exactly, using a binary comparison."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The feature was added in Laravel framework PR &lt;a href="https://github.com/laravel/framework/pull/61261/changes" rel="noopener noreferrer"&gt;#61261&lt;/a&gt;. It also adds &lt;code&gt;whereNotBinary()&lt;/code&gt;, &lt;code&gt;orWhereBinary()&lt;/code&gt;, and &lt;code&gt;orWhereNotBinary()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let's see how it works.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem: normal string comparisons.
&lt;/h2&gt;

&lt;p&gt;Imagine we have a &lt;code&gt;users&lt;/code&gt; table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;id | name
---|------
1  | John
2  | john
3  | JOHN
4  | Alice
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'users'&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;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'john'&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;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Depending on the column's collation, MySQL may consider these values equal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;John
john
JOHN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So our query can return more records than we expected.&lt;/p&gt;

&lt;p&gt;This isn't a Laravel problem, it's how MySQL string comparison works with a case-insensitive collation.&lt;/p&gt;

&lt;h2&gt;
  
  
  The old Laravel solution
&lt;/h2&gt;

&lt;p&gt;Before &lt;code&gt;whereBinary()&lt;/code&gt;, you could write a raw expression:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'users'&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;whereRaw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name = BINARY ?'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'john'&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;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This works, but it isn't particularly nice.&lt;/p&gt;

&lt;p&gt;You're mixing Laravel's query builder with database-specific SQL.&lt;/p&gt;

&lt;p&gt;You might also have seen code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="no"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'users'&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;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'='&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;raw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'BINARY "john"'&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;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, it works, but it's not very expressive.&lt;/p&gt;

&lt;p&gt;Laravel's new method makes the intention much clearer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Meet &lt;code&gt;whereBinary()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Now we can simply write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'users'&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;whereBinary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'john'&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;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's much easier to read.&lt;/p&gt;

&lt;p&gt;The meaning is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Find users where &lt;code&gt;name&lt;/code&gt; is exactly &lt;code&gt;john&lt;/code&gt;, using a binary comparison.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For MySQL, Laravel generates SQL equivalent to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nv"&gt;`users`&lt;/span&gt;
&lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="nv"&gt;`name`&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;binary&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with &lt;code&gt;john&lt;/code&gt; passed as a bound parameter.&lt;/p&gt;

&lt;p&gt;This is exactly what the new Laravel tests verify.&lt;/p&gt;

&lt;h2&gt;
  
  
  What does "binary" actually mean?
&lt;/h2&gt;

&lt;p&gt;This is the important part.&lt;/p&gt;

&lt;p&gt;A normal comparison might treat:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;john
John
JOHN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;as equal.&lt;/p&gt;

&lt;p&gt;A binary comparison cares about the actual characters.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;john != John
john != JOHN
John != JOHN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;john == john
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="no"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'users'&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;whereBinary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'john'&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;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;could match:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;john
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;John
JOHN
JoHn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is particularly useful when the exact casing matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;whereNotBinary()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The PR also adds the opposite operation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nf"&gt;whereNotBinary&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'users'&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;whereNotBinary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'john'&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;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;blockquote&gt;
&lt;p&gt;Find rows where &lt;code&gt;name&lt;/code&gt; is not exactly &lt;code&gt;john&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Laravel generates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="nv"&gt;`name`&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;binary&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So if the database contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;john
John
JOHN
Alice
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;whereNotBinary('name', 'john')&lt;/code&gt; can match:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;John
JOHN
Alice
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;john
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;orWhereBinary()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;You can also use the binary comparison with &lt;code&gt;OR&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'users'&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;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&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="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;orWhereBinary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'john'&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;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This produces the equivalent of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="nv"&gt;`users`&lt;/span&gt;
&lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="nv"&gt;`id`&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;
&lt;span class="k"&gt;or&lt;/span&gt; &lt;span class="nv"&gt;`name`&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;binary&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful when you want to combine a normal condition with a case-sensitive condition.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;orWhereNotBinary()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;And, of course, there is also:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nf"&gt;orWhereNotBinary&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'users'&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;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'id'&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="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;orWhereNotBinary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'john'&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;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The generated condition is equivalent to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="nv"&gt;`id`&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;
&lt;span class="k"&gt;or&lt;/span&gt; &lt;span class="nv"&gt;`name`&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;binary&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we now have four methods:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Method&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;whereBinary()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Exact binary equality&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;whereNotBinary()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Not exactly equal&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;orWhereBinary()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Binary equality using &lt;code&gt;OR&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;orWhereNotBinary()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Binary inequality using &lt;code&gt;OR&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  An example with usernames
&lt;/h2&gt;

&lt;p&gt;This is probably one of the easiest real-world examples.&lt;/p&gt;

&lt;p&gt;Imagine your application has usernames:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;john
John
john123
John123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your application treats usernames as case-sensitive, you might want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'users'&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;whereBinary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'username'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'John'&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;first&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you're explicitly asking the database for the exact value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;John
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;rather than relying on whatever collation happens to be configured on the column.&lt;/p&gt;

&lt;h2&gt;
  
  
  An example with API keys
&lt;/h2&gt;

&lt;p&gt;Another possible use case is comparing values where the exact string matters.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DB&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'api_keys'&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;whereBinary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'key'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$providedKey&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;first&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The comparison is binary rather than a normal case-insensitive string comparison.&lt;/p&gt;

&lt;p&gt;However, don't confuse this with password hashing or password security.&lt;/p&gt;

&lt;p&gt;You should still store passwords using a proper password hashing algorithm such as Laravel's password hashing facilities.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;whereBinary()&lt;/code&gt; is about &lt;strong&gt;database string comparison&lt;/strong&gt;, not password security.&lt;/p&gt;

&lt;h2&gt;
  
  
  It also works with Eloquent
&lt;/h2&gt;

&lt;p&gt;Because Eloquent uses Laravel's query builder underneath, you can use the method in an Eloquent query as well:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;query&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;whereBinary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'john'&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;first&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$users&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;query&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;whereNotBinary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'john'&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;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes it convenient when you're already working with models.&lt;/p&gt;

&lt;h2&gt;
  
  
  What happens behind the scenes?
&lt;/h2&gt;

&lt;p&gt;The implementation is actually quite small.&lt;/p&gt;

&lt;p&gt;Laravel adds a new &lt;code&gt;Binary&lt;/code&gt; where type to the query builder.&lt;/p&gt;

&lt;p&gt;Conceptually, this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;whereBinary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'john'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;gets stored as a binary where condition.&lt;/p&gt;

&lt;p&gt;The MySQL grammar then turns it into:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="nv"&gt;`name`&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;binary&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For &lt;code&gt;whereNotBinary()&lt;/code&gt; it becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="nv"&gt;`name`&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;binary&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The value is still passed as a normal query binding, so you don't need to manually put the value into a raw SQL string.&lt;/p&gt;

&lt;p&gt;This is one of the nice things about the new API: you get the database-specific comparison without having to write the raw SQL yourself.&lt;/p&gt;

&lt;h2&gt;
  
  
  What about PostgreSQL and SQLite?
&lt;/h2&gt;

&lt;p&gt;This is an important detail.&lt;/p&gt;

&lt;p&gt;This new feature is not pretending that every database supports the same binary comparison syntax.&lt;/p&gt;

&lt;p&gt;The base Laravel grammar throws an exception if the database grammar doesn't support binary comparisons.&lt;/p&gt;

&lt;p&gt;The tests in the PR explicitly verify this behavior for PostgreSQL, SQLite, and SQL Server.&lt;/p&gt;

&lt;p&gt;MySQL and MariaDB, on the other hand, compile the condition using:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;binary&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;binary&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So if your application uses MySQL or MariaDB, this feature is directly relevant.&lt;/p&gt;

&lt;p&gt;If your application supports multiple database engines, keep this database-specific behavior in mind.&lt;/p&gt;

&lt;h2&gt;
  
  
  When should you use &lt;code&gt;whereBinary()&lt;/code&gt;?
&lt;/h2&gt;

&lt;p&gt;A good rule is:&lt;/p&gt;

&lt;p&gt;Use it when &lt;strong&gt;the exact characters matter&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;whereBinary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'username'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$username&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;when usernames are case-sensitive.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;whereBinary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'code'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;when a code should match exactly.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;whereBinary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'slug'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$slug&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 application intentionally treats slug casing as significant.&lt;/p&gt;

&lt;h2&gt;
  
  
  When should you NOT use it?
&lt;/h2&gt;

&lt;p&gt;Don't automatically replace every &lt;code&gt;where()&lt;/code&gt; with &lt;code&gt;whereBinary()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example, if you want a normal user search:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'john'&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;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you may actually want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;John
john
JOHN
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to be considered the same.&lt;/p&gt;

&lt;p&gt;In that situation, a case-insensitive comparison is useful.&lt;/p&gt;

&lt;p&gt;The important thing is to decide what your application means by "equal".&lt;/p&gt;

&lt;h2&gt;
  
  
  One small API, one useful problem solved
&lt;/h2&gt;

&lt;p&gt;The new API isn't a huge change.&lt;/p&gt;

&lt;p&gt;That's actually what makes it nice.&lt;/p&gt;

&lt;p&gt;Instead of writing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;whereRaw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name = BINARY ?'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can now write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;whereBinary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And instead of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;whereRaw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name != BINARY ?'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;you can write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;whereNotBinary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your intent becomes much easier to understand when reading the code.&lt;/p&gt;

&lt;h3&gt;
  
  
  The complete example
&lt;/h3&gt;

&lt;p&gt;Here's a simple example showing all four methods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Exact binary match&lt;/span&gt;
&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;whereBinary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'john'&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;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Exact binary non-match&lt;/span&gt;
&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;whereNotBinary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'john'&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;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Binary match with OR&lt;/span&gt;
&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'active'&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;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;orWhereBinary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'john'&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;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Binary non-match with OR&lt;/span&gt;
&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'active'&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;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;orWhereNotBinary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'john'&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;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summay
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;whereBinary()&lt;/code&gt; is a small addition, but it solves a common source of confusion when working with MySQL and case-sensitive values.&lt;/p&gt;

&lt;p&gt;The biggest benefit isn't that it makes something possible that you couldn't do before. You could already use &lt;code&gt;BINARY&lt;/code&gt; through raw SQL.&lt;/p&gt;

&lt;p&gt;The benefit is that Laravel now gives us a clear query-builder API for saying:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nf"&gt;whereBinary&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'john'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;instead of having to drop down into:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nf"&gt;whereRaw&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'name = BINARY ?'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'john'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're using MySQL or MariaDB and you need an exact, case-sensitive string comparison, &lt;code&gt;whereBinary()&lt;/code&gt; is a much cleaner way to express that intent.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>mysql</category>
      <category>database</category>
    </item>
    <item>
      <title>Laravel WhereHas() and With()</title>
      <dc:creator>Othmane Nemli</dc:creator>
      <pubDate>Tue, 06 Jul 2021 09:44:58 +0000</pubDate>
      <link>https://dev.to/othmane_nemli/laravel-wherehas-and-with-550o</link>
      <guid>https://dev.to/othmane_nemli/laravel-wherehas-and-with-550o</guid>
      <description>&lt;h3&gt;
  
  
  Updates:
&lt;/h3&gt;

&lt;p&gt;June 2022 Laravel merged a &lt;a href="https://github.com/laravel/framework/pull/42597" rel="noopener noreferrer"&gt;PR&lt;/a&gt; (a year later from this topic) to Laravel 9, that add a new eloquent &lt;code&gt;withWhereHas()&lt;/code&gt; -- &lt;a href="https://laravel.com/framework/docs/9.x/eloquent-relationships#constraining-eager-loads-with-relationship-existence" rel="noopener noreferrer"&gt;doc&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This Topic now only for Legacy projects (before Laravel 9).&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick recall:
&lt;/h3&gt;

&lt;p&gt;When accessing &lt;a href="https://laravel.com/docs/8.x/eloquent-relationships" rel="noopener noreferrer"&gt;Eloquent relationships&lt;/a&gt; as properties, the related models are "lazy loaded". This means the relationship data is not actually loaded until you first access the property. However, Eloquent can &lt;a href="https://laravel.com/docs/8.x/eloquent-relationships#eager-loading" rel="noopener noreferrer"&gt;"eager load"&lt;/a&gt; relationships at the time you query the parent model. Eager loading alleviates the &lt;em&gt;"N+1"&lt;/em&gt; query problem. To illustrate the *N+1 *query problem, consider a Book model that "belongs to" to an Author model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Database\Eloquent\Model&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="cd"&gt;/**
&amp;nbsp;* Get the author that wrote the book.
&amp;nbsp;*/&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;belongsTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&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;We can use eager loading to reduce this operation to just two queries. When building a query, you may specify which relationships should be eager loaded using the &lt;strong&gt;with()&lt;/strong&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Book&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'author'&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;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$books&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$book&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$book&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;name&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;h5&gt;
  
  
  Query Results:
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;
&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;authors&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="k"&gt;in&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="mi"&gt;2&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="mi"&gt;4&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="err"&gt;&amp;nbsp;…&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When retrieving model records, you may wish to limit your results based on the existence of a relationship. For example, imagine you want to retrieve all authors that have books' titles start with PHP. To do so, you may pass the name of the relationship to the &lt;strong&gt;whereHas()&lt;/strong&gt; method and define additional query constraints on your has queries&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$authors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;whereHas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'books'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Builder&lt;/span&gt; &lt;span class="nv"&gt;$query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="nv"&gt;$query&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'title'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'like'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'PHP%'&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="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Query Result:
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;authors&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;authors&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;authors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;author_id&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="k"&gt;like&lt;/span&gt; &lt;span class="s1"&gt;'PHP%'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When this query gets executed you get all authors who have at least one book start with PHP, correct? Yes.&lt;br&gt;
Now If you loop over the authors and access the book relationship like so,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$authors&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$author&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$author&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;book&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;title&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;You will end up with &lt;em&gt;N+1&lt;/em&gt;, and to solve it sure you will use &lt;strong&gt;with()&lt;/strong&gt; method to eager load books:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$authors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'books'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;whereHas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'books'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Builder&lt;/span&gt; &lt;span class="nv"&gt;$query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="nv"&gt;$query&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'title'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'like'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'PHP%'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Query Result:
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;authors&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;authors&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;authors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;author_id&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="k"&gt;like&lt;/span&gt; &lt;span class="s1"&gt;'PHP%'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="nv"&gt;`books`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;`author_id`&lt;/span&gt; &lt;span class="k"&gt;in&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="mi"&gt;5&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;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;46&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;62&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;…&lt;/span&gt;&lt;span class="p"&gt;.)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So far so good, we solve N+1 issue, but &lt;strong&gt;WAIT&lt;/strong&gt; did you notice something, well I do, the 2nd query gets all books from only the authors that selected from the 1st query, right? Yes.&lt;br&gt;
Our first query did its job and gets us only authors that have books that start with PHP, but the 2nd query (eager load) will get us all books for each author, that means if I looped over the authors and call book relationship we will see also other books not only those start with PHP.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="nc"&gt;App\Author&lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"author 1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;…&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="nc"&gt;App\Books&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;…&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'PHP'&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="nc"&gt;App\Books&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;…&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'Java'&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="nc"&gt;App\Books&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;…&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'How to use'&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;…&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;…&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;to get same results as we wanted from whereHas we need to use same condition query inside &lt;strong&gt;with()&lt;/strong&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$authors&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'books'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$query&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'title'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'like'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'PHP%'&lt;/span&gt;&lt;span class="p"&gt;)])&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;whereHas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'books'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="nv"&gt;$query&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'title'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'like'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'PHP%'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Query Results:
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;authors&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;authors&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;authors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;author_id&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="k"&gt;like&lt;/span&gt; &lt;span class="s1"&gt;'PHP%'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="nv"&gt;`books`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;`author_id`&lt;/span&gt; &lt;span class="k"&gt;in&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="mi"&gt;5&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;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;39&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;46&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;62&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;…&lt;/span&gt;&lt;span class="p"&gt;.)&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="k"&gt;like&lt;/span&gt; &lt;span class="s1"&gt;'PHP%'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I think you have already noticed the 2nd query has the same condition as 1st query.&lt;br&gt;
Now, these are the results that we are looking for become:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="nc"&gt;App\Author&lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"author 1"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;…&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="nc"&gt;App\Books&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;…&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'PHP'&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;…&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="nc"&gt;App\Author&lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"author 2"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;…&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="nc"&gt;App\Books&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;…&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'PHP'&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="nc"&gt;App\Books&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;…&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'PHP Laravel'&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;…&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;…&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt; - - - - - -&amp;nbsp;&lt;br&gt;
Finally, doing this query over all places and repeating the same conditions, is cumbersome, so we will use a local scope in &lt;em&gt;Author&lt;/em&gt; model&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;scopeWithWhereHas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$query&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$relation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$constraint&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$query&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;whereHas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$relation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$constraint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nv"&gt;$relation&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$constraint&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, our code is much cleaner by calling it this way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Author&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;withWhereHas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'books'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$query&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="nv"&gt;$query&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'title'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'like'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'PHP%'&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="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Query Results:
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;authors&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;EXISTS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;authors&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;authors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;author_id&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="k"&gt;like&lt;/span&gt; &lt;span class="s1"&gt;'PHP%'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;select&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="nv"&gt;`books`&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;`author_id`&lt;/span&gt; &lt;span class="k"&gt;in&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="mi"&gt;5&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;22&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;25&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;27&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;35&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;39&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;46&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;62&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="err"&gt;&amp;nbsp;…&lt;/span&gt;&lt;span class="p"&gt;.)&lt;/span&gt; &lt;span class="k"&gt;and&lt;/span&gt; &lt;span class="n"&gt;books&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="k"&gt;like&lt;/span&gt; &lt;span class="s1"&gt;'PHP%'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since this query builder may be needed in many Models we will create a macro for it so all Models will have that scope, all you need is to add this snippet under *&lt;em&gt;AppServiceProvider::boot() *&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Database\Eloquent\Builder&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nc"&gt;Builder&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;macro&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'withWhereHas'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$relation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$constraint&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="err"&gt;&amp;nbsp;&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;whereHas&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$relation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$constraint&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;with&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="nv"&gt;$relation&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$constraint&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;Well, you reach the end of this topic, I hope all is clear and if you have any similar thoughts or ideas, I would be happy if you share them with us.&lt;br&gt;
Thank you&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>relationship</category>
      <category>eloquent</category>
    </item>
    <item>
      <title>Different ways to use Laravel Form Requests</title>
      <dc:creator>Othmane Nemli</dc:creator>
      <pubDate>Tue, 29 Jun 2021 11:25:18 +0000</pubDate>
      <link>https://dev.to/othmane_nemli/different-ways-to-use-laravel-form-requests-5bmb</link>
      <guid>https://dev.to/othmane_nemli/different-ways-to-use-laravel-form-requests-5bmb</guid>
      <description>&lt;p&gt;Laravel provides several different approaches to validate your application’s incoming data. It is most common to use the validate method available on all incoming HTTP requests. However, in this topic, we will use &lt;a href="https://laravel.com/docs/8.x/validation#form-request-validation" rel="noopener noreferrer"&gt;Form Requests&lt;/a&gt; in different ways.&lt;/p&gt;

&lt;p&gt;First of all, I don’t think using a small validation in the controller will harm your code readability but on the other hand, if you are willing to handle more complex validation scenarios, you may wish to create a “Form Request“.&lt;/p&gt;

&lt;p&gt;Form requests are custom request classes that encapsulate their own validation and authorization logic.&lt;/p&gt;

&lt;p&gt;Let’s create our own form request class, all you need is to run this command:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;php artisan make:request StoreUserRequest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;A new &lt;code&gt;StoreUserRequest&lt;/code&gt; class will be generated under "&lt;em&gt;\App\Http\Requests&lt;/em&gt;" namespace containing a &lt;strong&gt;rules()&lt;/strong&gt; &amp;amp; &lt;strong&gt;authorize()&lt;/strong&gt; methods.&lt;br&gt;
Let’s add some quick validation under &lt;strong&gt;rules()&lt;/strong&gt; method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/**
 * Get the validation rules that apply to the request.
 *
 * @return array
 */&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;rules&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="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required|min:3|max:50'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'email'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required|email|unique:users'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'password'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required|confirmed|min:8'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="c1"&gt;//... more validation&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;After that, we will inject our new Form request in the controller &lt;strong&gt;store()&lt;/strong&gt; method&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/**
 * Store a new user.
 *
 * @param  \App\Http\Requests\StoreUserRequest  $request
 * @return Illuminate\Http\Response
 */&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;StoreUserRequest&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// The incoming request is valid...&lt;/span&gt;

    &lt;span class="c1"&gt;// Retrieve the validated input data...&lt;/span&gt;
    &lt;span class="nv"&gt;$validatedData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;validated&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;So far so good, if the validation is valid we will get our validated data from Form request otherwise a Validation Exception will be thrown.&lt;/p&gt;

&lt;p&gt;Now, what about the update, clearly we need to use another form request &lt;code&gt;UpdateUserRequest&lt;/code&gt; with its rules and inject it in the controller &lt;strong&gt;update()&lt;/strong&gt; method.&lt;/p&gt;

&lt;p&gt;So this is the first and the simple approach used so far.&lt;/p&gt;



&lt;p&gt;The second approach is using one class to handle the store and update rules, so, we will run the command again and create new Form Request by naming it &lt;code&gt;UserRequest&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We create &lt;strong&gt;store()&lt;/strong&gt; and &lt;strong&gt;update()&lt;/strong&gt; functions and call them in &lt;strong&gt;rules()&lt;/strong&gt; function by using &lt;a href="https://github.com/symfony/symfony/blob/e34cd7dd2c6d0b30d24cad443b8f964daa841d71/src/Symfony/Component/HttpFoundation/Request.php#L1457" rel="noopener noreferrer"&gt;isMethod()&lt;/a&gt;  we're checking the HTTP request method if is it a &lt;em&gt;POST&lt;/em&gt; or other than that, you may be specific and check if it is a &lt;em&gt;PUT/PATCH&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;As you may notice we can also share validations used in both methods and concatenate it with the proper validation function.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;rules&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="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required|min:3|max:50'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
 &lt;span class="o"&gt;+&lt;/span&gt;
 &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;isMethod&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'POST'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;?&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;store&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;update&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;store&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="p"&gt;[&lt;/span&gt;
 &lt;span class="s1"&gt;'email'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required|email|unique:users'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s1"&gt;'password'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required|confirmed|min:8'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="c1"&gt;//… more validation&lt;/span&gt;

 &lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;update&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="p"&gt;[&lt;/span&gt;
 &lt;span class="s1"&gt;'email'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'required|email|unique:users,email,'&lt;/span&gt;&lt;span class="mf"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;user&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s1"&gt;'logo'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'nullable|image|max:1024'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s1"&gt;'bio'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'nullable|max:300'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="s1"&gt;'github_url'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'nullable|url'&lt;/span&gt;
 &lt;span class="c1"&gt;//… more validation&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;After that, we will inject  &lt;code&gt;UserRequest&lt;/code&gt;  in both &lt;strong&gt;store()&lt;/strong&gt; and &lt;strong&gt;update()&lt;/strong&gt; methods.&lt;br&gt;
Now, we have one class that serve different validation depends on HTTP request.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cd"&gt;/**
 * Store a new user.
 */&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;store&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;UserRequest&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nv"&gt;$validated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;validated&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cd"&gt;/**
 * Update user.
 */&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;UserRequest&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nv"&gt;$validated&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$request&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;validated&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;I will name the third approach “ResourceFormRequest” and it will be a little bit different from the others.&lt;/p&gt;

&lt;p&gt;First I’ll create a &lt;code&gt;BaseFormRequest&lt;/code&gt; that contains all resourceful methods, feel free to use your own naming just be careful when you name your methods to not end up overriding Request class methods.&lt;/p&gt;

&lt;p&gt;After that, create &lt;code&gt;UserRequest&lt;/code&gt; and extends &lt;code&gt;BaseFormRequest&lt;/code&gt;, and override existing methods with your rules, finally inject the UserRequest inside your controller methods.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Our Resource Form Request can handle now a Controller resource and you end up with one file that manage all validations of specific Model instead of separate files which personally I don't like it.&lt;/p&gt;

&lt;p&gt;I think there's a lot of approaches that we can follow and feel free to share your best approach or other approaches you have.&lt;/p&gt;

&lt;p&gt;Finally, if you are reading this line I think the topic was interesting for you.&lt;/p&gt;

&lt;p&gt;Thank you&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>validation</category>
    </item>
  </channel>
</rss>
