Open-source project
google/wireit avatar
google/wireit

google/wireit: Smarter npm Scripts with Dependency Graph and Caching

Wireit upgrades your npm/pnpm/yarn scripts to make them smarter and more efficient.

6,426 stars129 forksTypeScriptApache-2.0

At a glance

What is it?
Wireit wraps existing npm, pnpm and yarn scripts so they run in dependency order, skip when output is fresh, and cache results. It is a build orchestrator for people who do not want to leave npm run behind.
Who is it for?
Wireit suits teams already living inside npm scripts who want parallel execution, freshness checks and caching without adopting a separate build tool. It is the wrong choice if your build is not expressed as package.json scripts, or if you need remote caching outside GitHub Actions, since the README only documents local caching and GitHub Actions caching.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Wireit changes about npm run

The problem Wireit addresses is that npm scripts are flat. If `bundle` needs `build` to finish first, nothing in package.json says so; you either chain commands with `&&` or remember the order. Wireit moves each command into a `wireit` section of package.json and replaces the script body with the `wireit` command. From then on, `npm run bundle` runs `build` first if a dependency is declared, and runs independent scripts in parallel when the graph allows it.

The audience is anyone with a package.json and more than one script that depends on another. The README lists single packages, npm workspaces, and other monorepos as supported layouts, and notes that `node --run`, yarn and pnpm all work. You keep typing the commands you already know, which is the main difference from tools that ask you to learn a new task runner syntax.

The dependency graph and how scripts actually execute

Dependencies are declared as a list of script names under `wireit.<script>.dependencies`. Wireit builds a graph from those edges and runs scripts in parallel whenever the graph permits. The README gives an example where `B` and `C` both feed into `A`: `B` and `C` run at the same time, and `A` waits for both.

Two details matter more than the graph itself. First, you can depend on a vanilla npm script that was never configured for Wireit. The README states such scripts are always safe to use as dependencies, they simply are not optimized. That means migration can be incremental, one script at a time. Second, a script defined only in the `wireit` section, with no matching entry in `scripts`, can be used as a dependency but never run directly. That is a deliberate way to keep internal steps out of the user-facing command list.

Cross-package dependencies use the syntax `<relative-path>:<script-name>`, and the README says all cross-package dependencies should start with a `.`, as in `"../other-package:build"`. This is what makes the tool usable across an npm workspace rather than inside a single package.

Parallelism has a default: up to 2 scripts per logical CPU core. The README suggests lowering it if large builds starve resources, and shows `WIREIT_PARALLEL=1` to serialize everything. There is also a coordination rule worth knowing. If two separate `npm run` commands target the same Wireit script at the same time, only one runs while the others wait, which prevents two processes writing the same output files. Setting `output` to an empty array removes that restriction.

Installing Wireit and converting a first script

Wireit ships on npm as a dev dependency. The README gives a single install command.

bash
npm i -D wireit

Conversion is a two-part edit. The original command leaves the `scripts` block and reappears under `wireit`, with the script body replaced by the `wireit` command itself.

json
{
  "scripts": {
    "build": "wireit"
  },
  "wireit": {
    "build": {
      "command": "tsc"
    }
  }
}

After that edit, `npm run build` invokes Wireit, which invokes `tsc`. The README also asks you to keep Wireit's working directory out of version control.

bash
echo .wireit >> .gitignore

Wireit stores caches and other data in `.wireit`, so leaving it untracked avoids committing build state. If you use VSCode, the `google.wireit` extension adds hover documentation, autocomplete, diagnostics for common mistakes, and a refactoring that converts an npm script to use Wireit. It installs with `code --install-extension google.wireit`.

Freshness, caching, and the globs you have to get right

The efficiency claims rest on two mechanisms. Freshness means Wireit skips a script whose inputs and outputs have not changed since the last run. Caching means it can restore output instead of recomputing it. Both depend entirely on the `files` and `output` fields you declare, and the README documents default excluded paths for glob matching.

This is the sharp edge. If `files` is too narrow, a change that affects the build will not be noticed and a stale result gets reused. If `output` is wrong, the cache stores the wrong artifacts, or the empty-array case silently disables the run-exclusion rule described above. Wireit cannot infer your inputs; it only knows what you tell it. The repository's own package.json shows the pattern in practice, with `files` listing `src/**/*.ts` and `tsconfig.json`, and `output` listing `lib/**` and `.tsbuildinfo`.

