<?xml version="1.0" encoding="utf-8" standalone="yes"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><script src="https://www.rss.style/js/atom-style.js" xmlns="http://www.w3.org/1999/xhtml"/><title>Tower of Kubes</title><link rel="self" type="application/atom+xml" hreflang="en" href="https://www.towerofkubes.com/tags/javascript/feed.xml"/><link rel="alternate" type="text/html" hreflang="en" href="https://www.towerofkubes.com/tags/javascript/"/><link rel="alternate" type="application/rss+xml" hreflang="en" href="https://www.towerofkubes.com/tags/javascript/index.xml"/><id>/</id><updated>2025-11-10T00:00:00Z</updated><author><name>Ro'i Bandel</name></author><generator>Hugo 0.157.0</generator><entry><title>Pre-commit hooks for Node.js projects</title><link rel="alternate" type="text/html" hreflang="en" href="https://www.towerofkubes.com/articles/pre-commit-hooks/"/><id>https://www.towerofkubes.com/articles/pre-commit-hooks/</id><updated>2025-11-10T00:00:00Z</updated><summary type="html">Step-by-step Node.js pre-commit setup: Husky + lint-staged + Oxc to enforce linting, formatting, and TypeScript checks before every git commit.</summary><content type="html"><![CDATA[<p>This is my workflow for integrating pre-commit hooks for Node.js (NPM) projects. I combine this with my <a href="/articles/oxc-workflow/" >Oxc Workflow</a>.</p>

<h2 class="relative group">What is a Git pre-commit hook?
    <div id="what-is-a-git-pre-commit-hook" class="anchor"></div>
    
</h2>
<p>A <code>pre-commit</code> is a type of <a href="https://git-scm.com/book/ms/v2/Customizing-Git-Git-Hooks"  target="_blank" rel="noreferrer">Git Hook</a> that runs before each commit. It can help with verifying code standards (linting, formatting, testing etc.).</p>

<h2 class="relative group">Pre-commit tools
    <div id="pre-commit-tools" class="anchor"></div>
    
</h2>

<h3 class="relative group"><a href="https://pre-commit.com/"  target="_blank" rel="noreferrer">pre-commit</a>
    <div id="pre-commit" class="anchor"></div>
    
</h3>
<p>A tool written in Python, though can be used with projects in any language. Can be configured to run many hooks including <a href="https://github.com/pre-commit/pre-commit-hooks"  target="_blank" rel="noreferrer">pre-commit/pre-commit-hooks</a> and <a href="https://github.com/gitleaks/gitleaks?tab=readme-ov-file#pre-commit"  target="_blank" rel="noreferrer">Gitleaks</a>. I have used this tool and like it for Python and other projects, though for Node.js projects, I prefer the options below.</p>

<h3 class="relative group"><a href="https://typicode.github.io/husky/"  target="_blank" rel="noreferrer">Husky</a>
    <div id="husky" class="anchor"></div>
    
</h3>
<p>A pre-commit hooks tool written in JavaScript. I prefer this tool for Node.js projects since it can be easily integrated in <code>package.json</code> scripts.</p>

<h3 class="relative group"><a href="https://www.npmjs.com/package/lint-staged"  target="_blank" rel="noreferrer">lint-staged</a>
    <div id="lint-staged" class="anchor"></div>
    
</h3>
<p>Another tool that’s written in JavaScript, to help run checks against staged files (see <a href="/articles/pre-commit-hooks/#guide-husky--lint-staged--oxc-workflow" >Guide</a> below). Lint-staged does not configure git pre-commit hooks on its own, but can be combined with Husky.</p>

<h3 class="relative group"><a href="https://github.com/toplenboren/simple-git-hooks"  target="_blank" rel="noreferrer">simple-git-hooks</a>
    <div id="simple-git-hooks" class="anchor"></div>
    
</h3>
<p>Another git hooks manager written in JavaScript. Use to be more lightweight than Husky, but newer versions of Husky closed the gap.</p>

<h2 class="relative group">Guide: Husky + Lint-staged + Oxc workflow
    <div id="guide-husky--lint-staged--oxc-workflow" class="anchor"></div>
    
