> ## 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.

# Bazel for Frontend: Introducing rules_js

> Transform your frontend workflow with rules_js: faster builds, simplified tooling, and improved performance. Get started now!

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="Bazel for Frontend: Introducing rules_js" date="2022-06-15" authors="Alex Eagle" tags="JavaScript, Bazel">
  <img noZoom src="https://mintcdn.com/aspectbuild/x1L7Iep716jCyJVo/images/blog/hashnode/hn-b5daa3a554.jpeg?fit=max&auto=format&n=x1L7Iep716jCyJVo&q=85&s=daf7fccd7c33a1c482a9a360a016030c" alt="" className="blog-post-cover" width="1600" height="1067" data-path="images/blog/hashnode/hn-b5daa3a554.jpeg" />

  At Aspect we've been working on supporting the [Bazel build tool](https://bazel.build) in the frontend/JS ecosystem for [five years](https://github.com/bazelbuild/rules_nodejs/graphs/contributors). We started from how Node.js programs are run internally at Google. It worked okay, but to be honest, it was never great.

  A few of the problems our users have endured:

  * Too slow to run a full package manager install whenever a file like `package.json` changes

  * Having separate source and output folders breaks expectations of Node.js tooling. For example, TypeScript required a tricky `rootDirs` setting to resolve everything.

  * No support for "workspaces" so every `package.json` had to be independently installed

  * Performance: treating npm packages as directories rather than thousands of files was bolted-on late in the project and hard to adopt.

  rules\_js solves these problems! There's lots of info in our README: [https://github.com/aspect-build/rules\\\_js](https://github.com/aspect-build/rules\\_js). Note that in the best case scenario, Bazel only needs to install a single npm package if that's the only one in the transitive dependency closure of the requested build/test targets!

  The first Beta release of rules\_js is out: [v1.0.0-beta.0](https://github.com/aspect-build/rules_js/releases/tag/v1.0.0-beta.0) along with accompanying rulesets for some common tools like TypeScript, ESBuild, SWC, Rollup, Terser, Jest, and Webpack, listed at [https://github.com/aspect-build](https://github.com/aspect-build).

  So now is a great time to do some prototyping. Follow our [migration guide](https://github.com/aspect-build/rules_js/blob/main/docs/migrate.md) and let us know how we can improve our docs to help you get up and running quickly.

  I'll be giving a talk on it next week: [https://events.skillsmatter.com/bazelx2022](https://events.skillsmatter.com/bazelx2022) and we hope to publish the 1.0.0 final around that time.

  Thank you to so many of our partners:

  * Our awesome coworkers at [http://aspect.dev](http://aspect.dev) for working through design and public API review over the last year

  * Adobe for being an early adopter to help us shake out the bugs

  * Our OSS community for evaluating the design as it has evolved

  * [Pete](https://twitter.com/octogonz_) from [Rush.js](https://rushjs.io/) for showing us how pnpm is the perfect fit

  * Ryan Day at Google for pushing us to use npm-native abstractions
</BlogPost>
