npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@comvi/cli

v0.2.0

Published

CLI for Comvi i18n — type generation, translation sync, and project management

Readme


@comvi/cli connects your codebase to the Comvi Translation Management System. It generates a strict TranslationKeys interface from your TMS schema and syncs translation files between local JSON and the TMS — with optional SSE-based watch mode for live regeneration.

Use @comvi/cli if your translations live in the Comvi TMS and you want to sync them to your repo or generate types from the live schema. Use @comvi/vite-plugin if your translations live as local JSON files and you want autocomplete in your editor.

📖 Documentation: https://comvi.io/docs/cli/

About Comvi i18n

Comvi i18n is a modern, framework-agnostic internationalization library — ICU MessageFormat, rich-text component embedding, and locale-aware Intl formatters in ~8 kB gzipped with zero runtime dependencies and no eval (CSP-safe for Chrome extensions, Cloudflare Workers, and locked-down enterprise apps).

  • Same API across Vue, React, SolidJS, Svelte, Next.js, and Nuxt.
  • Real ICU MessageFormat — locale-correct plurals, ordinals, and gender via Intl.PluralRules. Recognized by every major TMS.
  • Type-safe translation keys via TypeScript declaration merging — autocomplete and parameter validation everywhere.
  • Pluggable — translation loading, locale detection, and in-context editing are opt-in plugins.

See the main repo for the full library overview, runnable demos, and the framework binding matrix.

Why @comvi/cli?

  • Type generation from the live TMS schema. No manual i18n.d.ts upkeep — types stay in sync with your platform.
  • Pull & push translations. Download from the TMS to local JSON, or upload changes back without leaving your terminal.
  • Watch mode with SSE. Use --watch to live-regenerate types as translators ship changes to the platform.

Install

npm install -D @comvi/cli

Quick start

export COMVI_API_KEY=cmv_xxxxxxxxxxxxxxxx

npx comvi init                    # creates .comvirc.json
npx comvi generate-types          # generate TranslationKeys.d.ts from the TMS
npx comvi generate-types --watch  # live-regenerate via SSE
npx comvi pull                    # download translations from the TMS
npx comvi push                    # upload local translations to the TMS

Recommended: keep the API key in the COMVI_API_KEY environment variable. Storing apiKey in .comvirc.json works but is discouraged — env vars take precedence and won't end up in version control by accident.

The CLI auto-loads the nearest .env by walking up from your current working directory (bounded by the project root) before each command — drop COMVI_API_KEY=... in .env and it just works, no dotenv-cli wrapper needed. Real env vars always win over the file (CI-safe). Use --no-env-file (or COMVI_NO_ENV=1) to opt out, or --env-file <path> to point at a specific file.

Filter what you pull/push

Declare a namespace/locale subset in .comvirc.json so it's not repeated in every package.json script:

{
  "namespaces": ["forest", "share_experience"],
  "locales": ["en", "uk"]
}

comvi pull and comvi push then operate on that subset by default. CLI flags (--ns, --locale) fully override the config for one-off runs (no merge). If a value in the config doesn't exist on the server (typo, deleted namespace), pull fails fast with exit code 4 instead of silently writing empty files.

For all commands and flags, the full .comvirc.json reference, and the programmatic API (TypeGenerator, ApiClient, TranslationSync, etc.), see the documentation.

What you get

Run npx comvi generate-types and the CLI writes a TranslationKeys declaration straight from your TMS schema:

// src/types/i18n.d.ts — generated, do not edit
declare module "@comvi/core" {
  interface TranslationKeys {
    welcome: { name: string };
    items: { count: number };
    greeting: never;
    "errors:NOT_FOUND": never;
    "errors:INVALID_INPUT": { field: string };
  }
}

Every t() call across your project is now strictly typed against the live TMS schema:

import { useI18n } from "@comvi/react"; // or vue, solid, svelte, @comvi/next/client; Nuxt auto-imports it
const { t } = useI18n();

// ✓ Compiles — name required, type-checked
t("welcome", { name: "Alice" });

// ✓ No params needed
t("greeting");

// ✓ Namespaced keys use the ns option
t("INVALID_INPUT", { ns: "errors", field: "email" });

What TypeScript catches:

// ✗ Expected 2 arguments, but got 1
t("welcome");

// ✗ Property 'name' is missing in type '{ age: number }'
t("welcome", { age: 5 });

// ✗ Type 'number' is not assignable to type 'string'
t("welcome", { name: 42 });

// ✗ Argument of type '"typo"' is not assignable to parameter
t("typo", { name: "Alice" });

Live regeneration with --watch

Run npx comvi generate-types --watch once at the start of your dev session. The CLI opens a Server-Sent Events connection to the TMS — when a translator adds, renames, or removes a key, your local .d.ts regenerates within seconds and your editor's autocomplete updates without a restart.

Workflow: pull/push for translations

npx comvi pull   # writes the TMS state to local JSON files
npx comvi push   # uploads local edits back to the TMS

Use pull to bootstrap a fresh checkout or to grab a translator's recent changes for offline review. Use push to ship a developer-side copy fix without leaving the editor.

License

MIT © Comvi