Caching is documented in two forms: local caching, and caching on GitHub Actions, which the feature list describes as free. The README does not document a general remote cache backend outside that CI context, so if you run CI somewhere else, local caching is what you get.

Watch mode, services, and where Wireit is the wrong tool

Wireit can watch a script and re-run it on changes, and it has a services concept for long-running processes. Those features push it toward being a small task runner rather than just a script wrapper.

The limitation is scope. Wireit operates on package.json scripts. If your build is a Makefile, a Bazel workspace, a Gradle project, or a set of shell scripts that never touch npm, Wireit has nothing to attach to. It also assumes Node 18 or newer, per the `engines` field in the repository's package.json, so older Node runtimes are out.

There is a subtler failure mode around the freshness model. Because skipping is based on declared files and outputs, a script that reads state Wireit cannot see (an environment variable, a file outside the declared globs, a network fetch) may be skipped when it should run. The README's environment variable reference covers Wireit's own variables, but nothing makes an arbitrary env var part of the fingerprint unless you account for it yourself. Teams that hit this usually end up widening `files` until the skip rate drops, which trades away some of the speed they adopted the tool for.

How Wireit differs from Turborepo and Nx

The closest alternatives are monorepo task runners such as Turborepo and Nx. The difference is where the graph lives. Turborepo and Nx define pipelines in their own configuration files and expect you to run tasks through their CLI, which gives them a single place to reason about every package at once. Wireit keeps the graph inside each package's package.json, under the `wireit` key, and you keep invoking `npm run`. Cross-package edges are written as relative paths like `"../other-package:build"` rather than as a pipeline entry in a root config.

That has consequences in both directions. Wireit is easier to adopt piecemeal, because a package can opt in without a root-level configuration and vanilla scripts still work as dependencies. It is harder to get a whole-repository view, because there is no root pipeline file to read; you reconstruct the graph by following dependency strings across packages. If your monorepo already standardizes on a root task configuration, Wireit asks you to give that up. If you have resisted that standardization, Wireit is the option that does not require it.

Licence, maintenance, and upgrade cost

Wireit is published under Apache-2.0 by Google LLC, and the repository includes a LICENSE file at the top level. Apache-2.0 permits commercial use and modification and includes a patent grant; it also requires that you preserve notices. That is a summary of the identifier, not legal advice, and your counsel should review it if the distinction matters to you.

The repository is not archived, and the last push was on 2026-09-21, so the codebase is being touched. The published version in the repository's package.json is 0.14.13, and the version is still below 1.0, which is the practical signal for upgrade cost: minor releases can carry breaking changes under semver conventions. The CHANGELOG.md at the top level is where release notes live, and the README does not document a rollback procedure, so pinning a version in your lockfile is the only revert path documented. The repository also carries a schema.json, which is what the VSCode extension and the JSON schema test script use to validate configuration.

Editorial conclusion

Wireit suits teams already living inside npm scripts who want parallel execution, freshness checks and caching without adopting a separate build tool. It is the wrong choice if your build is not expressed as package.json scripts, or if you need remote caching outside GitHub Actions, since the README only documents local caching and GitHub Actions caching. Before adopting, verify that every script you intend to wrap declares accurate files and output globs, because freshness and caching depend on them, and add .wireit to .gitignore.

Frequently asked questions

What is google/wireit?

Wireit is a tool that upgrades npm, pnpm and yarn scripts so they run dependencies automatically, execute in parallel where the graph allows, skip when output is fresh, and cache results. It works with `npm run` rather than replacing it, and is published on npm as the `wireit` package.

How do I set up Wireit in a project?

Install it with `npm i -D wireit`, move a command out of the `scripts` block into a `wireit` section of package.json, and replace the original script body with `wireit`. Then add `.wireit` to your `.gitignore`.

How do I use Wireit with npm scripts?

You keep running `npm run <script>`. Wireit intercepts the script because its body is the `wireit` command, reads the matching entry under the `wireit` key, and runs the configured `command`, resolving any `dependencies` first.

Is there an alternative to Wireit for orchestrating npm scripts?

Monorepo task runners such as Turborepo and Nx solve a similar problem, but they define pipelines in their own configuration files and expect you to run tasks through their CLI. Wireit keeps the graph in each package.json and leaves `npm run` in place.

Official sources

  1. google/wireit on GitHub
  2. Issues
  3. License: Apache-2.0
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/google-wireit.svg)](https://hysenlabs.com/projects/google-wireit)