</h2>
<ol>
<li>
<p>Configure <code>oxlint</code> and <code>oxfmt</code> based on my <a href="/articles/oxc-workflow/" >Oxc Workflow</a>.</p>
</li>
<li>
<p>Install <code>devDependencies</code>:</p>
</li>
</ol>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">npm install --save-dev husky lint-staged</span></span></code></pre></div></div>
<!-- markdownlint-disable MD029 -->
<ol start="3">
<li>Initialize <code>husky</code>:</li>
</ol>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># Installed</span>
</span></span><span class="line"><span class="cl">./node_modules/.bin/husky --init</span></span></code></pre></div></div>
<hr>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1"># Not installed</span>
</span></span><span class="line"><span class="cl">npx run husky --init</span></span></code></pre></div></div>
<ol start="4">
<li>Configure <code>lint-staged</code> to run Oxc and <code>tsc</code> checks:</li>
</ol>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="p">[</span><span class="cm">/**
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @filename: lint-staged.config.js
</span></span></span><span class="line"><span class="cl"><span class="cm"> * @type {import('lint-staged').Configuration}
</span></span></span><span class="line"><span class="cl"><span class="cm"> */</span>
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="s1">'**/*.[jt]s?(x)'</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="s1">'oxfmt'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">'oxlint --type-aware --type-check --fix'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="s1">'**/*.ts?(x)'</span><span class="o">:</span> <span class="p">()</span> <span class="o">=></span> <span class="s1">'tsc -p tsconfig.json --noEmit'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span></span></span></code></pre></div></div>

    <div class="admonition note">
      <div class="admonition-header"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M0 64C0 28.7 28.7 0 64 0L224 0l0 128c0 17.7 14.3 32 32 32l128 0 0 125.7-86.8 86.8c-10.3 10.3-17.5 23.1-21 37.2l-18.7 74.9c-2.3 9.2-1.8 18.8 1.3 27.5L64 512c-35.3 0-64-28.7-64-64L0 64zm384 64l-128 0L256 0 384 128zM549.8 235.7l14.4 14.4c15.6 15.6 15.6 40.9 0 56.6l-29.4 29.4-71-71 29.4-29.4c15.6-15.6 40.9-15.6 56.6 0zM311.9 417L441.1 287.8l71 71L382.9 487.9c-4.1 4.1-9.2 7-14.9 8.4l-60.1 15c-5.5 1.4-11.2-.2-15.2-4.2s-5.6-9.7-4.2-15.2l15-60.1c1.4-5.6 4.3-10.8 8.4-14.9z"/></svg>
        <span>Note</span>
      </div>
      <div class="admonition-content">
        <p>Can be further configured, but this is a good start for a project using TypeScript and Oxc.</p>
      </div>
    </div><ol start="5">
<li>Configure <code>husky</code> to run <code>lint-staged</code> as a pre-commit hook:</li>
</ol>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">npm <span class="nb">exec</span> -- lint-staged --config lint-staged.config.js</span></span></code></pre></div></div>
<ol start="6">
<li>Add a <code>prepare</code>script in <code>package.json</code> :</li>
</ol>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl">  <span class="s2">"scripts"</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">"prepare"</span><span class="p">:</span> <span class="s2">"husky"</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span><span class="err">,</span></span></span></code></pre></div></div>

    <div class="admonition note">
      <div class="admonition-header"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M0 64C0 28.7 28.7 0 64 0L224 0l0 128c0 17.7 14.3 32 32 32l128 0 0 125.7-86.8 86.8c-10.3 10.3-17.5 23.1-21 37.2l-18.7 74.9c-2.3 9.2-1.8 18.8 1.3 27.5L64 512c-35.3 0-64-28.7-64-64L0 64zm384 64l-128 0L256 0 384 128zM549.8 235.7l14.4 14.4c15.6 15.6 15.6 40.9 0 56.6l-29.4 29.4-71-71 29.4-29.4c15.6-15.6 40.9-15.6 56.6 0zM311.9 417L441.1 287.8l71 71L382.9 487.9c-4.1 4.1-9.2 7-14.9 8.4l-60.1 15c-5.5 1.4-11.2-.2-15.2-4.2s-5.6-9.7-4.2-15.2l15-60.1c1.4-5.6 4.3-10.8 8.4-14.9z"/></svg>
        <span>This script may have already been added by <code>husky --init</code>.</span>
      </div>
    </div><hr>
<p><em>Featured image by <a href="https://unsplash.com/@yancymin?utm_source=hugo&utm_medium=referral"  target="_blank" rel="noreferrer">Yancy Min</a> on <a href="https://unsplash.com/photos/a-close-up-of-a-text-description-on-a-computer-screen-842ofHC6MaI?utm_source=hugo&utm_medium=referral"  target="_blank" rel="noreferrer">Unsplash</a>.</em></p>
]]></content><author><name>Ro'i Bandel</name></author><category term="node" label="Node" scheme="https://www.towerofkubes.com/tags/node/"/><category term="javascript" label="Javascript" scheme="https://www.towerofkubes.com/tags/javascript/"/><category term="typescript" label="Typescript" scheme="https://www.towerofkubes.com/tags/typescript/"/><category term="pre-commit" label="Pre-Commit" scheme="https://www.towerofkubes.com/tags/pre-commit/"/><category term="git" label="Git" scheme="https://www.towerofkubes.com/tags/git/"/><published>2025-11-10T00:00:00Z</published></entry><entry><title>Oxc Workflow</title><link rel="alternate" type="text/html" hreflang="en" href="https://www.towerofkubes.com/articles/oxc-workflow/"/><id>https://www.towerofkubes.com/articles/oxc-workflow/</id><updated>2025-11-10T00:00:00Z</updated><summary type="html">How to setup new Node.js projects, with linting and formatting using Oxc.</summary><content type="html"><![CDATA[<p>Here’s how I like to setup new Node.js projects, with linting and formatting using Oxc.</p>

<h2 class="relative group">Oxc
    <div id="oxc" class="anchor"></div>
    
</h2>
<p>I wrote about Oxc (The JavaScript Oxidation Compiler) in <a href="/articles/next-generation-tooling-for-developers/" >Next Generation Tooling for Developers</a>. When I first wrote this article, Oxc already included a linter (<a href="https://www.npmjs.com/package/oxlint"  target="_blank" rel="noreferrer"><code>oxlint</code></a>, which can replace ESLint), but the formatter was not available yet. Since then, VoidZero has continued the development of Oxc, not only launching Vite+ but also launching a formatter (<a href="https://www.npmjs.com/package/oxfmt"  target="_blank" rel="noreferrer"><code>oxfmt</code></a>, which can replace Prettier). With the combination of <a href="https://www.npmjs.com/package/oxlint"  target="_blank" rel="noreferrer"><code>oxlint</code></a> and <a href="https://www.npmjs.com/package/oxfmt"  target="_blank" rel="noreferrer"><code>oxfmt</code></a>, I now have a modern-alternative to ESLint + Prettier. Note that this might not work as a replacement in all existing projects that rely on specific configurations of ESLint and/or Prettier. However, for new Node.js projects, I will strive to go with the Oxc stack.</p>

<h3 class="relative group">Why Oxc instead of ESLint + Prettier?
    <div id="why-oxc-instead-of-eslint--prettier" class="anchor"></div>
    
</h3>
<p>The two main reasons I prefer Oxc is speed and ease of configuration; as I have explained in <a href="/articles/next-generation-tooling-for-developers/" >Next Generation Tooling for Developers</a>, the Rust-based tools are noticeably faster. In addition, they have a more modern design with more intutive configuration. In particular, ESLint has become a nightmare to configure after the breaking changes in ESLint v9.</p>

<h2 class="relative group">Guide
    <div id="guide" class="anchor"></div>
    
