Skip to content

Features

Most of Label Alchemy is free. The heavy lifting — converting and deploying your whole project at once — is unlocked with a license. Gated features are marked Paid below; everything else works on the free tier with no account and no API key.

Label Alchemy detects hard-coded strings across all Salesforce source types in a single pass:

File typeWhat’s detected
Apex (.cls)Exception messages, addError values, return strings, result.put values, string literals
LWC JavaScriptToast titles/messages, property assignments, getter returns, template literals
LWC HTMLlabel, placeholder, title, value, message, header attributes; static text content
Aura JavaScriptcomponent.set strings, toast titles/messages, string assignments
Aura Markup (.cmp, .app)label, placeholder, title, value, description attributes; static text content

The scanner skips strings that aren’t user-facing copy: Salesforce API names (anything with __), SOQL/SOSL queries, framework references ($A.get, v.*, c.*, lightning:, force:), debug calls (System.debug, console.*, Logger.*), MIME types, single characters, numeric strings, and already-converted $Label.* references. Apex test classes are skipped by default when scanning a folder (toggle with labelAlchemy.scanTestClasses).

Built-in technical denylist [Free] · Custom denylist [Paid]

Section titled “Built-in technical denylist [Free] · Custom denylist [Paid]”

A built-in technical denylist ships free — HTTP verbs/headers, MIME and charset tokens, and dynamic-SOQL fragments never get flagged. With a license, add your noise — brand and product names, enum/API values, status codes, feature-flag names — via Label Alchemy: Edit Custom Denylist or the Manage denylist link in the Audit Report. Matching is whole-value and case-insensitive (no substrings/wildcards). Commit the labelAlchemy.denylist setting to your workspace so every developer scans by the same rules.

Before scanning, content is cleaned in a column-preserving pass that blanks block comments, inline comments (quote-aware), HTML comments, and multi-line SOQL [SELECT … ] blocks — eliminating false positives from commented-out code while keeping line/column numbers accurate.

Right-click any folder, or pick one from the Command Palette, to scan your whole project. Bounded-concurrency reads (12 at a time) prevent EMFILE crashes on large repos. A 1.5 MB per-file guard skips minified/generated files. A cancellable progress bar shows N/total.

Deterministic naming [Free] — no API key, offline, $0

Section titled “Deterministic naming [Free] — no API key, offline, $0”

Label names are generated locally: meaningful words split out (fillers stripped), a light context prefix added when unambiguous (Error_, Button_, Placeholder_), your label prefix applied, the 40-character Salesforce limit enforced, and uniqueness ensured (_2, _3…). Produces valid Snake_Case by default; switch to PascalCase with labelAlchemy.labelNameCase.

AI naming [Free per-file · Paid project-wide] — BYOK

Section titled “AI naming [Free per-file · Paid project-wide] — BYOK”

Enable labelAlchemy.useAiNaming to have an LLM suggest richer, context-aware names. The model’s suggestion is always sanitized to a valid Salesforce name. Two scopes (labelAlchemy.aiNamingScope):

  • Per-file (chunk) — Free: each file is named on its own context.
  • Project-wide (project) — Paid: also reads your existing CustomLabels.labels-meta.xml so an identical string reuses its existing label and new names follow your project’s convention.

Tune output with aiNamingStyle (concise / descriptive / domain-rich), aiNamingGuidance (free-text instructions), and aiGenerateDescriptions (also writes each label’s Description field). Any supported provider works — including free local models via Ollama or LM Studio. Provider setup →

Every generated name is an editable input in the diff panel. Validation runs live (regex, 40-char limit, duplicate detection); the Approve button stays disabled until all names are valid.

Set a Salesforce category on your labels right in the review panel — per label, or across a whole file in one click. It writes straight to the label’s <categories>, so labels land in your org already sorted instead of dumped in one bucket.

