Fundamentals 16 min read

How VS Code Implements Multi‑Language Support: Deep Dive into NLS and Module Loading

This article explains how VS Code’s complex Electron‑Node architecture handles internationalization by using a custom NLS system, language‑pack plugins, compile‑time AST analysis, and a specialized AMD loader to map source‑code calls to localized strings at runtime.

Taobao Frontend Technology
Taobao Frontend Technology
Taobao Frontend Technology
How VS Code Implements Multi‑Language Support: Deep Dive into NLS and Module Loading

NLS Overview

VS Code’s main process starts in src/main.js. At line 63 it checks for a locale and creates a nlsConfigurationPromise using lp.getNLSConfiguration, which later sets the VSCODE_NLS_CONFIG environment variable when the Electron onReady event fires.

What is NLS?

NLS stands for Native Language Support . The promise returned by lp.getNLSConfiguration receives four arguments: product.commit – the commit hash of the current VS Code build. userDataPath – the directory where VS Code stores user data (different per OS). metaDataFile – the generated nls.metadata.json file. locale – the language selected by the user.

product.commit

The product.json file adds a commit field during the build. Language packs are released together with each VS Code version, so the commit hash links a specific language‑pack plugin (e.g., vscode‑loc) to the matching VS Code release.

userDataPath

Typical locations:

# MacOS
~/Library/Application Support/Code

# Linux
~/.config

# Windows
%USERPROFILE%/AppData/Roaming

metaDataFile

The file nls.metadata.json is generated only after a full VS Code build. It contains three objects:

{
  "keys": { "vs/code/electron-browser/processExplorer/processExplorerMain": ["cpu","memory",...] },
  "messages": { "vs/code/electron-browser/processExplorer/processExplorerMain": ["CPU %","Memory (MB)",...] },
  "bundles": { "vs/code/electron-browser/processExplorer/processExplorerMain": ["vs/code/electron-browser/processExplorer/processExplorerMain"] }
}

The keys map source‑file identifiers to the keys used in nls.localize, while messages hold the default strings. The bundles list entry modules for the build process.

vs/nls Module

The module vs/nls is implemented as a plugin for the VS Code loader. It exports a localize function that formats a message with optional arguments. During compilation, calls like nls.localize('key', 'Default Message') are transformed to nls.localize(index, args), where the index reflects the call order within the file.

this.localize = (data, message, ...args) => localize(this._env, data, message, ...args);
function localize(env, data, message, ...args) {
  if (args.length === 0) {
    return message;
  }
  return message.replace(/\{(\d+)\}/g, (match, index) => {
    const arg = args[index];
    if (typeof arg === 'string') return arg;
    if (typeof arg === 'number' || typeof arg === 'boolean' || arg == null) return String(arg);
    return match;
  });
}

After compilation, the generated AMD module includes a special dependency syntax vs/nls!<em>modulePath</em>. The loader parses the part after the exclamation mark as a PluginDependency, loads the NLS plugin, and injects the appropriate language bundle.

define(__m[34], __M([1, 36]), function (require, exports, electron_1, strings_1, os_1, product_1, nls_1, ...) {
  // module body
});

The loader’s _loadPluginDependency method registers the plugin and calls its load function, which ultimately defines a module containing the localized strings.

Extensions and vscode‑nls

Extension processes do not use vs/nls. Instead they rely on the vscode-nls package. Before any extension code runs, initializeSettings reads VSCODE_NLS_CONFIG. Extensions call nls.loadMessageBundle(__filename) (the filename is injected at compile time) and then use nls.localize(index, args) to retrieve strings from the generated nls.metadata.json for that extension.

The entire i18n system hinges on compile‑time AST analysis, custom AMD loader plugins, and runtime environment variables to map source‑code calls to the correct localized text.

Understanding this workflow helps developers navigate VS Code’s source code and adapt similar i18n strategies for their own Electron‑based applications.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

ElectronVSCodei18nmodule loaderlanguage-packnls
Taobao Frontend Technology
Written by

Taobao Frontend Technology

The frontend landscape is constantly evolving, with rapid innovations across familiar languages. Like us, your understanding of the frontend is continually refreshed. Join us on Taobao, a vibrant, all‑encompassing platform, to uncover limitless potential.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.