</h2>

<h3 class="relative group">One-time run
    <div id="one-time-run" class="anchor"></div>
    
</h3>
<p>These tools can be run in a project without being installed or added to <code>package.json</code> using npx commands:</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">npx oxlint@latest</span></span></code></pre></div></div>
<hr>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">npx oxfmt@latest</span></span></code></pre></div></div>

<h3 class="relative group">Install Oxc tools in NPM project
    <div id="install-oxc-tools-in-npm-project" class="anchor"></div>
    
</h3>
<p>For consistent usage in an npm project, Oxc packages can be added as <a href="https://docs.npmjs.com/specifying-dependencies-and-devdependencies-in-a-package-json-file"  target="_blank" rel="noreferrer"><code>devDependencies</code></a>.</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">npm install --save-dev oxlint@latest oxlint-tsgolint@latest oxfmt@latest</span></span></code></pre></div></div>

<h3 class="relative group">Initialize configuration for oxlint
    <div id="initialize-configuration-for-oxlint" class="anchor"></div>
    
</h3>

    <div class="admonition quote">
      <div class="admonition-header"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M448 296c0 66.3-53.7 120-120 120l-8 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l8 0c30.9 0 56-25.1 56-56l0-8-64 0c-35.3 0-64-28.7-64-64l0-64c0-35.3 28.7-64 64-64l64 0c35.3 0 64 28.7 64 64l0 32 0 32 0 72zm-256 0c0 66.3-53.7 120-120 120l-8 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l8 0c30.9 0 56-25.1 56-56l0-8-64 0c-35.3 0-64-28.7-64-64l0-64c0-35.3 28.7-64 64-64l64 0c35.3 0 64 28.7 64 64l0 32 0 32 0 72z"/></svg>
        <span>Quote</span>
      </div>
      <div class="admonition-content">
        <p>Configuration files for Oxlint are written in JSON, with support for comments (JSONC). Oxlint will automatically search for files named <code>.oxlintrc.json</code> and automatically use those. But you can name the file anything when you are using the <code>--config</code> CLI option.</p>
      </div>
    </div><ul>
<li><a href="https://oxc.rs/docs/guide/usage/linter/config.html"  target="_blank" rel="noreferrer">Configuring Oxlint | The JavaScript Oxidation Compiler</a></li>
</ul>
<p>Use the <a href="https://oxc.rs/docs/guide/usage/linter/cli.html#basic-configuration"  target="_blank" rel="noreferrer"><code>--init</code></a> option to initialize a <code>.oxlintrc.json</code> file:</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1">## If installed</span>
</span></span><span class="line"><span class="cl">./node_modules/.bin/oxlint --init</span></span></code></pre></div></div>
<hr>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1">## If not installed</span>
</span></span><span class="line"><span class="cl">npx oxlint@latest --init</span></span></code></pre></div></div>

<h3 class="relative group">Initialize configuration for oxfmt
    <div id="initialize-configuration-for-oxfmt" class="anchor"></div>
    
</h3>

    <div class="admonition quote">
      <div class="admonition-header"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M448 296c0 66.3-53.7 120-120 120l-8 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l8 0c30.9 0 56-25.1 56-56l0-8-64 0c-35.3 0-64-28.7-64-64l0-64c0-35.3 28.7-64 64-64l64 0c35.3 0 64 28.7 64 64l0 32 0 32 0 72zm-256 0c0 66.3-53.7 120-120 120l-8 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l8 0c30.9 0 56-25.1 56-56l0-8-64 0c-35.3 0-64-28.7-64-64l0-64c0-35.3 28.7-64 64-64l64 0c35.3 0 64 28.7 64 64l0 32 0 32 0 72z"/></svg>
        <span>Quote</span>
      </div>
      <div class="admonition-content">
        <p>By default, <code>oxfmt</code> automatically tries to find the nearest <code>.oxfmtrc.json</code> or <code>.oxfmtrc.jsonc</code> file from current working directory. If not found, default configuration is used.</p>
<p>Also you can specify your config file by <code>-c yourconfig.jsonc</code> flag.</p>
<p>Almost all format options are compatible with Prettier’s <a href="https://prettier.io/docs/options"  target="_blank" rel="noreferrer">options</a>. So you may finish your setup by just renaming <code>.prettierrc.json</code> to <code>.oxfmtrc.jsonc</code>.</p>
      </div>
    </div><ul>
<li><a href="https://oxc.rs/docs/guide/usage/formatter.html#configuration-file"  target="_blank" rel="noreferrer">Formatter | The JavaScript Oxidation Compiler</a></li>
</ul>
<p>Use the <a href="https://oxc.rs/docs/guide/usage/formatter/cli.html#mode-options"  target="_blank" rel="noreferrer"><code>--init</code></a> option to initialize a <code>.oxfmtrc.json</code> file:</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1">## If installed</span>
</span></span><span class="line"><span class="cl">./node_modules/.bin/oxfmt --init</span></span></code></pre></div></div>
<hr>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl"><span class="c1">## If not installed</span>
</span></span><span class="line"><span class="cl">npx oxfmt@latest --init</span></span></code></pre></div></div>
<hr>

    <details class="admonition note">
      <summary class="admonition-header"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M0 64C0 28.7 28.7 0 64 0L224 0l0 128c0 17.7 14.3 32 32 32l128 0 0 125.7-86.8 86.8c-10.3 10.3-17.5 23.1-21 37.2l-18.7 74.9c-2.3 9.2-1.8 18.8 1.3 27.5L64 512c-35.3 0-64-28.7-64-64L0 64zm384 64l-128 0L256 0 384 128zM549.8 235.7l14.4 14.4c15.6 15.6 15.6 40.9 0 56.6l-29.4 29.4-71-71 29.4-29.4c15.6-15.6 40.9-15.6 56.6 0zM311.9 417L441.1 287.8l71 71L382.9 487.9c-4.1 4.1-9.2 7-14.9 8.4l-60.1 15c-5.5 1.4-11.2-.2-15.2-4.2s-5.6-9.7-4.2-15.2l15-60.1c1.4-5.6 4.3-10.8 8.4-14.9z"/></svg>
        <span>A previous version of this article, suggested to use prettier-init (before oxfmt had the <code>--init</code> option).</span>
      </summary>
      <div class="admonition-content">
        <p>The <a href="https://github.com/gabrielperales/prettier-init"  target="_blank" rel="noreferrer">prettier-init</a> tool can be used to help bootstrap configuration:</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">npx prettier-init@latest