A string that appears more than once maps to one label — both within a single scan and across separate scans, days apart, by reading your existing labels file. Identical strings collapse to one shared label automatically; new labels merge into your XML.

  • Component-grouped layout — an LWC component’s .html and .js review together under one header.
  • Collapsible sections with Expand all / Collapse all; collapsed sections with an invalid name show ⚠.
  • Per-label checkboxes with indeterminate file-level state.
  • VS Code native diff editor per file (live — updates on checkbox change).
  • LWC sidecar preview for the auto-added @salesforce/label imports and getters.
  • Filter box by component or file name.
  • Disk-backed streaming apply — O(1-file) memory; works on repos with thousands of files.
  • Automatic LWC sidecar@salesforce/label import + getter added to the sibling .js.
  • CustomLabels XML merge — new labels merged into your existing file; existing labels never overwritten; anchored to the right force-app package; sorted alphabetically.
  • Catch diverging-name duplicates [Paid] — automatic reuse handles identical text; this flags a value that already has a label under a different name (from a manual rename or AI-named label) and prompts you to reuse the existing label or create a new one — one prompt, no duplicate-value sprawl.

Every convert writes a timestamped folder to labelalchemy-changes/ — no git required — containing a readable summary.md (labels created, files modified, component breakdown, deploy status), the same data as summary.csv, and a portable package.xml you can deploy or hand to a teammate. A one-click Open summary notification appears the moment a conversion finishes.

Scan a folder or project and see the full picture before converting:

  • Total hard-coded string count and breakdown by component type (Apex / LWC / Aura)
  • Top-offenders table; filter by component or file name; lazy per-file drill-down
  • An ”≈ N hrs estimated manual conversion” cost-estimate KPI, with editable assumptions (labelAlchemy.audit.minutesPerString, optional labelAlchemy.audit.hourlyRate)

Apply conversions across all files from the Audit Report in one approval flow, deduped as it goes, grouped by component bundle.

Download the Audit Report as a CSV — file path, component, string count, plus the estimate summary and per-file minutes — for sharing with architects, QA, or clients.

  • One-click deploy after convert — runs sf project deploy start on just the changed files and new labels. No terminal step.
  • Scoped entry points — Deploy Last Conversion (Command Palette), Deploy This File / This Folder (right-click).
  • Production guardrail — deploying to a production org is hard-blocked (no override); only sandboxes, scratch orgs, and Developer Edition may proceed; unknown org type is blocked (fail-safe).
  • Scales to large orgs — for >25 files, generates a package.xml manifest and deploys via --manifest, staying within OS command-line limits.
ProviderModel examplesKey required
Anthropic (Claude)claude-sonnet-4-6, claude-haiku-4-5Yes
OpenAIgpt-4o, gpt-4o-mini, gpt-4.1Yes
Google Geminigemini-2.0-flash, gemini-1.5-proYes
DeepSeekdeepseek-chat, deepseek-reasonerYes
OpenRoutermeta-llama/llama-3.3-70b-instruct, + 100 othersYes
Ollama (local)llama3.3, qwen2.5:14b, deepseek-r1:14bNo
LM Studio (local)Any loaded modelNo
Custom OpenAI-compatibleAny endpointOptional

Provider setup guide →

Scan Active File · Scan Folder · Configure Settings · Switch Naming Mode (Deterministic / AI) · Enter License Key · Deactivate License on This Device · Edit Custom Denylist · Deploy Last Conversion to Org [Paid] · Deploy This File to Org [Paid] · Deploy This Folder to Org [Paid] — all prefixed Label Alchemy: in the Command Palette.

SettingWhat it does
useAiNamingTurn on AI naming (default off — deterministic, offline, free)
provider / model / baseUrlLLM provider, model id, and optional API base URL override
aiNamingScopechunk (free, per-file) or project (Paid, project-wide reuse + convention)
aiNamingStyleconcise / descriptive / domainRich name richness
aiNamingGuidanceExtra free-text instructions appended to the AI naming prompt
aiGenerateDescriptionsAlso write a Description for each label (extra tokens)
labelNameCasesnake (default) or pascal for new names
labelPrefixString prepended to every generated label name (e.g. MyApp_); does not change the c. reference namespace
denylistYour custom denylist terms (Paid; built-in technical list is always on)
scanTestClassesInclude Apex test classes in folder scans (off by default)
audit.minutesPerString / audit.hourlyRateAudit Report cost-estimate assumptions