Quartet / Quintet

2026-09-06  ·  npm · node · typescript · programming

You Cannot Tell It Does Not Ship Until You Ship It

I published three CLIs of my own to npm. All three turned out to be broken, found in the last few minutes before publishing.

Every one of them ran locally. The tests passed. What was broken was the installed state, and that is not visible until you actually install it.

1. npm cannot run TypeScript inside node_modules

Node 22.18 and later runs .ts directly, so I pointed bin at the source and expected to ship with no build step.

{ "bin": { "mytool": "src/cli.ts" } }

It works locally. Packed and installed, it does this:

Error [ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING]:
Stripping types is currently unsupported for files under node_modules,
for ".../node_modules/@scope/mytool/src/cli.ts"

Node refuses to strip types from anything under node_modules. It is a deliberate restriction — a dependency's contents should not be transformed at runtime.

So npx fails on the very first run.

The fix

Compile and ship dist/. A clone still runs the source with no build step.

{
  "bin": { "mytool": "dist/cli.js" },
  "files": ["dist", "README.md", "LICENSE"],
  "scripts": { "prepack": "tsc -p tsconfig.json" }
}

Set rewriteRelativeImportExtensions (TypeScript 5.7+) so import "./x.ts" in the source becomes "./x.js" in the output:

{ "compilerOptions": { "rewriteRelativeImportExtensions": true } }

typescript is a devDependency. The published package still has zero runtime dependencies.

2. prepack alone does not reach anyone installing from git

npx github:owner/repo is a real way people install things, and plenty of READMEs recommend it.

prepack runs for the registry. It does not run for a git install. The package lands with no dist/, so the file bin points at does not exist:

sh: mytool: command not found

Add prepare. That one does run on git installs.

{
  "scripts": {
    "build":   "tsc -p tsconfig.json",
    "prepare": "tsc -p tsconfig.json",
    "prepack": "tsc -p tsconfig.json"
  }
}

Writing both looks redundant. With only one, the other path is guaranteed broken.

3. The install command in my README had never worked

This is the one that mattered.

A published repository's README said:

npx github:quintetkit/ccheck        # from your repository root

I ran it in an empty directory:

npm error code ENOENT
npm error enoent Could not read package.json

npm cannot install a repository that has no package.json.

That repository had none — it has zero dependencies and runs with node src/cli.ts, so it never seemed necessary. Everyone who followed the first instruction in that README got this error. Since the day it was published.

It had no stars, so the damage was small. Finding this after traffic arrived would have been the expensive version.

What these share

All three are the same shape: "works on my machine" and "works as installed" are different claims.

what you can see what you cannot
node src/cli.ts runs it will not run inside node_modules
npm pack succeeds a git install has no dist
a clone works npm cannot install a repo with no package.json

Looking only at the left column keeps the right column invisible forever.

Put the check in CI

The fix is to build the installed state and actually run it.

- name: it still runs once packaged
  run: |
    npm pack --silent
    tmp=$(mktemp -d); cd "$tmp"
    npm init -y > /dev/null
    npm install --silent "$GITHUB_WORKSPACE"/*.tgz
    npx mytool --help > /dev/null

npm pack succeeding guarantees nothing. Installing and running it does.

The git path is one line:

cd $(mktemp -d) && npx -y github:owner/repo --help

In an empty directory, so no local cache or global install is answering for it.

Worth doing before you publish

Takeaways


Related


I publish the configuration for splitting Claude Code into separate personas — Architect, Coder, Reviewer, Conflict Resolver — under MIT. Copy it, run ./setup.sh, and it works. It does not depend on your tech stack.

https://github.com/quintetkit/quartet

I built one real tool using nothing but this workflow. Every Issue, PR, review and merge is still there. The parts that went wrong were not deleted.

https://github.com/quintetkit/mdlinkcheck

The version that adds a UI Designer persona, review criteria, a per-Issue parallel execution script and a 10-chapter guide is on the product page.

The full kit — five personas, the scripts and the complete guide in English and Japanese — is on BOOTH, a Japanese store with an English interface that takes international cards.

https://quartet-dev.booth.pm/items/8807156

The workflow itself is available

Quartet, the four-persona version, is published free under MIT. Quintet adds a UI Designer persona, review criteria, a per-Issue parallel execution script, and a 10-chapter guide.

See the free version Product page