</span></span><span class="line"><span class="cl">mv <span class="s2">".prettierrc.json"</span> <span class="s2">".oxfmtrc.json"</span></span></span></code></pre></div></div>
      </div>
    </details>
<h3 class="relative group"><code>scripts</code> block in <code>package.json</code>
    <div id="scripts-block-in-packagejson" class="anchor"></div>
    
</h3>
<p>For easy and consistent usage across the project, add to the <code>scripts</code> block in <code>package.json</code>:</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl">  <span class="s2">"scripts"</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">"lint"</span><span class="p">:</span> <span class="s2">"oxlint --type-aware --type-check ."</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">"lint:fix"</span><span class="p">:</span> <span class="s2">"oxlint --type-aware --type-check . --fix"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">"lint:fix-all"</span><span class="p">:</span> <span class="s2">"oxlint --type-aware --type-check . --fix --fix-suggestions --fix-dangerously"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">"format"</span><span class="p">:</span> <span class="s2">"oxfmt ."</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">"format:check"</span><span class="p">:</span> <span class="s2">"oxfmt . --check"</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span><span class="err">,</span></span></span></code></pre></div></div>

<h3 class="relative group">Commit and push all changed and added files
    <div id="commit-and-push-all-changed-and-added-files" class="anchor"></div>
    
</h3>
<p>Commit and push all relevant files that were changed or added:</p>
<div class="highlight-wrapper"><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">git add <span class="s2">".oxfmtrc.json"</span> <span class="s2">".oxlintrc.json"</span> <span class="s2">"package.json"</span> <span class="s2">"package-lock.json"</span>
</span></span><span class="line"><span class="cl">git commit -s
</span></span><span class="line"><span class="cl">git push</span></span></code></pre></div></div>
<hr>
<p><em>Featured image by <a href="https://unsplash.com/@6heinz3r?utm_source=hugo&utm_medium=referral"  target="_blank" rel="noreferrer">Gabriel Heinzer</a> on <a href="https://unsplash.com/?utm_source=hugo&utm_medium=referral"  target="_blank" rel="noreferrer">Unsplash</a>.</em></p>
]]></content><author><name>Ro'i Bandel</name></author><category term="node" label="Node" scheme="https://www.towerofkubes.com/tags/node/"/><category term="javascript" label="Javascript" scheme="https://www.towerofkubes.com/tags/javascript/"/><category term="typescript" label="Typescript" scheme="https://www.towerofkubes.com/tags/typescript/"/><category term="tools" label="Tools" scheme="https://www.towerofkubes.com/tags/tools/"/><category term="snippets" label="Snippets" scheme="https://www.towerofkubes.com/tags/snippets/"/><published>2025-11-10T00:00:00Z</published></entry><entry><title>Next Generation Tooling for Developers</title><link rel="alternate" type="text/html" hreflang="en" href="https://www.towerofkubes.com/articles/next-generation-tooling-for-developers/"/><id>https://www.towerofkubes.com/articles/next-generation-tooling-for-developers/</id><updated>2025-10-12T00:00:00Z</updated><summary type="html">In recent months I have been learning about Astral, and have started using uv and ruff. This led me to try to find similar tools for other languages.</summary><content type="html"><![CDATA[<p>In recent months I have been learning about <a href="https://astral.sh/"  target="_blank" rel="noreferrer">Astral: High-performance Python tooling</a>. I first learned about Astral’s tools from this article: <a href="https://www.cesarsotovalero.net/blog/i-am-switching-to-python-and-actually-liking-it.html"  target="_blank" rel="noreferrer">I’m Switching to Python and Actually Liking It</a> and have started using uv and ruff. This led me to try to find similar tools for other languages.</p>

<h2 class="relative group">What makes a tool “next generation”?
    <div id="what-makes-a-tool-next-generation" class="anchor"></div>
    
</h2>

    <div class="admonition note">
      <div class="admonition-header"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M0 64C0 28.7 28.7 0 64 0L224 0l0 128c0 17.7 14.3 32 32 32l128 0 0 125.7-86.8 86.8c-10.3 10.3-17.5 23.1-21 37.2l-18.7 74.9c-2.3 9.2-1.8 18.8 1.3 27.5L64 512c-35.3 0-64-28.7-64-64L0 64zm384 64l-128 0L256 0 384 128zM549.8 235.7l14.4 14.4c15.6 15.6 15.6 40.9 0 56.6l-29.4 29.4-71-71 29.4-29.4c15.6-15.6 40.9-15.6 56.6 0zM311.9 417L441.1 287.8l71 71L382.9 487.9c-4.1 4.1-9.2 7-14.9 8.4l-60.1 15c-5.5 1.4-11.2-.2-15.2-4.2s-5.6-9.7-4.2-15.2l15-60.1c1.4-5.6 4.3-10.8 8.4-14.9z"/></svg>
        <span>Note</span>
      </div>
      <div class="admonition-content">
        <p>I am not focusing on AI tools in this article. I have other articles on this subject (such as <a href="/articles/agentic-cli-tools-comparison/" >Agentic CLI Tools Comparison</a>).</p>
      </div>
    </div><p>The projects below have a few things in common. The projects are led by companies which have similar missions to develop modern tooling for developers. All of the tools below are open-source under the <a href="https://opensource.org/license/mit"  target="_blank" rel="noreferrer">MIT License</a>.</p>
