# open-wc: the lint script that rebuilds types, and the package table with no versions in it

> Open Web Components is a JavaScript monorepo of defaults for web component work: a scaffolder, an eslint preset, a rollup config, five testing entries and a dev server that now lives elsewhere. Read the root package.json against the README guide block and the gaps show up in the first screen.

**open-wc/open-wc** — Open Web Components: guides, tools and libraries for developing web components.

- Repository: https://github.com/open-wc/open-wc
- Website: https://open-wc.org/
- Stars: 2,399 · Forks: 435
- Language: JavaScript
- License: MIT
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/open-wc-open-wc

## npm run lint deletes packages/*/types before it checks anything

The root package.json opens its lint entry point with `run-p lint:*`, so three tasks start at the same moment: `lint:eslint`, `lint:prettier` and `lint:types`. The third one is a redirect. `lint:types` is set to `npm run types`, and `types` expands to `run-s types:clear types:copy types:build`, whose first entry is `rimraf packages/*/types/`. A lint run therefore wipes the declaration folder of every package in the workspace before a single file is inspected, then rebuilds it by running `node scripts/workspaces-scripts-bin.mjs types:copy` and finally `tsc --build`. Two consequences follow. The lint entry point is a build step wearing a different name, so the time it takes says nothing about linting. And any run that stops between the clear step and the build step leaves the workspace with no type declarations at all, which surfaces later as unresolved imports in editors rather than as a lint error.

## The guide block names npm run test:bs, and the root package.json has no such script

The bottom of the README hands anyone working inside the repository five commands in one fenced block.

```bash
# bootstrap/setup
npm install

# linting
npm run lint

# local testing
npm run test

# testing via browserstack
npm run test:bs

# run commands only for a specific scope
lerna run <command> --scope @open-wc/<package-name> --stream
```

The root package.json defines `test`, `test:web`, `test:node` and `test:node:watch` in that family, and nothing called `test:bs`. The Browserstack line therefore points at a script that does not exist in the file it is meant to be read next to. The package row that would cover the job, `@open-wc/testing-karma-bs`, links to `https://github.com/open-wc/legacy/tree/master/packages/testing-karma-bs`, which is a different repository. The fifth line is a lerna call with a `--scope` filter and a `--stream` flag, and no script in the root file invokes lerna at all: every root script that needs to reach a workspace goes through `node scripts/workspaces-scripts-bin.mjs` instead.

## The lint globs stop at .js and .html while the test glob loads .ts, .mjs and .cjs

`lint:eslint` runs `eslint --ext .js,.html .`, so it examines JavaScript and HTML and nothing else. `lint:prettier` checks `**/*.{js,md}` and `**/package.json`, which means Markdown is reformatted but never linted. `test:node` runs `mocha --exit --retries 3 --timeout 10000` against `packages/*/test-node/**/*.test.{ts,js,mjs,cjs}`, so test files written in TypeScript, in ES modules or in CommonJS do run, while nothing on the lint path ever opens them. The same gap reaches the root of the tree: `web-test-runner.config.mjs`, `web-test-runner.debug.config.mjs`, `rocket.config.mjs` and `workspace-packages.mjs` are four module files, and no lint glob reaches any of them. The two web test runner configs matter most, since the `debug` script hands `--config ./web-test-runner.debug.config.mjs` to the runner and the default `test:web` script takes the other file with no arguments at all.

## Fourteen package rows, fourteen empty version cells, and two rows that leave the repository

The package table carries a Version column, and every cell in it is a link with no link text. The table reads `@open-wc/building-rollup`, `@open-wc/create`, `@open-wc/demoing-storybook`, `@open-wc/eslint-config`, `@open-wc/polyfills-loader`, `@open-wc/scoped-elements`, `@open-wc/semantic-dom-diff`, `@open-wc/testing`, `@open-wc/testing-helpers`, `@open-wc/testing-karma`, `@open-wc/testing-karma-bs` and `@open-wc/testing-wallaby`, with no number next to any of them, so a version has to be resolved on npm by hand. Twelve rows point at a directory inside `./packages/`. Two do not. `@web/dev-server` links to the modern-web.dev documentation instead of a local path and is described as a modern development server for web applications replacing es-dev-server, so the development server sits outside this tree. `testing-karma-bs` links into the legacy repository. The row for `@open-wc/scoped-elements` describes it as auto defining custom elements to scope them and avoid the name collision.

## postinstall generates tsconfigs, patches node_modules and husky installs the hooks

`postinstall` is set to `npm run setup`, and setup runs three steps in sequence. `setup:ts-configs` runs `node scripts/generate-ts-configs.mjs`, and the root holds `tsconfig.browser-base.json`, `tsconfig.node-base.json` and `tsconfig.build.types.json` beside `tsconfig.json`, so the tsconfig files at the root are produced from those base files every time somebody installs. `setup:patch` is `npx patch-package`, and the tree carries a `patches/` directory, so an install rewrites files inside node_modules from patches held in this repository, through an npx call that can reach the network on the way. `setup:postinstall` then runs `node scripts/workspaces-scripts-bin.mjs monorepo:postinstall`. A fourth hook, `prepare`, runs `husky install` and wires the `.husky/` directory through `husky.config.js`. None of this reaches you when you install a published package, only when you work in the workspace.

