Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>SFMC Language ServiceNew to Visual Studio Code? Get it now.
SFMC Language Service

SFMC Language Service

Jörn Berkefeld

|
854 installs
| (0) | Free
Language support for Salesforce Marketing Cloud (Engagement and Next) — AMPscript, SSJS, and GTL. Includes syntax highlighting, auto-completion, IntelliSense, diagnostics, formatting, snippets, and MCN compatibility checks.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

SFMC Language Service for VS Code

A Visual Studio Code extension providing comprehensive language support for Salesforce Marketing Cloud Engagement and Marketing Cloud Next — AMPscript, SSJS (Server-Side JavaScript), GTL (Guide Template Language), and MCN Handlebars. HTML files containing SFMC content are auto-detected and switched to the combined SFMC (AMPscript / SSJS) language, and .hbs (Handlebars) files receive always-on Marketing Cloud Next intelligence — all without any manual file-type changes.

Feature Overview

Feature AMPscript (.amp) SSJS (.ssjs) SFMC HTML (.html) Handlebars (.hbs) SQL (.sql)
Syntax highlighting ✓ ✓ ✓ (auto-detected) ✓ (built-in) ✓ (built-in)
Auto-completion ✓ ✓ ✓ ✓ —
Hover / IntelliSense ✓ ✓ ✓ ✓ —
Signature help ✓ ✓ ✓ ✓ —
Go-to definition — ✓ ✓ — —
Diagnostics / errors ✓ ✓ ✓ ✓ —
Formatting ✓ ✓ ✓ ✓ ✓
Variable resolution planned ✓ ✓ — —
Snippets 36 18 via sfmc language via handlebars —

Formatting runs a bundled copy of Prettier and prettier-plugin-sfmc in-process, so Format Document and Format on Save work for AMPscript, SSJS, SFMC HTML (mixed AMPscript/SSJS/Handlebars), MCN Handlebars, and SQL with no separate Prettier or plugin install. Plain HTML with no SFMC markers is intentionally left to other formatters. Toggle it with sfmcLanguageServer.enableFormatter (default true).

Variable resolution means the language service infers the concrete type (and where possible, the value) held in a variable. Hovering over a local variable reveals its resolved type rather than a generic any. This is fully available in SSJS and planned for AMPscript in a future release.

AMPscript

Syntax Highlighting

  • Block syntax (%%[ ... ]%%) and inline expressions (%%= ... =%%)
  • <script runat="server" language="ampscript"> blocks (flexible attribute order, single/double quotes)
  • Variables (@name), system variables (@@ExecCtx), keywords, operators, strings, comments, function calls
  • Personalization strings (%%FirstName%%, %%emailaddr%%)

Auto-Completion

  • 155 AMPscript functions with snippet-style parameter placeholders, organized across 14 categories (Content, Data Extension, HTTP, String, Math, and more — see ampscript-data)
  • 17 keywords with contextual snippets (var, set, if/then/elseif/else/endif, for/to/downto/do/next, and/or/not, true/false)
  • 74 system personalization strings with descriptions (subscriber identity, email/job metadata, dates, sender info, URLs, MobileConnect demographics, GroupConnect, execution context)
  • File-scoped variable suggestions extracted from @variable declarations in the current document
  • Context-aware — completions only appear inside AMPscript regions

Hover / IntelliSense

  • Typed function signatures with full parameter documentation
  • Required / optional parameter markers
  • Return type information and usage examples
  • Keyword and personalization string documentation

Signature Help

  • Parameter hints while typing function arguments
  • Active parameter highlighted as you type commas

Diagnostics

  • Delimiter matching: unmatched %%[/]%% and %%=/=%% pairs (both directions)
  • Nesting-aware control flow: stack-based IF/ENDIF and FOR/NEXT validation with line-level error locations
  • Unknown function detection: flags function calls not in the AMPscript catalog
  • Best-practice hints: informational warnings for bare subscriber attribute access without AttributeValue() wrapping

Marketing Cloud Next compatibility (sfmcLanguageServer.targetPlatform)