<p>Most of the tools are written in modern compiled languages such as Rust or Go. Many of the tools boast significant performance improvements compared to previous tools, as well as a more modern design with better <a href="https://en.wikipedia.org/wiki/Developer_Experience"  target="_blank" rel="noreferrer">Developer Experience</a> (DX or DevEx).</p>
<p>As a result, these tools tend to feel both <em>faster</em> and <em>easier</em> to use than the tools that they aim to replace.</p>

<h2 class="relative group">Toolsets
    <div id="toolsets" class="anchor"></div>
    
</h2>

<h3 class="relative group">Python
    <div id="python" class="anchor"></div>
    
</h3>

<h4 class="relative group"><a href="https://astral.sh/"  target="_blank" rel="noreferrer">Astral: High-performance Python tooling</a>
    <div id="astral-high-performance-python-tooling" class="anchor"></div>
    
</h4>

<h5 class="relative group">Astrals’s Mission
    <div id="astralss-mission" class="anchor"></div>
    
</h5>

    <div class="admonition quote">
      <div class="admonition-header"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M448 296c0 66.3-53.7 120-120 120l-8 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l8 0c30.9 0 56-25.1 56-56l0-8-64 0c-35.3 0-64-28.7-64-64l0-64c0-35.3 28.7-64 64-64l64 0c35.3 0 64 28.7 64 64l0 32 0 32 0 72zm-256 0c0 66.3-53.7 120-120 120l-8 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l8 0c30.9 0 56-25.1 56-56l0-8-64 0c-35.3 0-64-28.7-64-64l0-64c0-35.3 28.7-64 64-64l64 0c35.3 0 64 28.7 64 64l0 32 0 32 0 72z"/></svg>
        <span>Quote</span>
      </div>
      <div class="admonition-content">
        <p><strong>Astral’s Mission</strong></p>
<p><strong>We build</strong> high-performance developer tools for the <strong>Python</strong> ecosystem.</p>
<p>Our mission is to make the <strong>Python</strong> ecosystem more productive.</p>
<p>By building tools that enable developers to <strong>ship great software, faster.</strong></p>
<p>Tools that change <strong>how we work.</strong></p>
      </div>
    </div><ul>
<li><a href="https://astral.sh/about"  target="_blank" rel="noreferrer">About | Astral</a></li>
</ul>

<h5 class="relative group">Astral’s Projects
    <div id="astrals-projects" class="anchor"></div>
    
</h5>
<ul>
<li><strong>uv (<a href="https://docs.astral.sh/uv/"  target="_blank" rel="noreferrer">Docs</a> | <a href="https://github.com/astral-sh/ruff"  target="_blank" rel="noreferrer">GitHub</a>):</strong> An extremely fast Python package and project manager, written in Rust.</li>
<li><strong>ruff (<a href="https://docs.astral.sh/ruff/"  target="_blank" rel="noreferrer">Docs</a> | <a href="https://github.com/astral-sh/ruff"  target="_blank" rel="noreferrer">GitHub</a>):</strong> An extremely fast Python linter and code formatter, written in Rust.</li>
<li><strong>ty (<a href="https://docs.astral.sh/ty/"  target="_blank" rel="noreferrer">Docs</a> | <a href="https://github.com/astral-sh/ty"  target="_blank" rel="noreferrer">GitHub</a>):</strong> An extremely fast Python type checker and language server, written in Rust.</li>
<li><strong>python-build-standalone (<a href="https://gregoryszorc.com/docs/python-build-standalone/main/"  target="_blank" rel="noreferrer">Docs</a> | <a href="https://github.com/astral-sh/python-build-standalone"  target="_blank" rel="noreferrer">GitHub</a>):</strong> This project produces standalone, highly-redistributable builds of Python. Used in uv.</li>
</ul>

    <div class="admonition note">
      <div class="admonition-header"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M0 64C0 28.7 28.7 0 64 0L224 0l0 128c0 17.7 14.3 32 32 32l128 0 0 125.7-86.8 86.8c-10.3 10.3-17.5 23.1-21 37.2l-18.7 74.9c-2.3 9.2-1.8 18.8 1.3 27.5L64 512c-35.3 0-64-28.7-64-64L0 64zm384 64l-128 0L256 0 384 128zM549.8 235.7l14.4 14.4c15.6 15.6 15.6 40.9 0 56.6l-29.4 29.4-71-71 29.4-29.4c15.6-15.6 40.9-15.6 56.6 0zM311.9 417L441.1 287.8l71 71L382.9 487.9c-4.1 4.1-9.2 7-14.9 8.4l-60.1 15c-5.5 1.4-11.2-.2-15.2-4.2s-5.6-9.7-4.2-15.2l15-60.1c1.4-5.6 4.3-10.8 8.4-14.9z"/></svg>
        <span>Note</span>
      </div>
      <div class="admonition-content">
        <p><a href="https://rye.astral.sh/"  target="_blank" rel="noreferrer">Rye</a> is another tool that was maintained by Astral, however it is no longer developed and uv is considered “the <a href="https://lucumr.pocoo.org/2024/8/21/harvest-season/"  target="_blank" rel="noreferrer">successor project</a> from the same maintainers”.</p>
      </div>
    </div>
<h3 class="relative group">JavaScript/TypeScript
    <div id="javascripttypescript" class="anchor"></div>
    
</h3>

<h4 class="relative group"><a href="https://voidzero.dev/"  target="_blank" rel="noreferrer">VoidZero | Next Generation Tooling for the Web</a>
    <div id="voidzero--next-generation-tooling-for-the-web" class="anchor"></div>
    
</h4>

<h5 class="relative group">VoidZero’s Mission
    <div id="voidzeros-mission" class="anchor"></div>
    