## release publishes the versions first and formats the tree afterwards

`release` is `changeset publish --provenance && npm run format`. The order is the interesting part. Version files go to the registry before the formatter runs, so a format pass that changes tracked files leaves the working tree dirty at the exact version that was just announced, and those edits never reach what the registry holds. The root also keeps two changesets directories, `.changeset/` and `.changeset-postPrelease/`, the second spelled without the R in Release. Alongside them sit `renovate.json` for dependency updates and `.prettierignore` for the format pass that `release` triggers. The package metadata for the root is `@open-wc/root`, marked private with an MIT licence, and the project homepage is `https://open-wc.org/`. The tree is not archived.

## The initializer sample stops at the first menu question, and the stated floor is node 10

The usage section gives one command, with the requirement in a comment: node 10 and npm 6 or higher.

```bash
# in a new or existing folder:
npm init @open-wc
# requires node 10 & npm 6 or higher
```

The second fence shows the banner that command prints, and it stops three words in, at `? What`, with no option list under it, so no individual choice from the menu is recorded in the file. The banner itself points elsewhere for the detail, at `https://open-wc.org/init/`, and says you can exit any time with Ctrl+C or Esc. The tree also carries a `.nvmrc` file, and this README never says which node version it pins, so the stated floor of node 10 and the pinned version cannot be compared from the page. What the command runs is the menu described as guiding through all available actions.

## The codelab builder is a package directory with no row in the table

The documentation site is built from inside the same workspace. `site:build` runs `node scripts/workspaces-scripts-bin.mjs site:build`, then `npm run codelabs:build`, which is `node ./packages/codelabs/build-codelabs.js`, then `rocket build`. `packages/codelabs` is a package directory with a build step of its own, and it has no row among the fourteen the table offers. `rocket.config.mjs` drives the site, `search` is `rocket search` and `start` is `rocket start`. The root also holds `netlify.toml`, `.eleventyignore`, `assets/`, `docs/` and `docs-draft/`, and the last push is dated 2026-07-13. Two of the three listed releases, `@open-wc/testing@5.0.0` and `@open-wc/semantic-dom-diff@0.21.0`, were published on that same date within minutes of each other, while `@open-wc/scoped-elements@3.0.10` is dated 2026-06-02, so the three versions in circulation came out of two separate release moments.

## Conclusion

Take the scaffolder and the eslint preset and treat the rest as reference. Before you run any command copied from the guide block, check that it exists in the package.json of the package you actually installed, because the root scripts and the root README are not in step. Pin exact versions from npm rather than from the README table, whose Version column carries no text at all. And if you clone the workspace to look around, expect the install to generate tsconfig files, rewrite packages inside node_modules and install git hooks before you have edited a line.

## FAQ

### What is open-wc?

Open Web Components provides a set of defaults, recommendations and tools to help facilitate a web component project. Its recommendations cover developing, linting, testing, building, tooling, demoing, publishing and automating.

### How does open-wc scaffold a new web component project?

You run `npm init @open-wc` in a new or existing folder. It requires node 10 and npm 6 or higher, opens a menu that guides through all available actions, and you can exit at any time with Ctrl+C or Esc.

### Which open-wc packages are about testing?

The table lists @open-wc/testing, @open-wc/testing-helpers, @open-wc/testing-karma, @open-wc/testing-wallaby and @open-wc/testing-karma-bs, the last of which links into the open-wc/legacy repository instead of a local package directory.

### Does an open-wc lint run change files in the workspace?

Yes. `lint:types` is set to npm run types, whose first step is `rimraf packages/*/types/`, so linting removes the type declarations of every package and then regenerates them with `tsc --build`.

### Where is the open-wc development server kept?

Outside this repository. The package table lists @web/dev-server with a link to the modern-web.dev documentation rather than to a local directory, and describes it as a modern development server for web applications replacing es-dev-server.

### What does installing the open-wc workspace do beyond fetching dependencies?

The postinstall hook runs setup, which regenerates the ts-configs with `node scripts/generate-ts-configs.mjs`, applies patches through `npx patch-package` and runs the monorepo postinstall script. A separate prepare hook runs `husky install`.

## Sources

- [License: MIT](https://github.com/open-wc/open-wc/blob/master/LICENSE)
- [open-wc/open-wc on GitHub](https://github.com/open-wc/open-wc)
- [Project website](https://open-wc.org/)
- [README](https://github.com/open-wc/open-wc/blob/master/README.md)
- [Releases](https://github.com/open-wc/open-wc/releases)

---

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