Set sfmcLanguageServer.targetPlatform to "next" (default: "engagement") to enable MCN-mode diagnostics. Engagement mode is completely unchanged — the setting is additive.

Setting value Behaviour
"engagement" (default) Existing diagnostics only — no MCN-specific checks
"next" Adds errors for MCN-unsupported functions and SSJS blocks; adds information hints for functions with behavioral differences

In "next" mode:

  • Error for any AMPscript function not available in Marketing Cloud Next (41 of 155 functions are supported). Example: InsertDE, AttachFile, ContentArea → "InsertDE is not supported in Marketing Cloud Next."
  • Information for supported functions with behavioral differences (FormatDate, Lookup, StringToDate) — the note is shown in the Problems panel at the call site so you can act on it before deploying
  • Error on any <script runat="server"> block — SSJS is not supported in Marketing Cloud Next
  • MCN Handlebars support activates: validation, completions, hover, signature help, and code actions for {{...}} mustaches and {!$...} built-in bindings. Binding hovers link to the Salesforce Developers documentation.

Hover cards always show the MCN support line regardless of the setting: "Supported in Marketing Cloud Next (API v67.0+)" or "Not supported in Marketing Cloud Next", so you can check at a glance without switching modes.

Variable Resolution

Variable resolution — inferring the type or value held by a @variable at any point in the file — is planned for a future release. The extension does not yet provide type-aware hover or diagnostics for AMPscript variables.

Snippets

36 built-in snippets:

Prefix Description
ampblock AMPscript block delimiters
ampinline Inline output expression
vout Variable output (%%=v(@var)=%%)
ampvar / ampset / ampvarset Variable declaration and assignment
ampif / ampifelse / ampifelseif Conditional blocks
ampfor / ampforrows FOR loops (counting and row-set iteration)
amplookup / amplookuprows / amplookuporderedrows Data Extension lookups
amphttpget / amphttppost HTTP requests with error handling
ampcloudpagesurl CloudPages URL builder
ampcontentblock Content Builder block inclusion
ampattrval Safe attribute retrieval
ampempty Empty check with default
ampupsertdata / ampinsertdata Data Extension DML
ampcreateobject SOAP API object creation
ampscripttag Script tag block
amptemplate Full email template boilerplate
ampssjs AMPscript-in-SSJS bridge pattern
amptreatascontent TreatAsContent from SSJS
ampredirectto Redirect to CloudPage
ampdateformat Common date format patterns
amprowsetloop RowSet loop with error check

SSJS (Server-Side JavaScript)

Syntax Highlighting

  • Standard JavaScript syntax, extended with SFMC-specific patterns
  • <script runat="server"> block recognition (without language="ampscript")

Auto-Completion

  • 223 SFMC-specific completions sourced from ssjs-data: 50 Platform.Function.* methods, 27 bare SSJS globals (Stringify, Now, Write, GUID, and more), 132 Core Library object methods across 41 objects, and 14 WSProxy operations — plus 127 ES3/ES5 built-in completions (Array, String, Number, Object, Math, Date, RegExp, etc.)
  • Platform.Function.*, Platform.Variable.*, Platform.Response.*, Platform.Request.* methods
  • Core library objects with full method listings: DataExtension, Subscriber, TriggeredSend, HTTP, Guard, and more — available after Platform.Load("Core", "1.1.5")
  • WSProxy method completions for new Script.Util.WSProxy()
  • Bare-name globals (Stringify(), Now(), GUID(), etc.) alongside their Platform.Function.* equivalents
  • Context-aware member completions: after a . only the relevant members are shown — the full global list is not injected into member-access positions

Hover / IntelliSense

  • TypeScript-powered: completions, hover, and diagnostics are backed by an embedded TypeScript language service with full SFMC type declarations — accurate, type-aware suggestions for all SFMC globals
  • Function signature with parameter names and types
  • ssjs.guide reference links embedded in hover cards
  • @deprecated notices for functions that should not be used in new code
  • @remarks requiresCoreLoad hints where Platform.Load("Core", "1.1.5") is required