</h5>

    <div class="admonition quote">
      <div class="admonition-header"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M448 296c0 66.3-53.7 120-120 120l-8 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l8 0c30.9 0 56-25.1 56-56l0-8-64 0c-35.3 0-64-28.7-64-64l0-64c0-35.3 28.7-64 64-64l64 0c35.3 0 64 28.7 64 64l0 32 0 32 0 72zm-256 0c0 66.3-53.7 120-120 120l-8 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l8 0c30.9 0 56-25.1 56-56l0-8-64 0c-35.3 0-64-28.7-64-64l0-64c0-35.3 28.7-64 64-64l64 0c35.3 0 64 28.7 64 64l0 32 0 32 0 72z"/></svg>
        <span>Quote</span>
      </div>
      <div class="admonition-content">
        <p><strong>The Mission</strong></p>
<p>We are building a unified high-performance toolchain for JavaScript: including parser, transformer, resolver, linter, formatter, minifier, bundler, test runner, and meta framework support. Our mission is to make the next generation of JavaScript developers more productive than ever before.</p>
      </div>
    </div><ul>
<li><a href="https://voidzero.dev/"  target="_blank" rel="noreferrer">VoidZero | Next Generation Tooling for the Web</a></li>
</ul>

<h5 class="relative group">VoidZero’s Projects
    <div id="voidzeros-projects" class="anchor"></div>
    
</h5>
<ul>
<li><strong>Vite (<a href="https://vite.dev"  target="_blank" rel="noreferrer">Website</a> | <a href="https://github.com/vitejs/vite"  target="_blank" rel="noreferrer">GitHub</a>):</strong> The build tool for the web.</li>
<li><strong>Vitest (<a href="https://vitest.dev/"  target="_blank" rel="noreferrer">Website</a> | <a href="https://github.com/vitest-dev/vitest"  target="_blank" rel="noreferrer">GitHub</a>):</strong> Next generation testing framework powered by Vite.</li>
<li><strong>Rolldown (<a href="https://rolldown.rs/"  target="_blank" rel="noreferrer">Website</a> | <a href="https://github.com/rolldown/rolldown"  target="_blank" rel="noreferrer">GitHub</a>):</strong> Fast Rust bundler for JavaScript/TypeScript with Rollup-compatible API.</li>
<li><strong>The JavaScript Oxidation Compiler (Oxc) (<a href="https://oxc.rs/"  target="_blank" rel="noreferrer">Website</a> | <a href="https://github.com/oxc-project"  target="_blank" rel="noreferrer">GitHub</a>):</strong> A collection of JavaScript tools written in Rust.</li>
</ul>

<h4 class="relative group"><a href="https://webinfra.org/"  target="_blank" rel="noreferrer">ByteDance Web Infra Team</a>
    <div id="bytedance-web-infra-team" class="anchor"></div>
    
</h4>

<h5 class="relative group">Web Infra’s Mission
    <div id="web-infras-mission" class="anchor"></div>
    
</h5>

    <div class="admonition quote">
      <div class="admonition-header"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M448 296c0 66.3-53.7 120-120 120l-8 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l8 0c30.9 0 56-25.1 56-56l0-8-64 0c-35.3 0-64-28.7-64-64l0-64c0-35.3 28.7-64 64-64l64 0c35.3 0 64 28.7 64 64l0 32 0 32 0 72zm-256 0c0 66.3-53.7 120-120 120l-8 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l8 0c30.9 0 56-25.1 56-56l0-8-64 0c-35.3 0-64-28.7-64-64l0-64c0-35.3 28.7-64 64-64l64 0c35.3 0 64 28.7 64 64l0 32 0 32 0 72z"/></svg>
        <span>Quote</span>
      </div>
      <div class="admonition-content">
        <p><strong>Web Infra</strong></p>
<p>We are from ByteDance, our goal is to build an open technical ecosystem to promote the development of frontend technology.</p>
      </div>
    </div><ul>
<li><a href="https://github.com/web-infra-dev"  target="_blank" rel="noreferrer">Web Infra · GitHub</a></li>
</ul>

<h5 class="relative group">Web Infras’s Projects
    <div id="web-infrass-projects" class="anchor"></div>
    
</h5>
<ul>
<li><strong>Rspack (<a href="https://rspack.rs"  target="_blank" rel="noreferrer">Website</a> | <a href="https://github.com/web-infra-dev/rspack"  target="_blank" rel="noreferrer">GitHub</a>):</strong> Fast Rust-based web bundler with webpack-compatible API.</li>
<li><strong>Rsbuild (<a href="https://rsbuild.rs"  target="_blank" rel="noreferrer">Website</a> | <a href="https://github.com/web-infra-dev/rsbuild"  target="_blank" rel="noreferrer">GitHub</a>):</strong> Zero-config build tool powered by Rspack.</li>
<li><strong>Rspress (<a href="https://rspress.rs"  target="_blank" rel="noreferrer">Website</a> | <a href="https://github.com/web-infra-dev/rspress"  target="_blank" rel="noreferrer">GitHub</a>):</strong> A fast Rsbuild-based static site generator.</li>
<li><strong>Rsdoctor (<a href="https://rsdoctor.rs"  target="_blank" rel="noreferrer">Website</a> | <a href="https://github.com/web-infra-dev/rsdoctor"  target="_blank" rel="noreferrer">GitHub</a>):</strong> A one-stop build analyzer for Rspack and webpack.</li>
<li><strong>Rslib (<a href="https://rslib.rs"  target="_blank" rel="noreferrer">Website</a> | <a href="https://github.com/web-infra-dev/rslib"  target="_blank" rel="noreferrer">GitHub</a>):</strong> Create JavaScript libraries in a simple and intuitive way.</li>
<li><strong>Rstest (<a href="https://rstest.rs"  target="_blank" rel="noreferrer">Website</a> | <a href="https://github.com/web-infra-dev/rstest"  target="_blank" rel="noreferrer">GitHub</a>):</strong> The testing framework powered by Rspack.</li>
<li><strong>Rslint (<a href="https://rslint.rs"  target="_blank" rel="noreferrer">Website</a> | <a href="https://github.com/web-infra-dev/rslint"  target="_blank" rel="noreferrer">GitHub</a>):</strong> High-performance JavaScript and TypeScript linter written in Go.</li>
<li><strong>Midscene.js (<a href="https://midscenejs.com"  target="_blank" rel="noreferrer">Website</a> | <a href="https://github.com/web-infra-dev/midscene"  target="_blank" rel="noreferrer">GitHub</a>):</strong> AI Operator for Web, Android, Automation & Testing.</li>
<li><strong>Modern.js (<a href="https://modernjs.dev"  target="_blank" rel="noreferrer">Website</a> | <a href="https://github.com/web-infra-dev/modern.js"  target="_blank" rel="noreferrer">GitHub</a>):</strong> Progressive web framework based on React and Rsbuild.</li>
<li><strong>Garfish (<a href="https://www.garfishjs.org"  target="_blank" rel="noreferrer">Website</a> | <a href="https://github.com/web-infra-dev/garfish"  target="_blank" rel="noreferrer">GitHub</a>):</strong> Powerful micro front-end framework.</li>
</ul>

