ResXLocalizer🇧🇬 Български | 🇬🇧 English A Visual Studio Code extension that shows your
Table of contents
What the extension does
InstallationOption A — from the Marketplace (recommended)Search for "ResXLocalizer" in the Extensions view ( Option B — from a
|
| Column | Content |
|---|---|
| Actions | Buttons to edit/delete that row |
| Key | The key's name (shared across all languages) |
| Default / language | One column per .resx file in the family |
Editing a translation
- Click the ✏️ blue pencil at the start of the row → the row's cells become editable, and the icon turns into a 💾 green save icon.
- Change the text in any cell (directly, like a plain text field).
- Click the green icon again to save. The values are written back into each corresponding
.resxfile — the file's comments and formatting are left untouched; only the value changes.
Deleting a key
Click the 🗑️ red trash icon next to the row → a confirmation dialog appears → once confirmed, the key is removed from every language file on that row.
Adding a new key
There's always a special "New key" row pinned to the top of the table:
- Click its pencil icon to make it editable.
- Type the key's name into the first cell, and the values for each language.
- Click save. If the key field is empty, it's outlined in red and the save is rejected. If the key you typed already exists in the group, you'll be asked whether to overwrite its value.
Missing translations
A cell with no value (or only whitespace) is highlighted with a red accent on its left edge — you immediately see which language variants are still waiting for a translation.
Filtering
Under every column header (except Actions) there's a Filter... field — type text and only rows whose value in that column contains it are shown (case-insensitive). Filters on different columns combine — for example, a filter of Login on Key plus error on BG shows only rows matching both conditions at once.
Exporting and importing
Two buttons sit above every table, at the top right, level with the table's title — a green Import button (↓ icon) and a blue Export button (↑ icon):

Export
- Click Export.
- Choose CSV or JSON from the small picker that pops up.
- Pick where to save the file.
The exported file has one row per key, with a column per language (the base/default file's column is simply called default) — the exact same shape you see in the table. You can open it in Excel, Google Sheets, or hand it to a translation agency that doesn't use VS Code at all.
Import
- Click Import.
- Pick a
.csvor.jsonfile — it doesn't have to come from this extension's own Export; any file with aKeycolumn/field and matching language columns works.
Before anything is written to your .resx files, the file is validated:
- it must parse correctly (valid CSV/JSON), with a
Keycolumn/field present on every row; - if any row is malformed or missing its key, the import is rejected entirely — a dialog lists every problem found, and nothing gets changed on disk.
Once validation passes:
- rows with a key that doesn't exist yet are added as new translations;
- rows with a key that already exists overwrite the existing value for that language — every such overwrite is recorded in a log;
- blank cells are skipped (an empty cell never erases an existing translation);
- columns that don't match any language file open in this table are simply ignored.
If any existing values were overwritten, a new tab opens automatically right after the import finishes, listing every overwritten key with its old and new value side by side — plus any warnings (e.g. a key repeated inside the imported file) — so you can review exactly what changed before trusting the result:

How files are grouped
The extension recognizes files using .NET's resource-naming convention:
Strings.resx— the base ("neutral") file → shown as the default column.Strings.bg.resx— the Bulgarian variant.Strings.de-DE.resx— the German (Germany) variant, with a region.
Every file sharing the same base name (Strings) in the same folder forms one "family" and is shown together in one table. The keys shown are the union of the keys from every file in the group — so it's immediately obvious if a key only exists in some of the languages.
For translators (no coding experience needed)
If your job is just to translate text, don't worry about the rest of this document — here's all you need:
- Open the project in VS Code (someone on the dev team has already set it up and given you a link/folder).
- Click the ResXLocalizer icon in the left-hand bar.
- Check the box next to your language (e.g.
bg) in the list — a table will open. - Look for rows highlighted in red — those are the missing translations.
- For each row: click the pencil ✏️, fill in the translation in your column, then click the save icon 💾 (it turns green while you're editing).
- Done — the change is saved automatically to the file. Nothing else is needed (no "Save As", no terminal).
You don't need to touch the Key column on existing rows, or delete files — just fill in the values in your own column.
For C# / Visual Studio developers
If you're coming from Visual Studio and this extension is the first reason you're opening VS Code, here's a quick "dictionary" between the two environments:
| Visual Studio | VS Code + ResXLocalizer |
|---|---|
| Solution Explorer | Explorer panel (the files icon, top-left) |
Double-click a .resx → built-in Resource Designer |
Right-click a .resx → "ResXLocalizer: Open Resx Table", or check its box in the extension's sidebar |
Adding a new .resx for a new language by hand (copy/paste + rename) |
The "Add new" button in the sidebar — creates the file and fills in every key automatically |
<NeutralLanguage> in .csproj |
Detected automatically and shown as a badge on the base file |
For peace of mind: the extension never touches the project, its references, or the .csproj — it only reads and writes the .resx files themselves, preserving the XML structure that ResXFileCodeGenerator in Visual Studio expects. You can freely move the project between both editors — the files stay fully compatible with Visual Studio even after being edited through ResXLocalizer.
Because changes are minimal diffs in the XML itself (just a changed value, or one added <data> block), git diffs stay clean and easy to review in a pull request.
Developing the extension itself
For anyone building or maintaining ResXLocalizer itself:
npm install— install dependencies.npm run watch— esbuild in watch mode (forF5debugging in an Extension Development Host).npm run check-types— TypeScript check with no emitted output.npm run lint— ESLint.npm run package— production build (invoked byvscode:prepublish).npm run vsix— package the extension into a.vsixfile (@vscode/vsce).npm run publish— publish the current version straight to the Marketplace (vsce publish); requires being logged in viavsce login <publisher>first.
For a map of the source code itself (folder layout, data flow, conventions worth knowing before changing something), see docs/ARCHITECTURE.md — useful for contributors and AI coding agents alike.
Roadmap
- Support for other localization formats (
.json,.po,.arb, ...)
License
ResXLocalizer is distributed under Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0).
In short (full terms are in LICENSE):
- ✅ You're free to use it, modify/extend it, and share it with others — both in its original and in a modified form.
- ✅ The only requirement is giving credit to the original source (author + a link to the license), and that a modified version must be shared under the same license.
- ❌ It (or a modified version of it) may not be sold, rented out/subscribed to, or otherwise used for commercial gain.
Full legal license text: https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode Human-readable summary: https://creativecommons.org/licenses/by-nc-sa/4.0/

