genversion

A CLI and Node API that generates a version module from package.json, so client bundles never need to ship the whole file.

Tool
npm
v3.2.0
68stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
34/100Needs Attention
Development Activity0
Maintenance20
Community44
Maturity60
Momentum12

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
63/100Good
Architecture68
Code Quality62
Innovation55
Learning Curve65

genversion is a small build-time tool that solves a common problem: keeping a module’s exposed version string in sync with package.json without requiring require('./package.json') in client-side bundles, which would leak dependency versions and other metadata publicly. It reads selected properties (by default just version) from the nearest package.json and writes a plain JavaScript module that can be imported directly.

The generated file starts with a recognizable signature line so genversion can safely detect whether it created a file before overwriting it, preventing accidental clobbering of hand-written code. It supports CommonJS and ESM output, single/double/backtick quote styles, optional semicolons and a ‘use strict’ header, custom EJS templates, and a --check-only mode for CI or pre-commit hooks that verifies the version file is current without writing to disk.

What You Get

  • CLI generator - npx genversion <target> writes a version module in one command, ready to wire into build or release scripts.
  • Node API - generate() and check() functions let you script version-file creation and validation programmatically.
  • Safe overwrite detection - generated files carry a signature comment so genversion refuses to clobber a file it didn’t create, unless --force is passed.
  • Format flexibility - flags for semicolons, quote style (single/double/backtick), ESM vs CommonJS exports, and a custom EJS template for the output shape.
  • CI-friendly check mode - --check-only exits non-zero when the version file is missing or stale, without writing anything, for pre-commit hooks or CI gates.

Common Use Cases

  • Client-side bundles - front-end libraries expose .version without shipping the full package.json (and its dependency list) to the browser.
  • Build pipeline integration - npm run build calls genversion first so every build embeds the current version string.
  • Pre-commit / CI verification - --check-only runs in CI to catch a version file that wasn’t regenerated after a version bump.
  • Custom output shape - projects with non-standard export conventions supply their own EJS template via --template.

Under The Hood

Architecture The standalone CLI (bin/genversion.js, built on commander) delegates to a small library organized as a single-responsibility pipeline: dryRun.js validates options and resolves the target package.json via pickPackage.js (wrapping the find-package dependency), then renders content through the default template.js or a custom template loaded by getTemplate.js via EJS; generate.js and check.js layer file IO (write vs. read-and-compare) on top of the shared dryRun() result. There’s no class hierarchy or DI container - just plain function exports required directly - so the dryRun() return shape (absoluteTargetPath, generatedContent, version) is the one abstraction both the write path and the check path depend on.

Tech Stack Plain JavaScript targeting Node >=10, using commander 7 for CLI argument parsing, ejs 3 for default and custom template rendering, and find-package 1.x to resolve the nearest package.json along a given path. Tests run on mocha 8 with should.js assertions and fs-extra for fixture setup/teardown; linting uses the zero-config standard style checker rather than a hand-rolled ESLint config. GitHub Actions runs the test suite across a Node 10-18 matrix on every push.

Code Quality A dedicated test/ directory splits API tests (api.test.js) from CLI tests (cli.test.js) with supporting fixtures, and npm test runs standard (lint) followed by mocha. Error handling is consistently Node-style err-first callbacks propagated up from dryRun.js; there is no TypeScript or runtime type validation, with JSDoc-style comments documenting parameters instead. Naming is consistent camelCase throughout, and CI verifies the suite passes across five Node major versions, though no code-coverage tooling is visible.

API Design The underlying idea, generating a plain importable file instead of requiring the whole package.json, is a well-known, narrow trick rather than something novel, but it’s executed with unusually thorough developer experience: the CLI exposes nearly every stylistic knob a downstream project might need (semicolons, quote style, ESM vs CommonJS, custom templates and template engines), and check()/--check-only distinguishes “file doesn’t exist” from “file exists but wasn’t generated by genversion” from “file is stale”, a careful safety detail that avoids silently overwriting hand-edited code. Getting started requires exactly one CLI invocation with zero configuration.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search