<h2 class="relative group">Business Model
    <div id="business-model" class="anchor"></div>
    
</h2>
<p>All of the tools mentioned above are primarily developed and maintained by companies. This raises the question, if the tools are FOSS (Free and Open Source), what are their business models?</p>
<p>ByteDance of course owns TikTok. They make enough money already and can afford contributing to open-source if they so chose. My theory is that ByteDance likely wants to continue contributing to open-source to put them in the same positive light as Western tech companies (for example Meta, who developed many open-source projects including React, Docusaurus and <a href="https://www.llama.com/"  target="_blank" rel="noreferrer">Llama</a>).</p>
<p>On the other hand, Astral and VoidZero are both venture-backed. While they can afford to lose money for a period while gaining users, eventually they will want to find a way to extract value. In the past, when the founders of the companies were asked about this, they gave somewhat vague statements.</p>
<p>However, more recently, Astral introduced <a href="https://astral.sh/pyx"  target="_blank" rel="noreferrer">pyx</a> (a Python-native package registry):</p>

    <div class="admonition quote">
      <div class="admonition-header"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path d="M448 296c0 66.3-53.7 120-120 120l-8 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l8 0c30.9 0 56-25.1 56-56l0-8-64 0c-35.3 0-64-28.7-64-64l0-64c0-35.3 28.7-64 64-64l64 0c35.3 0 64 28.7 64 64l0 32 0 32 0 72zm-256 0c0 66.3-53.7 120-120 120l-8 0c-17.7 0-32-14.3-32-32s14.3-32 32-32l8 0c30.9 0 56-25.1 56-56l0-8-64 0c-35.3 0-64-28.7-64-64l0-64c0-35.3 28.7-64 64-64l64 0c35.3 0 64 28.7 64 64l0 32 0 32 0 72z"/></svg>
        <span>Quote</span>
      </div>
      <div class="admonition-content">
        <p>Beyond the product itself, <a href="https://astral.sh/pyx"  target="_blank" rel="noreferrer">pyx</a> is also an instantiation of our strategy: <strong>our tools (uv, Ruff, ty, etc.) remain free, open source, and permissively licensed — forever.</strong> Nothing changes there. Instead, we’ll offer paid, hosted services like <a href="https://astral.sh/pyx"  target="_blank" rel="noreferrer">pyx</a> that represent the “natural next thing you need” when you’re already using our tools: the Astral platform.</p>
      </div>
    </div><ul>
<li><a href="https://astral.sh/blog/introducing-pyx"  target="_blank" rel="noreferrer">pyx: a Python-native package registry, now in Beta</a></li>
</ul>
<p>It is likely that VoidZero will go for a similar strategy in the future, by introducing paid services that go alongside the free tools.</p>
<p>The tools themselves are still FOSS, and all are licensed under the permissive <a href="https://opensource.org/license/mit"  target="_blank" rel="noreferrer">MIT License</a>. These companies know that if they ever attempt to change the license or terms for these tools, the community will immediately fork the projects (as has happened <em>many</em> times in the past with <em>other</em> open-source projects).</p>

    <div class="admonition note">
      <div class="admonition-header"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M0 64C0 28.7 28.7 0 64 0L224 0l0 128c0 17.7 14.3 32 32 32l128 0 0 125.7-86.8 86.8c-10.3 10.3-17.5 23.1-21 37.2l-18.7 74.9c-2.3 9.2-1.8 18.8 1.3 27.5L64 512c-35.3 0-64-28.7-64-64L0 64zm384 64l-128 0L256 0 384 128zM549.8 235.7l14.4 14.4c15.6 15.6 15.6 40.9 0 56.6l-29.4 29.4-71-71 29.4-29.4c15.6-15.6 40.9-15.6 56.6 0zM311.9 417L441.1 287.8l71 71L382.9 487.9c-4.1 4.1-9.2 7-14.9 8.4l-60.1 15c-5.5 1.4-11.2-.2-15.2-4.2s-5.6-9.7-4.2-15.2l15-60.1c1.4-5.6 4.3-10.8 8.4-14.9z"/></svg>
        <span>Note</span>
      </div>
      <div class="admonition-content">
        <p><strong>UPDATE:</strong> VoidZero has launched <a href="https://viteplus.dev/"  target="_blank" rel="noreferrer">Vite+</a>.</p>
      </div>
    </div>
<h2 class="relative group">My Experience
    <div id="my-experience" class="anchor"></div>
    
