> ## Documentation Index
> Fetch the complete documentation index at: https://site.aspect.build/llms.txt
> Use this file to discover all available pages before exploring further.

# Pnpm v10 and rules_js: Better Alignment and Improved Build Determinism

> Pnpm v10 improves build determinism with rules_js, offering enhanced performance and reliability for Bazel-based workflows

export const BlogPost = ({title, date, authors, tags, image, children}) => {
  const tagList = tags ? tags.split(", ").filter(Boolean) : [];
  const tagSlug = t => t.toLowerCase().replace(/&/g, "").replace(/\+/g, "").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
  const formattedDate = date ? new Date(date + "T00:00:00").toLocaleDateString("en-US", {
    year: "numeric",
    month: "long",
    day: "numeric"
  }) : "";
  return <section className="w-full flex justify-center px-4 py-12 md:py-16">
      <div style={{
    maxWidth: "800px",
    width: "100%"
  }}>
        {image && (typeof image === "string" ? <img noZoom src={image} alt={title} className="w-full rounded-xl mb-8" style={{
    maxHeight: "400px",
    objectFit: "cover"
  }} /> : <div className="blog-post-hero-image">{image}</div>)}
        <h1 className="text-3xl md:text-4xl font-bold text-zinc-900 dark:text-white">
          {title}
        </h1>
        <div className="flex flex-wrap items-center gap-3 mt-4 text-sm text-zinc-500 dark:text-zinc-400">
          {authors && <span>{authors}</span>}
          {authors && formattedDate && <span>·</span>}
          {formattedDate && <span>{formattedDate}</span>}
        </div>
        {tagList.length > 0 && <div className="flex flex-wrap gap-2 mt-3">
            {tagList.map(tag => <a key={tag} href={"/blog/tags/" + tagSlug(tag)} className="px-2 py-0.5 rounded-full text-xs bg-zinc-100 dark:bg-zinc-800 text-zinc-600 dark:text-zinc-400 hover:bg-blue-100 dark:hover:bg-blue-900/40 hover:text-blue-700 dark:hover:text-blue-300 transition">
                {tag}
              </a>)}
          </div>}
        <hr className="my-8 border-zinc-200 dark:border-zinc-700" />
        <div className="prose dark:prose-invert max-w-none">{children}</div>
      </div>
    </section>;
};

export const MarketingPage = () => <div className="marketing-page-marker" style={{
  display: "none"
}} />;

export const Section = ({children, className = "", gray = false, dark = false, id}) => <section id={id} className={`w-full flex justify-center px-4 py-16 md:py-24 ${gray ? "bg-gray-50 dark:bg-zinc-900" : dark ? "bg-zinc-900 dark:bg-zinc-950" : ""} ${className}`}>
    <div className="w-full" style={{
  maxWidth: "1140px"
}}>
      {children}
    </div>
  </section>;

<MarketingPage />

<BlogPost title="Pnpm v10 and rules_js: Better Alignment and Improved Build Determinism" date="2025-07-22" authors="Jason Bedard" tags="JavaScript, Releases, Bazel">
  <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/blog/hashnode/hn-8e9d8d5326.jpeg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=1c827c3d448a78ce938e4ea2508e01c5" alt="" className="blog-post-cover" width="1365" height="768" data-path="images/blog/hashnode/hn-8e9d8d5326.jpeg" />

  **Pnpm v10** was released [earlier this year](https://github.com/pnpm/pnpm/releases/tag/v10.0.0). After some [initial issues](https://github.com/pnpm/pnpm/issues/9531) release [10.11.1](https://github.com/pnpm/pnpm/releases/tag/v10.11.1) now fully passes regression tests with [rules\_js](https://github.com/aspect-build/rules_js).

  This release brings notable improvements in **hermeticity**, **performance**, and **reliability**, aligning `pnpm` more closely with the expectations and requirements of Bazel-based workflows that use `rules_js`.

  ### (Only) Built Dependencies

  Since pnpm v9 rules\_js has required packages with build steps to be manually declared in the `pnpm.onlyBuiltDependencies` field of `package.json`. Now pnpm v10 has the exact same requirements as rules\_js, see pnpm [#8897](https://github.com/pnpm/pnpm/pull/8897) (as well as [#7710](https://github.com/pnpm/pnpm/pull/7710) and [#7716](https://github.com/pnpm/pnpm/pull/7715) for more background).

  Explicitly declaring which packages require a build step improves determinism and hermeticity in both pnpm and rules\_js. This allows `rules_js` to model Bazel build actions without first needing to download and inspect package contents.

  This change was followed-up with `pnpm.neverBuiltDependencies` ([#8958](https://github.com/pnpm/pnpm/pull/8958)) in pnpm 10.1 to suppress `pnpm install` warnings about packages containing install logic without being listed in `pnpm.onlyBuiltDependencies`.

  ### Secure SHA256 Hashing

  Pnpm v10 has switched to more secure **SHA256** hashing of content in the `pnpm-lock.yaml` file, see [#8530](https://github.com/pnpm/pnpm/pull/8530). Bazel and rules\_js already use sha256/512 for integrity checks, and rules\_js will continue to align with pnpm lockfiles where pnpm v10 has upgraded to sha256.

  ### Configuration changes

  Pnpm v10 has made many other configuration related changed that do not directly effect integration with rules\_js, but may effect your experience when upgrading such as:

  * default hoisting has changed [#8378](https://github.com/pnpm/pnpm/issues/8378)

  * `NODE_ENV` is now ignored on install [#8827](https://github.com/pnpm/pnpm/issues/8827)

  * the `@yarnpkg/extensions` package was upgraded, this may alter resolved dependencies in edge cases

  ### Catalogs

  While actually a pnpm v9.5 feature, [pnpm catalogs](https://pnpm.io/catalogs) is a feature worth mentioning again. Catalogs have provided a way to stop repeating version numbers throughout your `package.json` files and declare a single version for a package in a single location, while keeping fine grained dependencies in your projects.

  Catalogs are especially useful in large monorepos where Bazel and rules\_js are normally used.

  Catalogs are used by pnpm when generating the `pnpm-lock.yaml` file and does not change the underlying lockfile format, so rules\_js supports comes for free.

  ### Final Thoughts

  Like pnpm v9 last year, pnpm v10 continues to move toward more deterministic builds that continue to align with Bazel and rules\_js, further proving pnpm was the right choice for the Bazel and rules\_js ecosystems.

  See the [pnpm v10 release](https://github.com/pnpm/pnpm/releases/tag/v10.0.0) and [followup releases](https://github.com/pnpm/pnpm/releases) for a full list of changes.
</BlogPost>
