package.json Validator: Catch Mistakes Before npm install or Publish
A malformed version string, an invalid package name, or a dependency accidentally listed in both dependencies and devDependencies can all cause confusing failures — sometimes only at publish time, sometimes only for teammates installing fresh. This validator checks package.json's structure against the rules npm and Node tooling actually enforce.
Scoped packages use the form @scope/package-name.
Why Package Names Have Strict Rules
npm package names become part of a URL (registry.npmjs.org/
The Cost of an Invalid Version String
Every tool in the JavaScript ecosystem — npm, yarn, pnpm, bundlers, dependency-update bots — assumes package.json's version field is valid semver. An invalid version doesn't just break your own publish; it breaks version-range resolution for anyone who depends on your package with a range like ^1.2.0.
Duplicate Dependencies Across Sections
It's easy to end up with the same package in both dependencies and devDependencies after refactoring — for example, moving a build-time-only tool that used to be a runtime dependency. Different package managers handle this ambiguity differently (some prefer dependencies, some warn), so it's worth resolving explicitly rather than relying on tool-specific behavior.
Practical Examples
Catching an Invalid Version
A common typo when bumping versions manually.
- 1.Input: "version": "1.2"
- 2.Error: not valid semver (expected MAJOR.MINOR.PATCH)
- 3.Fix: "version": "1.2.0"
Finding a Duplicate Dependency
Left over from a refactor.
- 1.dependencies: { "lodash": "^4.17.21" }
- 2.devDependencies: { "lodash": "^4.17.21" }
- 3.Warning: "lodash" is listed in both — remove one
What Gets Validated
- Valid JSON syntax
- name: format and length
- version: valid semver
- scripts: values must be strings
- dependencies/devDependencies/peerDependencies: valid version ranges
- Cross-listed dependencies in both deps and devDeps
Good Use Cases
- Reviewing package.json before publishing a package
- Debugging a confusing npm install or CI failure
- Catching a leftover duplicate dependency after refactoring
- Validating a hand-written or generated package.json
Frequently Asked Questions
What makes an npm package name invalid?
It must be lowercase, URL-safe (no spaces or most special characters), 214 characters or fewer, and can't start with a dot or underscore. It may optionally have a scope prefix like @myorg/package-name.
Why does semver format matter for 'version'?
npm and every dependency resolver expects MAJOR.MINOR.PATCH (with optional pre-release/build metadata, like 1.2.3-beta.1). A malformed version string breaks npm publish and confuses version-range matching for anything that depends on your package.
Why does it flag a package in both dependencies and devDependencies?
Listing the same package in both is usually accidental — it means the intended install location is ambiguous, and different tools resolve the conflict differently. It's typically a leftover from moving a dependency between the two sections without removing the old entry.
What version range formats does it recognize?
Common npm range syntax: exact versions (1.2.3), caret (^1.2.3), tilde (~1.2.3), comparison operators (>=1.2.3), 'x' ranges (1.2.x), workspace: and file: protocols, git/https URLs, and 'latest' or '*'.
Does this check if the dependencies actually exist on npm?
No — it only validates the package.json file's own structure and syntax. It doesn't make any network requests to the npm registry.
Is my package.json uploaded anywhere?
No, validation runs entirely in your browser via JSON.parse and pattern matching — no npm registry calls, no upload.