npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

eslint-plugin-sfmc

v4.16.0

Published

ESLint plugin for Salesforce Marketing Cloud Engagement+Next - AMPscript, Server-Side JavaScript (SSJS) and Handlebars

Readme

eslint-plugin-sfmc

Unified ESLint plugin for Salesforce Marketing Cloud — linting rules for both AMPscript and Server-Side JavaScript (SSJS).

Installation

npm install eslint-plugin-sfmc --save-dev

Requires ESLint 9+ (flat config).

Quick Start

// eslint.config.js
import sfmc from 'eslint-plugin-sfmc';

export default [
  // Lint standalone .ampscript/.amp and .ssjs files
  ...sfmc.configs.recommended,

  // Lint AMPscript + SSJS embedded in .html files
  ...sfmc.configs.embedded,
];

VS Code Setup

To see eslint(sfmc/...) diagnostics in VS Code for .amp, .ssjs, and .html files you need the VS Code ESLint extension to validate the custom SFMC language IDs.

Option A — Install vscode-sfmc-language (recommended)

The SFMC Language Service extension contributes the SFMC language IDs and automatically configures eslint.validate for you. No manual settings required.

Option B — Manual configuration

Add the following to your .vscode/settings.json:

{
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "typescript",
    "typescriptreact",
    "html",
    "vue",
    "markdown",
    "ampscript",
    "ssjs",
    "sfmc",
    "handlebars"
  ]
}

Why eslint.validate and not eslint.probe? eslint.probe silently skips files for language IDs that the ESLint extension does not natively recognise. eslint.validate forces the extension to process those files regardless of language ID.

Configs

Marketing Cloud Engagement (default)

| Config | Files | What it does | | -------------------------- | ---------------------------- | --------------------------------------------------------- | | sfmc.configs.ampscript | **/*.ampscript, **/*.amp | AMPscript rules only (recommended severity) | | sfmc.configs.ssjs | **/*.ssjs | SSJS rules only (recommended severity) | | sfmc.configs.recommended | Both of the above | All rules at recommended severity for standalone files | | sfmc.configs.embedded | **/*.html | Combined processor extracts both languages from HTML | | sfmc.configs.strict | All of the above + HTML | All rules at error severity for standalone and embedded |

recommended, embedded, and strict are arrays — spread them with ....

Marketing Cloud Next

Use the -next config variants when targeting Marketing Cloud Next (MCN). MCN supports only a subset of AMPscript functions and does not support SSJS at all. Handlebars is MCN's templating language, so the -next configs also lint the {{...}} helpers and {!$...} bindings extracted from HTML and standalone .hbs files (see Handlebars Rules).

| Config | Files | What it does | | ---------------------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------- | | sfmc.configs['ampscript-next'] | **/*.ampscript, **/*.amp | AMPscript rules + flags functions unsupported in MCN (single config object) | | sfmc.configs['ssjs-next'] | **/*.ssjs | Flags all SSJS API calls as MCN-unsupported; all other SSJS quality rules disabled | | sfmc.configs['recommended-next'] | Both of the above + **/*.hbs | AMPscript MCN-aware + SSJS flagged + Handlebars rules for standalone .hbs files | | sfmc.configs['embedded-next'] | **/*.html, **/*.hbs | AMPscript MCN-aware + SSJS flagged + Handlebars rules for HTML-embedded code and .hbs | | sfmc.configs['strict-next'] | All of the above + HTML + **/*.hbs | All AMPscript rules at error severity + MCN flag; SSJS fully flagged; Handlebars rules on |

Standalone .hbs files (VS Code's built-in Handlebars language) are treated as MCN by default — Handlebars only runs on Marketing Cloud Next, so a .hbs file is always linted with the full Handlebars rule set. This is deliberately wired only into the -next configs; the classic recommended / strict (Engagement) configs never lint .hbs.

recommended-next, embedded-next, and strict-next are arrays — spread them with ....

// eslint.config.js — targeting Marketing Cloud Next
import sfmc from 'eslint-plugin-sfmc';

export default [...sfmc.configs['recommended-next'], ...sfmc.configs['embedded-next']];

AMPscript Rules (amp-*)

| Rule | Default | Description | | ------------------------------------------------------------------------------------------- | ------------------------ | ----------------------------------------------------------------------------------- | | sfmc/amp-no-unknown-function | error | Disallow calls to unknown AMPscript functions | | sfmc/amp-no-mcn-unsupported | off (error in -next) | Flag AMPscript functions unavailable in the targeted MCN API version (apiVersion) | | sfmc/amp-function-arity | error | Enforce correct argument counts | | sfmc/amp-arg-types | error | Check that literal arguments match expected parameter types and allowed values | | sfmc/amp-set-requires-target | error | Require set to have a target variable | | sfmc/amp-no-smart-quotes | error | Disallow smart/curly quotes in strings | | sfmc/amp-no-var-redeclaration | warn | Disallow re-declaring a variable with var | | sfmc/amp-no-empty-block | warn | Disallow empty %%[ ]%% blocks | | sfmc/amp-no-loop-counter-assign | warn | Disallow assigning to the for loop counter | | sfmc/amp-no-inline-statement | warn | Disallow statements inside inline expressions | | sfmc/amp-no-deprecated-function | warn | Flag deprecated functions and suggest replacements | | sfmc/amp-no-nonfunctional-function | error | Flag functions that resolve but have no working runtime invocation | | sfmc/amp-naming-convention | warn | Enforce variable naming convention | | sfmc/amp-no-empty-then | warn | Disallow IF with empty THEN branch | | sfmc/amp-require-rowcount-check | warn | Require RowCount check before FOR on LookupRows | | sfmc/amp-no-html-comment | warn | Disallow HTML comments inside AMPscript blocks | | sfmc/amp-no-js-line-comment | warn | Disallow JS-style // line comments in AMPscript | | sfmc/amp-no-nested-script-tag | error | Disallow <script> tags nested inside AMPscript script tags | | sfmc/amp-no-nested-ampscript-delimiter | error | Disallow AMPscript delimiters nested inside AMPscript blocks | | sfmc/amp-prefer-attribute-value | off | Prefer AttributeValue() over bare personalization | | sfmc/amp-require-variable-declaration | off | Require var before set | | sfmc/amp-no-email-excluded-function | off | Flag functions unavailable in email context |

SSJS Rules (ssjs-*)

| Rule | Default | Description | | ------------------------------------------------------------------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | sfmc/ssjs-require-platform-load | error | Require Platform.Load("core") before Core or requiresCoreLoad globals | | sfmc/ssjs-no-unsupported-syntax | error | Flag ES6+ syntax not supported by SFMC | | sfmc/ssjs-no-unknown-function | error | Disallow unknown methods on Platform.*, HTTP, Core Library, and WSProxy | | sfmc/ssjs-no-mcn-unsupported | off (error in -next) | Flag all SSJS API usage as unsupported in Marketing Cloud Next | | sfmc/ssjs-no-deprecated-function | error | Flag deprecated SFMC SSJS APIs (Classic Content classes, ErrorUtil); reports a stronger "undefined at runtime" message when the loaded Core version no longer provides the API | | sfmc/ssjs-no-nonexistent-global | error | Flag documented SSJS globals that throw ReferenceError at runtime | | sfmc/ssjs-no-property-call | error | Disallow calling Platform.Request/Response properties as functions | | sfmc/ssjs-no-invalid-property-access | error | Disallow reading write-only properties (postData) and assigning to read-only ones (Platform.Request.*) | | sfmc/ssjs-no-clr-header-access | error | Disallow CLR-unsafe reads of HttpResponse.headers; read via for..in | | sfmc/ssjs-require-string-clr-content | error | Require wrapping HttpResponse.content with String() before use | | sfmc/ssjs-platform-function-arity | error | Enforce correct arity for Platform.Function.* | | sfmc/ssjs-require-platform-load-order | error | Require Platform.Load() before Core usage in order | | sfmc/ssjs-no-hardcoded-credentials | error | Flag hardcoded keys in encryption calls | | sfmc/ssjs-cache-loop-length | warn | Require caching .length in for-loops | | sfmc/ssjs-require-hasownproperty | warn | Require hasOwnProperty guard in for-in loops | | sfmc/ssjs-prefer-platform-load-version | warn | Enforce a minimum Platform.Load version string; autofix is withheld in files using ErrorUtil | | sfmc/ssjs-no-unavailable-method | warn | Flag Array/String methods unavailable or broken in SFMC's ES3 engine | | sfmc/ssjs-no-nonfunctional-method | warn | Flag Core Library methods that never take effect at runtime | | sfmc/ssjs-prefer-parsejson-safe-arg | warn | Require string coercion on ParseJSON argument | | sfmc/ssjs-no-switch-default | warn | Disallow default clause in switch statements | | sfmc/ssjs-no-treatascontent-injection | warn | Flag dynamic string concatenation in TreatAsContent calls | | sfmc/ssjs-core-method-arity | warn | Enforce correct argument counts for Core Library object methods | | sfmc/ssjs-arg-types | warn | Check that literal arguments match expected parameter types |

Handlebars Rules (hbs-*)

Handlebars is the templating language for Marketing Cloud Next (MCN) only. These rules are enabled at error severity in the -next configs — applied both to {{...}} extracted from HTML and to standalone .hbs files — and are off in the classic (Engagement) configs — in classic SFMC, {{...}} is plain content and must not be flagged.

| Rule | Default (-next) | Description | | --------------------------------------------------------------------------------- | ----------------- | ------------------------------------------------------------------------------------ | | sfmc/hbs-no-unknown-helper | error | Disallow helper invocations that are not part of the MCN catalog | | sfmc/hbs-no-unknown-binding | error | Disallow unknown {!$...} built-in data bindings | | sfmc/hbs-helper-arity | error | Enforce correct positional-argument counts for known helpers | | sfmc/hbs-no-unsupported-construct | error | Disallow constructs unsupported by the MCN engine (partials, decorators, log) | | sfmc/hbs-no-mcn-unsupported | error | Flag helpers and bindings unavailable in the targeted MCN API version (apiVersion) |

MSO / Outlook email checks

Email HTML for SFMC frequently contains Outlook conditional comments (<!--[if mso]>…<![endif]-->), MSO-only CSS, and VML fallbacks. These checks are provided by eslint-plugin-mso-email, which ships as a bundled dependency of eslint-plugin-sfmc — you do not load it separately.

The MSO rules are auto-included in the HTML-embedded configs: embedded, strict, embedded-next, and strict-next. When you lint an .html file with any of these, the combined sfmc/sfmc processor also extracts MSO conditional comments and the document body and runs the MSO rules on them — no extra processor or config to wire up, and no processor conflict.

| Rule (mso/*) | Default (embedded/strict) | Description | | -------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------- | ----------------------------------------------------------- | | mso/valid-mso-condition | error | Validate the [if …] expression syntax of MSO comments | | mso/matching-mso-endif | error | Require every MSO opener to have a matching <![endif]> | | mso/matching-mso-endif-type | warn | Require the endif comment style to match its opener | | mso/no-unknown-mso-property | warn | Flag unknown mso-* CSS properties | | mso/vml-requires-namespace | warn | Require the v: VML namespace declaration when VML is used | | mso/no-unknown-vml-tag | warn | Flag unknown v:* VML tags | | mso/no-unknown-vml-attribute | warn | Flag unknown attributes on VML tags | | mso/table-presentation-role | warn | Require role="presentation" on layout tables |

Severities above are the same in embedded, strict, embedded-next, and strict-next (MSO markup is engine-agnostic — it behaves identically for Engagement and Next). For MSO rule details and options, see the eslint-plugin-mso-email docs.

Using eslint-plugin-unicorn with SFMC

eslint-plugin-unicorn is a high-quality, widely used plugin that we strongly recommend — but it is built for modern JavaScript, not SFMC's SSJS runtime. SFMC SSJS runs on a JINT-based ES3/ES5-era engine that lacks many built-ins (Array#includes, String#startsWith, Set, Map, Object.fromEntries, Math.trunc, spread ..., ES modules, async/await, …).

If you enable unicorn's recommended set on SSJS, about 46 of its 308 recommended rules would either autofix your code to a missing built-in (breaking it at runtime) or forbid a required SFMC workaround. eslint-plugin-sfmc offers an optional override config that turns off exactly those 46 rules for SSJS.

Important — this is optional and only needed if you use unicorn. eslint-plugin-sfmc does not depend on or load unicorn. The override configs are plain rules objects with no plugins key, so they only resolve when your own unicorn config (which registers the unicorn plugin) is loaded earlier in the flat-config array. Spread the sfmc override after it:

import sfmc from 'eslint-plugin-sfmc';
import eslintPluginUnicorn from 'eslint-plugin-unicorn';

export default [
  eslintPluginUnicorn.configs.recommended, // you opt in — registers the `unicorn` plugin
  ...sfmc.configs.recommended,
  ...sfmc.configs.embedded, // AMPscript + SSJS embedded in HTML (<script runat="server">)
  ...sfmc.configs['unicorn-ssjs'], // OPTIONAL: off the 46 SFMC-incompatible unicorn rules for SSJS
  ...sfmc.configs['unicorn-ssjs-embedded'], // OPTIONAL: same override for SSJS embedded in HTML (<script runat="server">)
];

| Config | Files | What it does | | --------------------------------------- | ---------------- | --------------------------------------------------------- | | sfmc.configs['unicorn-ssjs'] | **/*.ssjs | Turns off the 46 SFMC-incompatible unicorn rules for SSJS | | sfmc.configs['unicorn-ssjs-embedded'] | **/*.html/*.js | Same 46-rule override for SSJS embedded in HTML |

Only 46 of unicorn's 308 recommended rules are overridden — the other 262 stay active. If you don't use unicorn, omit these configs entirely. For the full rule-by-rule breakdown (with rationale and SFMC evidence links, pinned to unicorn v73.0.0), see docs/unicorn-compatibility.md.

Processors

| Processor | Purpose | | ---------------- | ----------------------------------------------------------------- | | sfmc/ampscript | Extract %%[ ]%%, %%= =%%, <script language="ampscript"> | | sfmc/ssjs | Extract <script runat="server"> (non-ampscript) | | sfmc/sfmc | Combined: extracts AMPscript, SSJS, Handlebars, and MSO from HTML |

License

MIT