mrkeyoor.com_
Sat 08 Aug 21:56 UTC
npmUtilsupdated 08 Aug 2026

string-template

string-template is a dependency-free CommonJS formatter that replaces ASCII named or numeric placeholders such as {name} and {0}. Values can come from one object or array, or from positional function arguments; missing, null, and undefined values become empty strings, and doubled braces preserve a literal placeholder. A separate compile subpath can pre-parse frequently reused templates, with an optional new Function mode. It is interpolation only, not a full template language.

Verdict

Do not add it to new modern code for ordinary interpolation; a template literal or a maintained formatter is easier to type and audit. It remains acceptable as a frozen legacy formatter when you know its flat-key, missing-value, object-shape, and escaping behavior exactly.

API stability4/5The direct function, compile subpath, placeholder grammar, empty-on-missing rule, positional conventions, and doubled-brace escaping have remained unchanged since 1.0.0. There are no dependencies that can alter runtime behavior. That predictability deserves credit for legacy users, but the package's own README labels stability as unstable, compile and direct parsing disagree on underscore keys, and the absence of releases means long-standing edge cases are frozen rather than deliberately guaranteed.
Docs3/5The README demonstrates named objects, indexed arrays, variadic arguments, doubled-brace escaping, both compile modes, installation, and the fact that inline compilation uses new Function. It does not document the accepted key grammar precisely, silent missing-value behavior, zero and false handling, direct-versus-compiled underscore mismatch, hasOwnProperty assumptions, null-prototype objects, raw unescaped output, CommonJS packaging, Content Security Policy consequences, or TypeScript absence. Several status badges and links are from retired services.
Maintenance1/5npm 1.0.0 was published in January 2016, GitHub reports the last repository push in March 2017, and the repository has 10 issues and pull requests combined with no later release. It is not archived or npm-deprecated, and a tiny dependency-free formatter may need little routine work, but there has been no published response to modern ESM, TypeScript, Content Security Policy, prototype-safe property checks, stale CI, or the parser mismatch between direct and compiled templates.
Ecosystem2/5The package recorded 3,682,989 downloads in the measured week and has 279 GitHub stars, largely reflecting its long residence in transitive dependency trees and usefulness before template literals were universal. It has no dependencies and works in old browsers. There is no surrounding plugin, loader, type, internationalization, framework, or escaping ecosystem, while native syntax and maintained packages such as Mustache, Handlebars, sprintf-js, and message-format tools cover new projects more deliberately.

Use it if

  • You maintain code that already uses its {name} or {0} syntax and depends on missing values becoming empty strings
  • You need an ES5-era formatter that runs in very old browsers and has no runtime dependencies
  • Your templates are trusted, tiny, context-neutral messages with flat ASCII keys and no conditionals or nesting
  • You reuse a hot template enough to benefit from the default pre-parsed compile function without enabling generated code
Skip it if

Setup reality

npm install string-template adds a CommonJS package with no dependencies, peers, native build, credentials, config, engines constraint, ESM export map, or TypeScript declarations. require('string-template') gives the direct formatter. require('string-template/compile') reaches an undeclared subpath because the old package has no exports restrictions. The argument convention has a subtle branch: exactly one value argument is treated as a lookup object only when typeof is object; otherwise all remaining arguments become numeric positions. Arrays work as the object form. Missing own properties and null or undefined values silently become empty strings, which is convenient for display but can hide misspelled keys and produce dangerous partial commands or queries. Zero and false are preserved. Keys are not property paths and must be ASCII alphanumerics; the direct formatter also accepts underscore, but compile's regular expression does not, so {first_name} works directly and remains literal in compiled templates. Both implementations call the object's own hasOwnProperty method rather than Object.prototype.hasOwnProperty.call. Object.create(null) data therefore produces blanks, while an own non-function hasOwnProperty property crashes. Escaping only means doubled braces such as {{0}} becoming literal {0}; it does not sanitize substituted values. The normal compiler pre-tokenizes without code generation and is the safer choice. Passing true as compile's second argument constructs a function with new Function, which violates strict Content Security Policy without unsafe-eval and can be blocked in locked-down runtimes. The README calls the package unstable, and its badges and browser matrix describe an obsolete CI era rather than current runtime testing.

Patterns

Replace named placeholdersformat-named-values

const format = require('string-template');

const message = format('Hello {name}, you have {count} messages', {
  name: 'Robert',
  count: 12,
});