Signature Help

  • Parameter hints while typing function arguments
  • Active parameter highlighted as you type commas
  • ssjs.guide links shown alongside the active signature

Go-to Definition

  • Navigate to SFMC function and object declarations in the bundled type definition file

Diagnostics

  • Missing Platform.Load: flags calls to Core Library objects (DataExtension, HTTP.Get, etc.) and bare globals (Stringify(), Now(), GUID(), etc.) when Platform.Load("Core", "1.1.5") has not been called before that line — order-aware
  • ES6+ syntax errors: let/const, arrow functions, for...of, generator functions, spread ..., destructuring are flagged as errors (SSJS runs in ES3/ES5 only)
  • TypeScript type diagnostics: type-aware errors powered by the embedded TypeScript service
  • Non-functional Core methods: Error on Core Library methods that resolve and are callable but never take effect on a live business unit — covers static calls such as FilterDefinition.Update(...) as well as instance calls on objects created via Init(...)
  • Deprecated Core classes: Warning on methods of deprecated Core Library classes (ContentAreaObj, Email, Portfolio, Template, Send, Send.Definition) — covers static calls such as Send.Definition.Add(...) as well as instance calls on objects created via Init(...)
  • Core-version-bound members: Error when a member that only exists up to Platform.Load("Core", "1") — such as ErrorUtil and ErrorUtil.ThrowWSProxyError — is used in a file that loads a newer Core version, because the member is undefined at runtime there. With Platform.Load("Core", "1") the usual deprecation Warning is shown instead
  • MCN incompatibility (when sfmcLanguageServer.targetPlatform is "next"): Error on any <script runat="server"> block — SSJS is not supported in Marketing Cloud Next

Suppressing "Cannot find name" for cross-file variables

SFMC CloudPages and emails often rely on variables that are defined in another asset — such as a global DEBUG flag set in a parent page, a subscriber key passed via AMPscript, or a configuration variable set in an included script. The embedded TypeScript service does not see those other files and will report them as unknown names.

Use an ESLint-style file-level /* global */ comment to tell the extension which names are supplied by the surrounding context. The comment must appear at the top of the .ssjs file (or inside a <script runat="server"> block for SFMC HTML files):

/* global DEBUG, deKey */

if (DEBUG) {
  Write(deKey);
}

Multiple names are separated by commas. The :readonly / :writable qualifiers used by ESLint are accepted for compatibility but have no effect on TypeScript diagnostics — all declared names are treated as any:

/* global DEBUG:readonly, deKey:writable */

You can also use /* globals */ (with a trailing s) — both spellings work identically. The declarations are scoped to the current document and are removed when the file is closed, so they cannot leak into other open files.

Variable Resolution

The embedded TypeScript service infers the type — and where possible the concrete value — held by a variable at each point in the file. Hovering over a local variable shows its resolved type (string, number, a specific object type, etc.) rather than a generic any. This works for variables whose initializer has a known type and for variables reassigned within the same scope.

Snippets

18 built-in snippets:

Prefix Description
ssjsblock <script runat="server"> wrapper
ssjsplatformload Platform.Load("core", "1")
ssjslookup / ssjslookuprows Platform.Function lookups
ssjsinsertdata / ssjsupsertdata Data Extension DML
ssjshttpget / ssjshttpgetsimple / ssjshttppost HTTP requests
ssjswsproxy / ssjswsproxycreate WSProxy operations
ssjstrycatch Try/catch error handling
ssjsde DataExtension Init/Retrieve
ssjsvarbridge AMPscript variable bridge
ssjsrequestparam / ssjsformdata Request parameters
ssjsredirect / ssjscloudpagesurl Navigation
ssjstemplate Full CloudPage template

How .ssjs files are interpreted (sfmcLanguageServer.ssjsFileMode)

By default a .ssjs file is treated as plain Server-Side JavaScript — the whole file is linted as SSJS. Some tooling (notably SSJS Manager) instead stores .ssjs files as HTML that wraps the code in <script runat="server">…</script> (sometimes with AMPscript/HTML around it). Feeding such a file to the SSJS linter whole would flag the wrapper as broken JavaScript.

