msg-cli is a command-line tool for the msg library. It helps you scaffold internationalization (i18n) and localization (l10n) layout and wire up your project for use with msg.
Current status: CLI for the msg library (npm: @worldware/msg-cli, v0.2.2). Commands: init (scaffold i18n/l10n and config), create project (new MsgProject in i18n/projects), create resource (new MsgResource in i18n/resources), export (serialize MsgResources to XLIFF 2.0 in l10n/xliff), import (import translations from XLIFF 2.0 to JSON in l10n/translations).
Install globally:
npm install -g @worldware/msg-cliOr use via npx:
npx msg <command>For project-local setup, run msg init in your project root to add @worldware/msg and scaffold directories and config. Install msg-cli globally (as above) or as a dev dependency to run the commands.
- i18n (internationalization): Source message projects and resources. MsgProject and MsgResource files live under the i18n directory (default
src/i18n). - l10n (localization): Exported XLIFF files and imported translation JSON. Exports and translation data live under the l10n directory (default
res/l10n). - Import aliases: The init command adds
#i18n/*and#l10n/*(and#root/*) topackage.jsonso you can import with short paths likeimport project from '#i18n/projects/main'.
Commands: init, create project, create resource, export, import.
Scaffold a msg project: create i18n and l10n directories, update package.json (directories, import aliases, scripts), optionally update tsconfig.json for path aliases, and install @worldware/msg.
msg init| Flag | Description |
|---|---|
-h, --help |
Show help for the init command. |
-i |
Interactive: prompt for i18n and l10n directory paths. |
-f, --force |
Force clean install; overwrite existing msg setup. |
--i18nDir <path> |
Relative path for the i18n directory (default: src/i18n). |
--l10nDir <path> |
Relative path for the l10n directory (default: res/l10n). |
Examples:
# Default layout (src/i18n, res/l10n)
msg init
# Custom paths
msg init --i18nDir lib/i18n --l10nDir data/l10n
# Re-run and overwrite existing setup
msg init -f
# Prompt for paths
msg init -iWhat init does:
- Creates
i18nwith subdirectoriesprojectsandresources, andl10nwithtranslationsandxliff(or your custom paths). - Adds
.gitkeepin each leaf directory. - Adds
directories.i18n,directories.l10n, anddirectories.roottopackage.json. - Adds import aliases
#i18n/*,#l10n/*, and#root/*topackage.json. - Adds scripts
i18n-exportandl10n-import(runningmsg exportandmsg import). - If
tsconfig.jsonexists, addscompilerOptions.baseUrlandcompilerOptions.pathsfor the aliases. - Installs the latest
@worldware/msgas a dependency.
Create a new MsgProject file in the i18n projects directory. Requires package.json with directories.i18n and directories.l10n (run msg init first).
msg create project <projectName> [source] [targets...] [--extend <name>]| Argument | Required | Description |
|---|---|---|
projectName |
Yes | Name of the project (used as file name). |
source |
Yes* | Source locale (e.g. en). |
targets |
Yes* (≥1) | Target locale(s), e.g. fr, de, es. |
* source and targets are optional when --extend is passed; they are inherited from the base project.
| Flag | Short | Description |
|---|---|---|
--extend |
-e |
Extend an existing project. |
--help |
-h |
Show help for create project. |
Examples:
# Create project myApp with source en and targets fr, de
msg create project myApp en fr de
# Extend an existing project (inherits source and targets from base)
msg create project extendedApp --extend base
# Extend and add/override locales
msg create project extendedApp en de --extend base
# Help
msg create project -hBehavior:
- Writes the file to
i18n/projects/<projectName>.js(always.js). - Uses ES module or CommonJS export syntax based on
package.json"type"or presence oftsconfig.json. - Generates a translation loader that imports from
l10n/translationsusing the relative path fromi18n/projects(fromdirectoriesin package.json). - Includes
pseudoLocale: 'en-XA'by default (or inherits from the base project when extending), for use with msg'sgetTranslation(pseudoLocale)pseudolocalization support. - With
--extend <name>, merges target locales and pseudoLocale from the existing project. Ifsourceandtargetsare omitted, they are inherited from the base project. - Errors if the project name already exists, package.json is missing or invalid, or required directories are not configured.
Create a new MsgResource file in the i18n resources directory. Requires msg init and a project file in i18n/projects (run msg create project first).
msg create resource <projectName> <title> [-f] [-e]| Argument | Required | Description |
|---|---|---|
projectName |
Yes | Name of the project to import in the MsgResource. |
title |
Yes | Title of the resource and file name (e.g. messages → messages.msg.js). |
| Flag | Short | Description |
|---|---|---|
--force |
-f |
Overwrite an existing resource file. |
--edit |
-e |
Open the file for editing after creation. |
--help |
-h |
Show help for create resource. |
Examples:
# Create resource messages for project myProject
msg create resource myProject messages
# Overwrite existing resource
msg create resource myProject messages --force
# Create and open in editor
msg create resource myProject messages --editBehavior:
- Writes the file to
i18n/resources/<title>.msg.js(always.js). - Uses ES module or CommonJS export syntax based on
package.json"type"or presence oftsconfig.json. - Sets
langfrom the project'ssourceLocaleanddirtortlfor Arabic/Hebrew,ltrotherwise. - Includes a minimal example message. Validates that the generated file is importable.
- Errors if i18n/projects or i18n/resources does not exist, the project is not found, or the resource file already exists (unless
--force).
Serialize all MsgResource files in i18n/resources to XLIFF 2.0 files in l10n/xliff, one file per project. Does not send files for translation; use your own translation workflow with the generated XLIFF. Requires package.json with directories.i18n and directories.l10n (run msg init first).
msg export [-p <projectName>]| Flag | Short | Description |
|---|---|---|
--project |
-p |
Export only the named project. |
--help |
-h |
Show help for the export command. |
Examples:
# Export all projects to l10n/xliff
msg export
# Export only project "myApp"
msg export --project myApp
msg export -p myAppBehavior:
- Recursively finds all
.msg.jsand.msg.tsfiles underi18n/resources. - Imports each file as a MsgResource; errors if any file is invalid.
- Groups resources by project name and writes one XLIFF 2.0 file per project to
l10n/xliff(e.g.myApp.xliff). - With
--project, only that project is exported; existing other files inl10n/xliffare not removed. - If no MsgResource files are found, exits with an informational message (no error).
- Logs each major step (finding files, importing, grouping, writing).
What is preserved in XLIFF 2.0:
- Message keys — Stored as unit
id(sanitized for XML) andname(original key). - Resource notes — Emitted as file-level
<notes>with category (e.g.description,comment). - Resource attributes —
dir→ filesrcDir;dnt→ filetranslate="no". - Message notes — Emitted as unit-level
<notes>with category (e.g.description,context,parameters). - Message attributes —
dnt→ unittranslate="no"; messagediris serialized as the unit’ssrcDirattribute (XLIFF 2.0 text direction for the segment).
Import translations from bilingual XLIFF 2.0 files in l10n/xliff to JSON files in l10n/translations. Expects XLIFF files with trgLang (target language) and translated content in <target> elements. Writes JSON files without notes for minimal size. Requires package.json with directories.i18n and directories.l10n (run msg init first).
msg import [-p <projectName>] [-l <locale>]| Flag | Short | Description |
|---|---|---|
--project |
-p |
Import only the named project. |
--language |
-l |
Import only the specified locale. |
--help |
-h |
Show help for the import command. |
Examples:
# Import all XLIFF files
msg import
# Import only project "myApp"
msg import --project myApp
msg import -p myApp
# Import only locale "zh"
msg import --language zh
msg import -l zhBehavior:
- Recursively finds all
.xliffand.xlffiles underl10n/xliff. - Project and target locale are taken from the filename (e.g.
myApp.zh.xliff) or from path segments (e.g.myApp/zh/messages.xliff). - Dynamically imports
MsgProjectfromi18n/projectsto validate target locales. - Skips monolingual XLIFF files (no
trgLang). - Skips files whose target locale is not in the project's
targetLocales. - Skips files when the matching project file does not exist or cannot be loaded.
- Writes JSON to
l10n/translations/<project>/<locale>/<title>.json. - Preserves existing translation files for other projects or locales when filtering.
- Errors on malformed XLIFF and logs each step.
The CLI does not expose a programmatic API. For library usage, see @worldware/msg.
- Repository: github.com/worldware-studios/msg-cli
- Setup:
npm install - Build:
npm run build - Tests:
npm run test - Coverage:
npm run coverage
Source layout:
src/commands/— CLI commands (init, export, import, create/project, create/resource).src/lib/— Shared utilities: init-helpers, export-helpers, import-helpers, create-project-helpers, create-resource-helpers.src/tests/— Vitest tests and fixtures.
MIT. See LICENSE.
i18n, l10n, internationalization, localization, xliff, msg, cli