{"id":49589080,"url":"https://github.com/comvi-io/comvi-js","last_synced_at":"2026-05-09T12:01:45.493Z","repository":{"id":355491711,"uuid":"1228270648","full_name":"comvi-io/comvi-js","owner":"comvi-io","description":"Official Comvi i18n library for JavaScript and TypeScript. CDN-loaded translations, ICU plurals, framework adapters.","archived":false,"fork":false,"pushed_at":"2026-05-03T22:07:19.000Z","size":796,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-03T23:23:30.284Z","etag":null,"topics":["cdn","comvi","i18n","icu","internationalization","javascript","l10n","localization","react","tms","translation","translations","typescript","vue"],"latest_commit_sha":null,"homepage":"https://comvi.io/i18n","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/comvi-io.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-03T20:17:54.000Z","updated_at":"2026-05-03T22:05:58.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/comvi-io/comvi-js","commit_stats":null,"previous_names":["comvi-io/comvi-js"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/comvi-io/comvi-js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/comvi-io%2Fcomvi-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/comvi-io%2Fcomvi-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/comvi-io%2Fcomvi-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/comvi-io%2Fcomvi-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/comvi-io","download_url":"https://codeload.github.com/comvi-io/comvi-js/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/comvi-io%2Fcomvi-js/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32818397,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-08T08:22:46.396Z","status":"online","status_checked_at":"2026-05-09T02:00:06.633Z","response_time":123,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cdn","comvi","i18n","icu","internationalization","javascript","l10n","localization","react","tms","translation","translations","typescript","vue"],"created_at":"2026-05-04T00:02:20.835Z","updated_at":"2026-05-09T12:01:45.486Z","avatar_url":"https://github.com/comvi-io.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cpicture\u003e\n    \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/comvi-io/comvi-js/main/.github/assets/header-logo-dark.svg\"\u003e\n    \u003cimg alt=\"Comvi\" src=\"https://raw.githubusercontent.com/comvi-io/comvi-js/main/.github/assets/header-logo-light.svg\" width=\"860\"\u003e\n  \u003c/picture\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eModern i18n for JavaScript \u0026 TypeScript\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  One framework-agnostic core. ICU MessageFormat and rich text without XSS —\u003cbr/\u003e\n  for \u003cb\u003eVue\u003c/b\u003e, \u003cb\u003eReact\u003c/b\u003e, \u003cb\u003eSolidJS\u003c/b\u003e, \u003cb\u003eSvelte\u003c/b\u003e, \u003cb\u003eNext.js\u003c/b\u003e, and \u003cb\u003eNuxt\u003c/b\u003e.\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.npmjs.com/package/@comvi/core\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/@comvi/core?color=blue\u0026label=npm\" alt=\"npm version\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://bundlephobia.com/package/@comvi/core\"\u003e\u003cimg src=\"https://img.shields.io/bundlephobia/minzip/@comvi/core?label=minzip\" alt=\"Bundle size\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/comvi-io/comvi-js/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/comvi-io/comvi-js/actions/workflows/ci.yml/badge.svg\" alt=\"CI\"\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-MIT-blue.svg\" alt=\"License: MIT\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.typescriptlang.org/\"\u003e\u003cimg src=\"https://img.shields.io/badge/TypeScript-strict-blue?logo=typescript\u0026logoColor=white\" alt=\"TypeScript\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://comvi.io\"\u003e\u003cimg src=\"https://img.shields.io/badge/Platform-comvi.io-7c3aed\" alt=\"Comvi Platform\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://x.com/Comvi_io\"\u003e\u003cimg src=\"https://img.shields.io/twitter/follow/Comvi_io?style=social\u0026logo=x\" alt=\"Follow on X\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.linkedin.com/company/comvi-io/\"\u003e\u003cimg src=\"https://img.shields.io/badge/LinkedIn-Comvi-0A66C2?logo=linkedin\u0026logoColor=white\" alt=\"Comvi on LinkedIn\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cb\u003e\u003ca href=\"https://comvi.io/docs/i18n/quick-start/\"\u003eDocumentation\u003c/a\u003e\u003c/b\u003e\n  \u0026nbsp;·\u0026nbsp;\n  \u003cb\u003e\u003ca href=\"https://comvi.io\"\u003eComvi Platform\u003c/a\u003e\u003c/b\u003e\n\u003c/p\u003e\n\n---\n\n## Why Comvi?\n\n- **Rich text without XSS.** Embed components into translations (`Click \u003clink\u003ehere\u003c/link\u003e`) without raw HTML strings or unsafe DOM injection.\n- **Same API across six frameworks.** `useI18n()` and the `\u003cT\u003e` component look the same in Vue, React, SolidJS, Svelte, Next.js, and Nuxt. All bindings ship together with the core — same version, same release cycle.\n- **ICU `plural`, `selectordinal` \u0026 `select`.** Locale-correct grammar for every language `Intl.PluralRules` supports. Numbers, dates, currency, and relative time are formatted via native `Intl` methods on the `i18n` instance.\n- **~8 kB gzipped core, zero dependencies.** No `eval` or `new Function` in any runtime package — works under a strict CSP without `unsafe-eval`.\n- **Pluggable loading \u0026 detection.** Translations come from inline objects, local JSON, or a CDN/API loader plugin. Locale detection (query, cookie, storage, `navigator`) is a separate plugin you opt into.\n- **Server-side rendering for Next.js \u0026 Nuxt.** `@comvi/next` ships an App Router `loadTranslations()` for server components, locale-routed layouts under `[locale]`, and a `createMiddleware()` for redirect-on-detect. `@comvi/nuxt` is a Nuxt 3 module with locale composables, middleware, and `\u003cNuxtLinkLocale\u003e`.\n\n## Install\n\nPick one — framework packages bundle `@comvi/core`, so a single install is enough:\n\n```bash\nnpm install @comvi/core      # Vanilla / Node\nnpm install @comvi/vue       # Vue 3\nnpm install @comvi/react     # React 16.8+\nnpm install @comvi/solid     # SolidJS 1.8+\nnpm install @comvi/svelte    # Svelte 4 / 5\nnpm install @comvi/next      # Next.js 14+\nnpm install @comvi/nuxt      # Nuxt 3\n```\n\n## Quick start\n\n```ts\nimport { createI18n } from \"@comvi/core\";\n\nconst i18n = createI18n({\n  locale: \"en\",\n  fallbackLocale: \"en\",\n  translation: {\n    en: {\n      greeting: \"Hello, {name}!\",\n      items: \"{count, plural, one {# item} other {# items}}\",\n    },\n    uk: {\n      greeting: \"Привіт, {name}!\",\n      items: \"{count, plural, one {# елемент} few {# елементи} other {# елементів}}\",\n    },\n  },\n});\n\nawait i18n.init();\n\ni18n.t(\"greeting\", { name: \"Alice\" }); // \"Hello, Alice!\"\ni18n.t(\"items\", { count: 5 }); // \"5 items\"\n```\n\nFor framework-specific setup, see the docs:\n[React](https://comvi.io/docs/i18n/react/) ·\n[Vue](https://comvi.io/docs/i18n/vue/) ·\n[Next.js](https://comvi.io/docs/i18n/next/) ·\n[Nuxt](https://comvi.io/docs/i18n/nuxt/) ·\n[SolidJS](https://comvi.io/docs/i18n/solid/) ·\n[Svelte](https://comvi.io/docs/i18n/svelte/) ·\n[Vanilla](https://comvi.io/docs/i18n/vanilla/)\n\nOr jump straight into runnable code in [`test-apps/`](test-apps/) — one demo app per framework.\n\n## Rich text without XSS\n\nThe hero feature. Embed components inside translation strings without raw HTML, without unsafe DOM injection, without splitting a sentence across multiple template fragments. Translators see clean markup; you control the rendering.\n\n```json\n{ \"help\": \"Click \u003clink\u003ehere\u003c/link\u003e for support, or \u003cbold\u003eread the docs\u003c/bold\u003e.\" }\n```\n\n**React**\n\n```tsx\nimport { T } from \"@comvi/react\";\n\n\u003cT\n  i18nKey=\"help\"\n  components={{\n    link: \u003ca href=\"/help\" /\u003e,\n    bold: \u003cstrong /\u003e,\n  }}\n/\u003e;\n```\n\n**Vue**\n\n```vue\n\u003cscript setup lang=\"ts\"\u003e\nimport { T } from \"@comvi/vue\";\n\u003c/script\u003e\n\n\u003ctemplate\u003e\n  \u003cT i18nKey=\"help\"\u003e\n    \u003ctemplate #link=\"{ children }\"\n      \u003e\u003ca href=\"/help\"\u003e{{ children }}\u003c/a\u003e\u003c/template\n    \u003e\n    \u003ctemplate #bold=\"{ children }\"\n      \u003e\u003cstrong\u003e{{ children }}\u003c/strong\u003e\u003c/template\n    \u003e\n  \u003c/T\u003e\n\u003c/template\u003e\n```\n\nSolidJS and Svelte expose the same tag-interpolation concept with framework-specific component map shapes. Pass `tagInterpolation: { strict: \"warn\" }` to `createI18n` to surface translations referencing tags you forgot to handle — before they ship.\n\n## ICU plurals, ordinals \u0026 select\n\nComvi uses [ICU MessageFormat](https://unicode-org.github.io/icu/userguide/format_parse/messages/) — the industry-standard syntax for localized strings, recognized by every major translation management platform (Crowdin, Lokalise, Phrase, and more). Locale-correct for every language `Intl.PluralRules` supports — Polish, Ukrainian, Arabic, Welsh, and the rest:\n\n```\n{count, plural, one {You have # message} other {You have # messages}}\n{place, selectordinal, one {#st} two {#nd} few {#rd} other {#th}}\n{gender, select, female {Welcome, madam} male {Welcome, sir} other {Welcome}}\n```\n\n```ts\nt(\"messages\", { count: 1 }); // \"You have 1 message\"\nt(\"messages\", { count: 5 }); // \"You have 5 messages\"\nt(\"rank\", { place: 3 }); // \"You finished 3rd\"\nt(\"greeting\", { gender: \"female\" }); // \"Welcome, madam\"\n```\n\n## Locale-aware formatting\n\nNumbers, dates, currency, and relative time — automatically follow the active locale via native `Intl`:\n\n```ts\ni18n.formatNumber(1234.5); // \"1,234.5\" · \"1.234,5\" · \"1 234,5\"\ni18n.formatNumber(0.75, { style: \"percent\" }); // \"75%\"\ni18n.formatDate(new Date(), { dateStyle: \"long\" }); // \"January 15, 2025\" · \"15. Januar 2025\"\ni18n.formatCurrency(99.99, \"USD\"); // \"$99.99\" · \"99,99 $\"\ni18n.formatRelativeTime(-2, \"hour\"); // \"2 hours ago\" · \"vor 2 Stunden\"\n\ni18n.dir; // \"ltr\" | \"rtl\" — handles script subtags (ku-Arab → rtl, ks-Deva → ltr)\n```\n\nReactive in every framework binding via `useI18n()`.\n\n## Packages\n\n### Frameworks\n\n| Package                            | Description                                              | Docs                                     |\n| ---------------------------------- | -------------------------------------------------------- | ---------------------------------------- |\n| [`@comvi/core`](packages/core)     | Framework-agnostic runtime, ICU parser, plugin system    | [→](https://comvi.io/docs/i18n/vanilla/) |\n| [`@comvi/vue`](packages/vue)       | Vue 3 plugin, `useI18n()`, `\u003cT\u003e` component               | [→](https://comvi.io/docs/i18n/vue/)     |\n| [`@comvi/react`](packages/react)   | `\u003cI18nProvider\u003e`, `useI18n()` hook, `\u003cT\u003e` component      | [→](https://comvi.io/docs/i18n/react/)   |\n| [`@comvi/solid`](packages/solid)   | SolidJS provider + reactive signals + `\u003cT\u003e` component    | [→](https://comvi.io/docs/i18n/solid/)   |\n| [`@comvi/svelte`](packages/svelte) | Svelte stores + context (Svelte 4 \u0026 5) + `\u003cT\u003e` component | [→](https://comvi.io/docs/i18n/svelte/)  |\n| [`@comvi/next`](packages/next)     | Next.js App Router: SSR, middleware, locale routing      | [→](https://comvi.io/docs/i18n/next/)    |\n| [`@comvi/nuxt`](packages/nuxt)     | Nuxt 3 module: auto-imports, SSR, locale routing         | [→](https://comvi.io/docs/i18n/nuxt/)    |\n\n### Plugins\n\n| Package                                                            | Description                                             |\n| ------------------------------------------------------------------ | ------------------------------------------------------- |\n| [`@comvi/plugin-fetch-loader`](packages/plugin-fetch-loader)       | Load translations from CDN or API                       |\n| [`@comvi/plugin-locale-detector`](packages/plugin-locale-detector) | Auto-detect locale from query, cookie, storage, browser |\n\n### Platform plugins\n\nThese plugins require the [Comvi Platform](https://comvi.io) — they don't work standalone.\n\n| Package                                                                | Description                                               |\n| ---------------------------------------------------------------------- | --------------------------------------------------------- |\n| [`@comvi/plugin-in-context-editor`](packages/plugin-in-context-editor) | Visual in-app translation editor (requires Comvi account) |\n\n### Tooling\n\n| Package                                      | Description                                            |\n| -------------------------------------------- | ------------------------------------------------------ |\n| [`@comvi/vite-plugin`](packages/vite-plugin) | Generate types from local JSON files at dev/build time |\n| [`@comvi/cli`](packages/cli)                 | Generate types from the Comvi TMS, sync translations   |\n\n## Comvi Platform\n\nComvi i18n is the open-source library — fully usable on its own. [**Comvi**](https://comvi.io) is the optional translation management platform that pairs with it:\n\n- **Collaborative dashboard** for translators, designers, and developers\n- **CDN delivery** via [`@comvi/plugin-fetch-loader`](packages/plugin-fetch-loader) — ship a translation without a redeploy\n- **Auto-generated types** straight from the platform via [`@comvi/cli`](packages/cli)\n- **In-context editing** in your live app via [`@comvi/plugin-in-context-editor`](packages/plugin-in-context-editor)\n\nAdopt the platform when you're ready — the library never depends on it.\n\n## Repository\n\n```\npackages/        — published npm packages (12 total)\ntooling/         — shared internal Vite/Vitest config\ntest-apps/       — runnable demo apps for every framework\n```\n\n[pnpm](https://pnpm.io/) + [Turborepo](https://turbo.build/) monorepo. Every package builds independently and is published to npm under the `@comvi/*` scope.\n\n## Development\n\n```bash\npnpm install     # install workspace deps\npnpm build       # build all packages\npnpm -w run test # run all tests\npnpm lint        # lint all packages\n```\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines.\n\n## License\n\n[MIT](LICENSE) © Comvi\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcomvi-io%2Fcomvi-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcomvi-io%2Fcomvi-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcomvi-io%2Fcomvi-js/lists"}