Use sfmcLanguageServer.ssjsFileMode (resource-scoped) to choose how .ssjs files are read:

Value Behaviour
"javascript" (default) Every .ssjs file is plain SSJS — today's behaviour, no content scan.
"auto" Per-file detection: a .ssjs that wraps its code in <script runat="server"> (or contains AMPscript) is treated as SFMC content so the embedded SSJS is linted inside the tag; a plain-JS .ssjs stays SSJS. Enables interop with SSJS Manager. Costs a small per-edit content scan.
"sfmc" Every .ssjs file is forced to SFMC content — choose this only when all your .ssjs files are script-wrapped (a plain-JS .ssjs would then be treated as HTML, not linted as SSJS). No content scan.

The default preserves existing behaviour. SSJS Manager can set "auto" per-workspace automatically.

HTML Files — SFMC Language

Any .html file that contains SFMC content is automatically switched to the SFMC (AMPscript / SSJS) language (sfmc) — no manual language selection needed.

Detection triggers (checked on file open and on every content change, so pasting code into a blank file works immediately):

  • AMPscript block: %%[ ... ]%%
  • AMPscript inline: %%= ... =%%
  • AMPscript script tag: <script language="ampscript">
  • SSJS script tag: <script runat="server"> (without language="ampscript")

What you get after detection:

  • Language shown in the VS Code status bar as SFMC (AMPscript / SSJS) with the blue/yellow icon
  • Full AMPscript IntelliSense (completions, hover, signature help, diagnostics) inside %%[ ]%% and %%= =%% regions
  • Full SSJS IntelliSense (completions, hover, signature help, go-to definition, TypeScript diagnostics) inside <script runat="server"> blocks — with correct line/column offsets back to the HTML document
  • Syntax highlighting for both AMPscript and SSJS content within the same file

Plain HTML files (no SFMC content) are never affected and remain as html.

GTL (Guide Template Language)

GTL uses {{ }} delimiters and is a thin wrapper around AMPscript. The extension provides:

  • Context-aware completions inside {{ }} — AMPscript functions, variables, and personalization strings
  • 8 built-in snippets:
Prefix Description
gtlexpr GTL expression {{ }}
gtlvar Variable output {{ v(@var) }}
gtllookup Lookup via GTL
gtlif Inline conditional {{ IIf(...) }}
gtlcontent ContentBlockByKey via GTL
gtlpersonalization Personalization string
gtlattrval AttributeValue via GTL
gtlformatdate Date formatting via GTL

Handlebars (.hbs) — Marketing Cloud Next

.hbs files use VS Code's built-in Handlebars language (HTML plus Handlebars), so syntax highlighting works out of the box — no custom language is registered by this extension. On top of that, the extension attaches its language server to Handlebars documents and provides MCN Handlebars intelligence for the Salesforce Marketing Cloud Next template engine.

Because Handlebars is a Marketing Cloud Next-only feature, .hbs files are always treated as targetPlatform: "next" regardless of the sfmcLanguageServer.targetPlatform setting. You get the same MCN Handlebars support that Engagement HTML files only receive when the setting is switched to "next".