</h2>
<ul>
<li>
<p>I have listed a lot of tools from these companies, of course I have not tried all of the tools mentioned above.</p>
</li>
<li>
<p>I have been using Astral’s projects, uv and Ruff, and had good experience with both, and I want to try ty as well. As I’m getting more into TypeScript development with React, Docusaurus and Cloud Development Kit (CDK), I have been trying out some of the TypeScript tools as well.</p>
</li>
<li>
<p>In the case of Docusaurus, I tried <a href="https://docusaurus.io/blog/releases/3.6#docusaurus-faster"  target="_blank" rel="noreferrer">Docusaurus Faster</a> which uses Rspack (by Web Infra), as well as SWC and Lightning CSS. This makes it almost as fast as Rspress (another project by Web Infra). The difference in build times is immediately noticeable compared to building Docusaurus with Webpack.</p>
</li>
<li>
<p>The speed difference is also felt in uv; compared to pip, uv downloads the same packages noticeably faster. I have further explained my love for uv in <a href="/articles/uv-is-incredible/" >uv is incredible</a>.</p>
</li>
<li>
<p>Ruff works well as both a Linter and Formatter. Ty does the same for type checking in Python.</p>
</li>
<li>
<p>Besides the speed, I have also noticed these tools tend to be <em>easier</em> to use than the older, less modern tools that the aim to replace. The focus on <a href="https://en.wikipedia.org/wiki/Developer_Experience"  target="_blank" rel="noreferrer">Developer Experience</a> (DX or DevEx) is apparent.</p>
</li>
<li>
<p>Recently, I have been trying out TypeScript Linters and Formatters and wrote about the Rust Alternatives. Oxc looks promising, it currently has a <a href="https://oxc.rs/docs/guide/usage/linter.html"  target="_blank" rel="noreferrer">Linter</a>, while the Prettier-compatible <a href="https://oxc.rs/docs/contribute/formatter"  target="_blank" rel="noreferrer">Formatter</a> is still under development. Once the <a href="https://oxc.rs/docs/contribute/formatter"  target="_blank" rel="noreferrer">Formatter</a> is ready, I will try using Oxc (instead of ESLint + Prettier), at least for projects that don’t require specific ESLint plugins that aren’t yet <a href="https://github.com/oxc-project/oxc/issues/481"  target="_blank" rel="noreferrer">supported by Oxc</a>.</p>
</li>
</ul>

    <div class="admonition note">
      <div class="admonition-header"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><path d="M0 64C0 28.7 28.7 0 64 0L224 0l0 128c0 17.7 14.3 32 32 32l128 0 0 125.7-86.8 86.8c-10.3 10.3-17.5 23.1-21 37.2l-18.7 74.9c-2.3 9.2-1.8 18.8 1.3 27.5L64 512c-35.3 0-64-28.7-64-64L0 64zm384 64l-128 0L256 0 384 128zM549.8 235.7l14.4 14.4c15.6 15.6 15.6 40.9 0 56.6l-29.4 29.4-71-71 29.4-29.4c15.6-15.6 40.9-15.6 56.6 0zM311.9 417L441.1 287.8l71 71L382.9 487.9c-4.1 4.1-9.2 7-14.9 8.4l-60.1 15c-5.5 1.4-11.2-.2-15.2-4.2s-5.6-9.7-4.2-15.2l15-60.1c1.4-5.6 4.3-10.8 8.4-14.9z"/></svg>
        <span>Note</span>
      </div>
      <div class="admonition-content">
        <p><strong>UPDATE:</strong> <a href="https://oxc.rs/docs/guide/usage/formatter"  target="_blank" rel="noreferrer">oxfmt</a> is now available and I have been using it in my projects alongside <a href="https://oxc.rs/docs/guide/usage/linter.html"  target="_blank" rel="noreferrer">oxlint</a>.</p>
      </div>
    </div><ul>
<li>I wrote more about using Oxc in <a href="/articles/oxc-workflow/" >Oxc Workflow</a>).</li>
</ul>

<h3 class="relative group">Vite
    <div id="vite" class="anchor"></div>
    
</h3>
<ul>
<li>
<p>Out of all the projects I listed here, Vite is probably the most widely used. It’s popular enough to have gotten its own documentary: <a href="https://youtu.be/bmWQqAKLgT4"  target="_blank" rel="noreferrer">Vite: The Documentary - YouTube</a></p>
</li>
<li>
<p>I have been using Vite for React apps, notably <a href="https://github.com/CALMe25"  target="_blank" rel="noreferrer">CALMe</a>. Ever since <a href="https://github.com/facebook/create-react-app"  target="_blank" rel="noreferrer">create-react-app</a> has been deprecated, I have been consistently seeing Vite as one of the top recommendations, including in the <a href="https://react.dev/"  target="_blank" rel="noreferrer">React Documentation</a>: <a href="https://react.dev/learn/creating-a-react-app#start-from-scratch"  target="_blank" rel="noreferrer">Creating a React App</a> and <a href="https://react.dev/learn/build-a-react-app-from-scratch"  target="_blank" rel="noreferrer">Build a React app from Scratch</a>.</p>
</li>
<li>
<p>Vite is being integrated with Rolldown: <a href="https://vite.dev/guide/rolldown"  target="_blank" rel="noreferrer">Rolldown Integration | Vite</a></p>
</li>
</ul>
<hr>
<p><em>Featured image by <a href="https://unsplash.com/@tonchik?utm_source=hugo&utm_medium=referral"  target="_blank" rel="noreferrer">Anton Savinov</a> on <a href="https://unsplash.com/?utm_source=hugo&utm_medium=referral"  target="_blank" rel="noreferrer">Unsplash</a>.</em></p>
]]></content><author><name>Ro'i Bandel</name></author><category term="tools" label="Tools" scheme="https://www.towerofkubes.com/tags/tools/"/><category term="programming" label="Programming" scheme="https://www.towerofkubes.com/tags/programming/"/><category term="typescript" label="Typescript" scheme="https://www.towerofkubes.com/tags/typescript/"/><category term="javascript" label="Javascript" scheme="https://www.towerofkubes.com/tags/javascript/"/><category term="python" label="Python" scheme="https://www.towerofkubes.com/tags/python/"/><category term="astral" label="Astral" scheme="https://www.towerofkubes.com/tags/astral/"/><category term="uv" label="Uv" scheme="https://www.towerofkubes.com/tags/uv/"/><published>2025-10-12T00:00:00Z</published></entry></feed>