Only own properties are substituted. Values are coerced to strings without escaping, so keep this to context-neutral text or escape values first.

Replace numeric placeholders from an arrayformat-indexed-array

const message = format(
  'Hello {0}, you have {1} messages',
  ['Robert', 12]
);

An array works because exactly one object-typed argument is used as the lookup table. Numeric placeholders are property names such as 0 and 1.

Pass positional values as separate argumentsformat-positional-arguments

const message = format(
  'Hello {0}, you have {1} messages',
  'Robert',
  12
);

With more than one value argument, the function builds an internal array and resolves {0}, {1}, and later positions from it.

Keep a placeholder literalescape-placeholder-braces

const example = format('Write {{name}} or {{0}} in the config');
console.log(example);
// Write {name} or {0} in the config

Double braces escape only recognized placeholder-shaped text. This is syntax escaping, not HTML, shell, SQL, or URL escaping.

Observe empty output for absent valueshandle-missing-values

const result = format('{first} {middle} {last}', {
  first: 'Ada',
  last: 'Lovelace',
});
console.log(result); // Ada  Lovelace

Missing, null, and undefined values all become empty strings without an error. Validate required data before formatting when omissions matter.

Keep valid falsy valuespreserve-zero-and-false

const result = format('count={count}, enabled={enabled}', {
  count: 0,
  enabled: false,
});
console.log(result); // count=0, enabled=false

Only null and undefined disappear. Zero, false, NaN, objects, and arrays are passed through JavaScript string coercion.

Use underscore keys only with the direct formatteruse-underscore-key

const result = format('Hello {first_name}', {
  first_name: 'Ada',
});
console.log(result); // Hello Ada

The direct regex accepts underscores, but string-template/compile accepts only letters and digits. Compiling this exact template leaves {first_name} unchanged.

Pre-parse a frequently reused templatecompile-reused-template

const compile = require('string-template/compile');
const greet = compile('Hello {0}, you have {1} messages');

console.log(greet('Ada', 3));
console.log(greet(['Grace', 7]));

The default compile mode pre-tokenizes and does not use generated code. It accepts one object or array, or separate positional arguments.

Opt into generated-code compilationcompile-inline-function

const compile = require('string-template/compile');
const greet = compile('Hello {0}', true);
console.log(greet('Ada'));

The true flag uses new Function. It can violate Content Security Policy and locked-down runtime rules; benchmark before accepting that deployment and audit cost.

Convert a null-prototype map before formattingnormalize-null-prototype-data

const raw = Object.assign(Object.create(null), { name: 'Ada' });
const values = Object.fromEntries(
  Object.entries(raw).filter(([key]) => key !== 'hasOwnProperty')
);

console.log(format('Hello {name}', values));

A null-prototype object is treated as empty, and an own hasOwnProperty value shadows the method the formatter calls. Normalize and reject that reserved key.

Escape values before inserting into HTMLescape-html-values

function escapeHtml(value) {
  return String(value)
    .replaceAll('&', '&')
    .replaceAll('<', '&lt;')
    .replaceAll('>', '&gt;')
    .replaceAll('"', '&quot;')
    .replaceAll("'", '&#39;');
}

const html = format('<p>Hello {name}</p>', {
  name: escapeHtml(userName),
});

string-template never escapes output. This helper is only for HTML text and quoted attributes; other contexts need their own encoder, and DOM APIs are preferable when available.

Fail before silent placeholders disappearassert-template-keys

function strictFormat(template, values) {
  const keys = [...template.matchAll(/\{([0-9A-Za-z_]+)\}/g)]
    .map((match) => match[1]);
  for (const key of keys) {
    if (!Object.prototype.hasOwnProperty.call(values, key)) {
      throw new Error(`Missing template value: ${key}`);
    }
  }
  return format(template, values);
}

The package intentionally turns absent keys into empty strings. A strict wrapper is useful for configuration, notifications, and any message where silent truncation is a bug.

Alternatives

PackageRegistryPick it when
sprintf-jsnpmUse familiar positional or named format specifiers when widths, precision, numeric bases, and explicit formatting matter
mustachenpmUse escaped HTML interpolation, sections, inverted sections, and nested lookup with a logic-less template format
handlebarsnpmUse helpers, partials, conditions, loops, and HTML escaping for larger presentation templates
lodashnpmUse its template function only in an existing Lodash codebase that already accepts code-generation and escaping configuration