What you get in .hbs files:

  • Completions for MCN Handlebars helpers inside {{ ... }} mustaches and for built-in {!$...} data bindings
  • Hover documentation for helpers and bindings, with links to the Salesforce Developers documentation
  • Signature help for helper arguments — MCN helper arguments are whitespace-separated (e.g. {{substring value 0 3}}), so hints appear as you type spaces
  • Diagnostics for unsupported Handlebars constructs (partials, decorators, and built-in helpers absent from MCN's locked-down engine)
  • Code actions / quick fixes for MCN Handlebars diagnostics

Status Bar

A compact entry appears in the VS Code status bar (bottom-right) as soon as the extension activates. Its label reflects the active sfmcLanguageServer.targetPlatform: sfmc-e for Engagement and sfmc-next for Marketing Cloud Next.

  • Spinner while the language server is starting up.
  • Check mark once the server is running and ready.
  • Error icon if the server stops or fails.
  • Click to open the language server output channel.
  • Hover for a tooltip with a Show Output link, live server status, active trace level (if enabled), a quick Settings link, and an MCE Mode / MCNext Mode line that opens Settings filtered to the targetPlatform option. The label and tooltip update automatically when the setting changes.

Formatting

The extension ships a built-in document formatter powered by a bundled copy of Prettier and prettier-plugin-sfmc — no separate install or .prettierrc is required. It runs entirely in-process, so Format Document and Format on Save work out of the box.

Supported languages

Language Trigger
AMPscript *.ampscript, *.amp
SSJS *.ssjs
SFMC HTML (mixed content) *.html auto-switched to sfmc on markers
MCN Handlebars *.hbs
SQL *.sql

Mixed-content SFMC HTML is formatted as one unit: the surrounding HTML, embedded AMPscript (%%[ … ]%%, %%= … =%%), embedded SSJS (<script runat="server">), and MCN Handlebars ({{ … }}) are all handled together.

Plain HTML (files without SFMC markers) is intentionally not claimed — it keeps the html language id and is left to VS Code's HTML formatter or your own.

Choosing a formatter (coexistence with the Prettier extension)

The built-in formatter is always registered, but VS Code decides which formatter runs via editor.defaultFormatter. The extension is designed to just work out of the box — no manual Prettier or prettier-plugin-sfmc install required:

  • For every SFMC language that has no formatter set in your workspace/folder settings, the extension quietly claims it (writes itself to your workspace .vscode/settings.json). A formatter you set only in your User (global) settings does not block this per-workspace takeover.
  • It only asks when there is a genuine conflict — i.e. one or more SFMC languages already have a different editor.defaultFormatter (the Prettier extension esbenp.prettier-vscode, or any other formatter) in your workspace/folder settings. In that case the free languages are still claimed silently, and a prominent modal dialog appears once per workspace offering to switch the conflicting languages to the SFMC formatter too. Your answer is remembered internally per workspace — it is not written to your settings file.
  • If nothing conflicts, you are never prompted.

Whenever the extension claims one or more languages silently, it shows a brief informational notification (which auto-dismisses) listing exactly which languages it now formats. After the conflict prompt, it also confirms whether the conflicting languages were switched to the SFMC formatter or kept with your existing one.

Re-showing the prompt. To force the conflict prompt to appear again (e.g. to reset your earlier choice), add "sfmcLanguageServer.formatterPromptDismissed": false to your workspace .vscode/settings.json. The extension removes that entry automatically once you answer, so it never lingers in a git-tracked settings file.

Team lead / admin opt-out. To pin a formatter choice for a whole repository and stop the extension from ever prompting or silently claiming languages, commit "sfmcLanguageServer.formatterPromptDismissed": true to the project's .vscode/settings.json (alongside your desired editor.defaultFormatter per-language blocks). With true set, the extension leaves your editor.defaultFormatter values completely untouched and never shows the modal — and, unlike the transient false reset value, it never removes an explicit true. This is the recommended way to standardise the formatter (SFMC formatter, Prettier extension, or a mix) across a team without each member being asked. (sfmcLanguageServer.enableFormatter: false also silences everything, but it additionally turns the built-in formatter off — use formatterPromptDismissed: true when you still want the built-in formatter available where you point editor.defaultFormatter at it.)

Language IDs, not aliases. Per-language override blocks must use the lowercase language IDs — [ampscript], [ssjs], [sfmc], [handlebars], [sql]. The capitalised display names (e.g. [AMPscript]) are aliases and are ignored by VS Code's language-scoped settings.

Auditing the decision. On every activation the extension writes a single status line to the SFMC Prettier Formatter Output channel (Output panel → "SFMC Prettier Formatter") describing the current state — whether the prompt was already answered for this workspace, whether the admin opt-out is active, which languages conflict, and which (if any) were newly claimed. Use it to confirm why (or why not) the prompt appeared.

To switch formatters at any time, set editor.defaultFormatter per language in .vscode/settings.json, for example:

{
  // Use the built-in SFMC formatter for AMPscript…
  "[ampscript]": { "editor.defaultFormatter": "joernberkefeld.sfmc-language" },
  // …but hand SSJS to the Prettier extension:
  "[ssjs]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
  // …and keep the remaining three on the built-in SFMC formatter:
  "[sfmc]": { "editor.defaultFormatter": "joernberkefeld.sfmc-language" },
  "[handlebars]": { "editor.defaultFormatter": "joernberkefeld.sfmc-language" },
  "[sql]": { "editor.defaultFormatter": "joernberkefeld.sfmc-language" },
}

All five SFMC language IDs ([ampscript], [ssjs], [sfmc], [handlebars], [sql]) support this per-language override. Set sfmcLanguageServer.enableFormatter to false to turn the built-in formatter off entirely.

Config override and its limits

A workspace .prettierrc*, package.json "prettier" field, or .editorconfig overrides the standard defaults (e.g. tabWidth, printWidth, singleQuote), and a workspace .prettierignore is respected — ignored files are skipped.

Two things are always enforced, regardless of your config:

  1. The bundled prettier-plugin-sfmc is used. A "plugins" entry in your config file is ignored (loading a second Prettier from disk would break the mixed-content parser).
  2. The bundled Prettier version is used.

If you need full control over the Prettier or plugin version, or a custom plugins list, use the Prettier extension (esbenp.prettier-vscode) with a project-local prettier / prettier-plugin-sfmc install instead, and point the relevant editor.defaultFormatter at it.

Model Context Protocol (MCP) for AI Assistants

This extension registers the mcp-server-sfmc MCP server with VS Code so GitHub Copilot agent mode (and other MCP-aware chat flows) can discover SFMC tooling automatically — validation and lookups for AMPscript and SSJS, diff-aware review, fix suggestions, catalogs as resources, and guided prompts. You do not need a separate npm install or a manual .vscode/mcp.json entry for that discovery; the server is still loaded via npx when the tool runs.

Finding this extension vs. the MCP Server Gallery in VS Code

  • In the Extensions view, @contribute:mcp filters extensions that contribute MCP server definitions. This extension appears there because it declares that contribution and registers mcp-server-sfmc.
  • The @mcp filter opens the MCP Server Gallery, which is backed by the curated GitHub MCP Registry (not the full Marketplace catalog). Publishing the VS Code extension does not add the server to that gallery. The npm package mcp-server-sfmc is registered as io.github.JoernBerkefeld/mcp-server-sfmc (see mcp-server-sfmc mcpName / server.json); after a release, metadata is published to the MCP Registry via mcp-publisher (locally or from CI). Quickstart: Publish an MCP Server to the MCP Registry. Ensure chat.mcp.gallery.enabled is on if the gallery does not appear.

Requirements: VS Code 1.101 or newer (see engines in this extension's package.json). Older versions can add the server manually as described in the mcp-server-sfmc README (also covers Cursor, Claude Desktop, Windsurf, and global or local installs).

File Types

File pattern Language Notes
*.ampscript, *.amp AMPscript Always
*.ssjs SSJS Always
*.html containing SFMC content SFMC (AMPscript / SSJS) Auto-detected on open and on paste
*.html without SFMC content html (unchanged) Extension does not touch plain HTML
*.hbs Handlebars (built-in) MCN Handlebars intelligence, always in next mode

Installation

Option 1: Install from VSIX

  1. Build and package:

    npm install
    npm run compile
    npm run package
    
  2. In VS Code: Extensions > ... > Install from VSIX... > select the generated .vsix file

Option 2: Run in Extension Development Host

  1. Open the vscode-sfmc-language folder in VS Code
  2. Run npm install and npm run compile
  3. Press F5 and choose Launch Client
  4. Open a .ampscript, .amp, .ssjs, or .hbs file in the Extension Development Host

Configuration

Setting Default Description
sfmcLanguageServer.maxNumberOfProblems 100 Maximum number of diagnostics reported per file
sfmcLanguageServer.trace.server off Traces LSP communication (off, messages, verbose)
sfmcLanguageServer.ssjsFileMode javascript How .ssjs files are interpreted: javascript (plain SSJS, default), auto (detect script-wrapped vs plain per file — SSJS Manager interop), or sfmc (force all .ssjs to SFMC)
sfmcLanguageServer.enableFormatter true Enable the built-in Prettier-based formatter (AMPscript, SSJS, SFMC HTML, Handlebars, SQL)
sfmcLanguageServer.formatterPromptDismissed false Set to false to force the coexistence prompt to reappear (auto-removed once answered; state persisted internally per workspace). Set to true as an admin opt-out — the extension then never prompts and never writes editor.defaultFormatter, and an explicit true is left untouched

Architecture

vscode-sfmc-language/
├── client/                   Language client (VS Code extension host)
│   ├── src/extension.ts        Starts the LSP server, auto-detects SFMC HTML files
│   └── src/test/               Integration tests (completion, diagnostics, hover)
├── server/                   Language server (Node.js LSP)
│   ├── src/server.ts           LSP adapter — completions, hover, signature help, diagnostics
│   └── src/tsService.ts        Embedded TypeScript language service for SSJS
├── syntaxes/                 TextMate grammars for syntax highlighting
│   ├── ampscript.tmLanguage.json   AMPscript + GTL grammar (includes SSJS embed rules)
│   ├── ssjs.tmLanguage.json        SSJS grammar (extends JavaScript)
│   └── sfmc.tmLanguage.json        SFMC HTML grammar (delegates to ampscript grammar)
├── snippets/                 VS Code snippet definitions
│   ├── ampscript.snippets.json
│   ├── ssjs.snippets.json
│   └── gtl.snippets.json
├── resources/icons/          Language icons (amp, ssjs, sfmc)
├── language-configuration.json      AMPscript bracket/comment/folding config
├── ssjs-language-configuration.json SSJS bracket/comment/folding config
└── package.json              Extension manifest

Language intelligence is delegated to two shared packages:

  • sfmc-language-lsp — AMPscript and SSJS function catalog, validators, hover, completions, code actions
  • ssjs-data — SSJS function/object metadata and TypeScript declarations (sfmc-globals.d.ts)

Development

npm install          # Install root + client + server dependencies
npm run compile      # TypeScript compilation (type-checked)
npm run watch        # Watch mode for development
npm test             # Run integration tests in VS Code instance
npm run lint         # ESLint
npm run package      # Package as .vsix

The extension uses esbuild for production bundling (vscode:prepublish), reducing load time and VSIX size.

Telemetry

This extension collects a small amount of anonymous usage telemetry to understand adoption and which features are used, so development can be prioritised. It is sent to a PostHog project hosted in the EU and contains no personally identifiable information, file contents, credentials, or business-unit / tenant identifiers.

What is collected: extension activation (with the configured target platform, .ssjs file mode, and booleans indicating whether a small allowlist of related SFMC extensions are co-installed), which SFMC language(s) a session edits, the formatter-coexistence outcome (and, on failed, a closed-enum stage plus sanitized error name/code — never the exception message, stack, or file paths), and whether a known conflicting AMPscript extension is active. Events are keyed by VS Code's anonymous machine id only. The full catalogue ships as telemetry.json in the extension root and is visible via the VS Code CLI --telemetry dump.

Opt out: telemetry is gated solely by VS Code's global telemetry setting. Set telemetry.telemetryLevel to off and nothing is sent — the extension respects isTelemetryEnabled and stops immediately when you change it. There is no separate extension setting to configure.

Notes

  • AMPscript function metadata is sourced from the ampscript-data shared package.
  • SSJS function metadata and TypeScript declarations are sourced from the ssjs-data shared package.
  • This extension provides editing support for SFMC languages — it does not execute AMPscript or SSJS code.
  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft