ci-info
Zero-dependency detection of the current CI environment, vendor, and pull-request status in Node.js.
Repository Health
Technical Analysis
ci-info is a small, zero-dependency Node.js library that answers one narrow question reliably: is this code running on a CI server, and if so, which one? Requiring the module populates a plain object of exports — isCI, name, id, isPR, and a boolean constant per vendor (TRAVIS, GITHUB_ACTIONS, JENKINS, and 50+ others) — derived entirely from inspecting process.env against a declarative registry of vendor-specific environment variables.
Because detection is data-driven from vendors.json rather than hardcoded per-vendor logic, the library can support an unusually long tail of CI providers (Buildkite, Cirrus CI, Netlify, Vercel, Render, Woodpecker, and more) without each one needing bespoke code, and new vendors are added by extending the JSON registry rather than touching index.js. It also normalizes pull-request detection across vendors that expose that signal in wildly different ways (a single env var, an env var compared against a value, or an env var checked against a list of possible values).
What You Get
- A single
isCIboolean usable in any script or build tool to gate CI-only behavior - The detected vendor’s display
nameand normalizedid, ornullif the environment doesn’t match any known CI provider - An
isPRboolean (ornullwhen the vendor doesn’t expose PR status) so tooling can distinguish PR builds from regular branch builds - A dedicated boolean constant per supported vendor (
ci.GITHUB_ACTIONS,ci.CIRCLE,ci.JENKINS, etc.) for code that needs to special-case a specific provider - Bundled TypeScript typings (
index.d.ts) generated directly from the vendor registry, so the API is fully typed with no extra@typespackage
Common Use Cases
- Test runner behavior - a test framework disables interactive watch mode and enables machine-readable output only when
ci.isCIis true - Build script branching - a build tool skips a local dev-only step (like opening a browser) whenever it detects it’s running under CI
- PR-only checks - a CI script runs extra linting or a size-diff comment only when
ci.isPRis true - Vendor-specific workarounds - a tool applies a fix only under
ci.GITHUB_ACTIONSbecause that provider truncates log output differently than others - Telemetry tagging - an internal CLI tags anonymous usage telemetry with
ci.nameto separate local developer runs from automated CI runs
Under The Hood
Architecture
The entire library is a single CommonJS module (index.js) that runs its detection logic once, as a side effect of being required: it loads a flat JSON vendor registry (vendors.json, ~53 entries), iterates every vendor checking its declared environment-variable conditions via two small dispatch helpers (checkEnv, checkPR) that handle the handful of shapes a vendor’s env-condition can take (a plain string, an {env, includes} object, an {any: [...]} list), and assigns the resulting booleans directly onto module.exports. There’s no class hierarchy, no lazy evaluation, and no runtime dependency on anything outside Node’s process.env — the generated index.d.ts typings file is kept in sync with vendors.json by a separate build script (create-typings.js) run at pre-commit time via Husky, so the one piece that could drift (the registry vs. the type declarations) is regenerated mechanically rather than hand-maintained.
Tech Stack
Plain CommonJS targeting Node >=8 with zero runtime dependencies — the only external input is process.env. All dependencies are dev-only tooling: standard for zero-config linting, tape for the test suite’s assertions, husky to run the typings-generation build step as a pre-commit git hook, clear-module to reset Node’s require cache between test cases so each vendor’s env vars can be tested in isolation, and publint to catch packaging/exports-field mistakes before publish.
Code Quality
The test suite (test.js, ~25KB) iterates the full vendor registry and exercises both isCI/vendor-boolean detection and isPR detection per vendor, mocking process.env per case; there’s no formal TypeScript source, but linting is enforced project-wide via standard, which also runs as part of npm test. Error handling is minimal by design — the library has almost no failure modes since it only reads environment variables and returns booleans, never throwing.
API Design
The public surface asks for zero configuration and zero function calls: requiring the package immediately gives you a plain object of booleans and strings, so integrating it is a one-line require plus a property access. Naming is consistent (uppercase vendor constants matching the provider’s own branding) and every export is individually documented in the generated .d.ts file, keeping editor autocomplete and inline docs accurate without hand-written type definitions.
Used by 7 apps in this directory
Artillery
Devops · Developer Tools
Cloud-scale load testing and functional testing for APIs, WebSockets, gRPC, and headless browsers, distributed across AWS Lambda or Fargate with zero infrastructure to manage.
KeystoneJS
CMS · Developer Tools
The superpowered headless CMS for developers built with GraphQL and React
medusa
Ecommerce
The most flexible open-source commerce platform — build B2C, B2B, and marketplace applications with modular, composable commerce primitives.
OpenWiki
Developer Tools
A LangChain-built CLI that writes and maintains codebase documentation automatically — generates an initial wiki, refreshes it as the repo changes, and can open a daily PR of documentation updates via GitHub Actions.
Payload CMS
Developer Tools · Blogging · CMS
The open-source, Next.js-native headless CMS that lives inside your /app folder and gives you a full TypeScript backend instantly.
strapi
CMS
Open-source headless CMS that auto-generates REST and GraphQL APIs from your content models, with a fully customizable admin panel you control.
Webiny JS
Ecommerce · Blogging · CMS
Open-source, self-hosted CMS on AWS serverless — a TypeScript framework you extend with code, not a product you configure through a UI.