# git-js: the package is simple-git, the version is 4.0.2, and the first example forces a clean

> git-js is the repository behind the simple-git package, a wrapper that runs git commands from Node.js instead of a shell, with task chaining, per-command configuration and a plugin system covering the binary path, the environment, standard input and process ownership. Its fourth major version exists mostly to stop you typing abbreviated git options, and the repository contains two places where a forced clean is the documented way to get things done.

**steveukx/git-js** — A light weight interface for running git commands in any node.js application.

- Repository: https://github.com/steveukx/git-js
- Stars: 3,858 · Forks: 341
- Language: TypeScript
- License: MIT
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/steveukx-git-js

## The repository is git-js and the package is simple-git

Nothing about the two names matches, and the first practical consequence is that searching for the repository does not find the package. The documentation is titled for the package, and the published artifact is named after it, while the hosting path is the abbreviation. Two packages were published from this repository on the same day: the main library at its fourth point zero point two, and a scoped sub-package with its own independent version line. That second one is the reason there is a packages directory beside the directory holding the main package, so this is a monorepo rather than a single library, and the release tags follow the name-at-version convention instead of a bare version tag. The manifest at the root belongs to neither of them: it is a private workspace package with its own name and a version of three point one point one, which is left over and does not track the library it builds.

## Version four blocks abbreviated options as an attack-vector measure

The upgrade section is the most security-conscious paragraph in the file. Two changes are named for the fourth major version: how the library is loaded and initialised was standardised, and the use of abbreviated git options in commands was blocked, described as a reduction in attack vectors. The second one is concrete. A command you write as a short flag is refused; the same command spelled out is accepted. The rationale is that unambiguous long options cannot be reinterpreted by whatever is constructing the command, which is the class of problem that made short git options attractive in the first place. The cost is equally concrete: callers migrating from the third major cannot leave abbreviated options anywhere in their command strings, which is why a separate migration document with step-by-step examples is linked. The file hedges that in many cases the upgrade will be seamless, and that hedge is the thing to test against your own command list.

```javascript
const { simpleGit, CleanOptions } = require('simple-git');
simpleGit().clean(CleanOptions.FORCE);
```

## Two forced cleans, one of them the first example

The library's own clean script deletes untracked and ignored files from the working tree, excluding only the dependency directory and the two source directories that hold the packages. That is a repository-level operation with real consequences for anything uncommitted, and it is wired to a script name a contributor is expected to run. Then there is the documentation, whose first example in all three module systems is a forced clean, expressed through a named constant rather than a short flag. So the class of command the fourth major version refuses to accept as abbreviated text is the class the library hands you a constant for, and the repository's own housekeeping does it in full. Neither is wrong on its own, but a reader arriving at the documentation sees a destructive operation as the introduction, with no warning attached to it.

## Four configuration defaults and one kept for compatibility

The configuration surface is presented as a properties object with four values, all of them optional and all of them shown as defaults: the working directory taken from the process, the binary name, a concurrency limit of six child processes, and output trimming switched off. The first argument to the main function is deliberately loose. It can be a string standing for the working directory, an options object, or nothing at all, with an optional options object as the second parameter, and the file keeps the older form of passing the directory and options separately for backward compatibility. Per-command configuration is the other mechanism: an array of settings passed to the instance is prefixed onto every command the instance runs, so a proxy setting given once applies to every subsequent call without being written into the git configuration on disk.

## Ten plugins, two of them pointing at the same document

The plugin list covers the surfaces that matter when a library wraps a child process, and it does so explicitly: a plugin to change which binary is spawned, one to allow named environment variables through to it, one to write to its standard input, and one to set the system user and group its processes run as. Alongside those sit behavioural plugins for detecting when a process ends, for detecting errors, for streaming progress, for timing out a process that hangs, and for aborting pending and future tasks, which is the only one with a runtime requirement, node sixteen or newer. Two entries in the list, one for allowing environment variables and one for opting out of the safety precautions, link to the same document, so the list is not a reliable index into that documentation. The opt-out plugin is the interesting one: opting out of safety precautions is a supported, documented configuration.

## Two error-handling patterns that contradict each other

The guidance on catching errors offers two patterns and then states a rule that undercuts the second. The first wraps the whole chain in a single try block, which is straightforward. The second catches individual steps so that the main chain carries on executing rather than jumping to the catch on the first error, and the example attaches an empty handler to the first step specifically to let the second one run. Immediately after that, the file says that if any step in the chain results in an error, all pending steps will be cancelled, and points the reader to a section on running tasks in parallel instead of in series. Whether per-step catching also suppresses that cancellation is exactly the question a reader needs answered, and the two statements sit three lines apart. The link to that parallel section is also written with its angle brackets in the wrong order.

## One linter, changeset releases, and a resolutions key in a pnpm workspace

The tooling is unusually tidy in one respect and inconsistent in another. A single configuration file handles both linting and formatting, with one script to check and one to fix, and there is no second formatter configuration anywhere in the tree. Releases are driven by a changesets directory with the matching tooling as dependencies, which is why the release tags carry a version per package. The inconsistency is in the dependency pins: the root manifest declares a package-manager resolutions field pinning the compiler to one range while the same compiler appears in the dependencies with a looser one, and resolutions is a Yarn-era key in a workspace that declares itself as pnpm. There are three test scripts, including one that runs the suite on Windows and one that tests against installed consumers, plus a pinned Node version file and a small tooling directory with a script that resets generated package manifests.

## Conclusion

git-js fits a Node.js service that needs to run git as part of its work rather than as a manual step, and that wants each command written out rather than abbreviated. Four things to settle first. The package name and the repository name do not match, so search for the package. Version four refuses abbreviated options, which is a deliberate security choice with a real cost: every command must be spelled out, and the hedge that most upgrades will be seamless is worth testing on your own command list. Read the plugin list before you reach for the environment or stdin plugins, since those are the surfaces that decide what a spawned git process can see and do, and the library ships a documented plugin for opting out of its own safety precautions. And note that the first example in the documentation is a forced clean, which is the operation most likely to surprise someone who copies it.

## FAQ

### Is Git difficult to learn?

That is not what this repository is about. It is a Node.js library for running git commands from application code, and its fourth major version makes that harder in one specific way by refusing abbreviated git options, so every command must be written out in full rather than as a short flag.

### Is Git a coding language?

Not this repository's subject. It is a wrapper around the git binary, which has to be installed and callable under the name git, and the plugin list exists to control how that child process is launched: which binary, which environment variables, what goes into standard input, and which system user and group it runs as.

### Can GitHub run JS?

Not addressed here. What this repository documents is the Node.js side: chaining tasks on a returned instance, awaiting each step, catching errors either around the whole chain or per step, and prefixing every command with per-command configuration that is never written to disk.

## Sources

- [Issues](https://github.com/steveukx/git-js/issues)
- [License: MIT](https://github.com/steveukx/git-js/blob/main/LICENSE)
- [README](https://github.com/steveukx/git-js/blob/main/README.md)
- [Releases](https://github.com/steveukx/git-js/releases)
- [steveukx/git-js on GitHub](https://github.com/steveukx/git-js)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/steveukx-git-js
