# @pfeiferio/string-interpolate

> Lightweight string interpolation with named placeholders and filter pipelines

Latest version **1.0.0** (published 2026-01-25) · MIT license · 0 weekly downloads

## Install

```sh
npm install @pfeiferio/string-interpolate
pnpm add @pfeiferio/string-interpolate
yarn add @pfeiferio/string-interpolate
bun add @pfeiferio/string-interpolate
```

## Health

**Score 60/100 (C)** — status: stable.

Positive: has types; esm support; no vulnerabilities; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 1.0.0 |
| Published | 2026-01-25 |
| First published | 2026-01-25 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Node | >=18.0.0 |
| Dependencies | 0 |
| Unpacked size | 46.1 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 0 |
| Author | Pascal Pfeifer |
| Maintainers | something_with_code |
| Keywords | string, interpolation, template, filters, parser, dot-notation, placeholders, lightweight, no-dependencies |

## Links

- npm: https://www.npmjs.com/package/@pfeiferio/string-interpolate
- Repository: https://github.com/pfeiferio/string-interpolate
- Homepage: https://github.com/pfeiferio/string-interpolate#readme
- Issues: https://github.com/pfeiferio/string-interpolate/issues
- npm.io page: https://npm.io/package/@pfeiferio/string-interpolate

## Alternatives

- [babylon](https://npm.io/package/babylon.md) — 5.1M weekly downloads
- [csscolorparser](https://npm.io/package/csscolorparser.md) — 3.7M weekly downloads
- [expr-eval-fork](https://npm.io/package/expr-eval-fork.md) — 1.5M weekly downloads
- [@leeoniya/ufuzzy](https://npm.io/package/@leeoniya/ufuzzy.md) — 247.7K weekly downloads
- [xml-parser](https://npm.io/package/xml-parser.md) — 78.4K weekly downloads

## Recent versions

- 1.0.0 (latest) — 2026-01-25

## README

# `@pfeiferio/string-interpolate`

Lightweight string interpolation with named placeholders and filter pipelines.

* ✅ No dependencies
* ✅ No template engine
* ✅ No expressions, no loops
* ✅ Built-in and custom filters
* ✅ Safe, test-driven parser

---

## Installation

```bash
npm install @pfeiferio/string-interpolate
```

---

## Basic Usage

```js
import { interpolate } from '@pfeiferio/string-interpolate'

interpolate(
  'Hello {{ user.name }}',
  { user: { name: 'Pascal' } }
)
// → "Hello Pascal"
```

---

## Nested Placeholders (Dot Notation)

```js
interpolate(
  'ID: {{ order.customer.id }}',
  {
    order: {
      customer: { id: 42 }
    }
  }
)
// → "ID: 42"
```

---

## Selective Removal of Missing Placeholders

By default, unresolved placeholders are kept when `keep=true`.

With the `remove` option, you can **explicitly remove selected placeholders** when their value is missing, while keeping all others unchanged.

```js
interpolate(
  'Hello {{ user.name }} {{ user.email }}',
  {
    user: { name: 'Pascal' }
  },
  {
    keep: true,
    remove: ['user.email']
  }
)
// → "Hello Pascal "
```

### Behavior

* `remove` entries act as prefix paths
* All placeholders **under the given path**are removed if their value is `undefined`
* Existing values are **never removed**
* `remove` overrides `keep` for the specified paths

```js
interpolate(
  'Hello {{ user.email }}',
  {},
  {
    keep: true,
    remove: ['user.email']
  }
)
// → "Hello "
```

Partial matches **do** apply:

```js
interpolate(
  'Hello {{ user.email }}',
  {},
  {
    keep: true,
    remove: ['user']
  }
)
// → "Hello "
```

### Options Reference

```ts
interpolate(
  template: string,
  replacements: Record<string, unknown>,
  options?: {
    keep?: boolean
    remove?: string[]
    customFilters?: Record<string, FilterFunction>
  }
): string
```

---

## Filters

Filters are applied using a pipe syntax.

```js
interpolate(
  '{{ name | uppercase }}',
  { name: 'pascal' }
)
// → "PASCAL"
```

Multiple filters are applied left to right:

```js
interpolate(
  '{{ name | uppercase | truncate length=3 }}',
  { name: 'pascal' }
)
// → "PAS..."
```

---

## Filter Arguments

Filters receive **named arguments** using `key=value` syntax.

```js
interpolate(
  '{{ text | truncate length=4 ending="..." }}',
  { text: 'abcdef' }
)
// → "abcd..."
```

### Argument Rules

* Arguments are key-value based
* Values may be:

    * numbers (`length=10`)
    * booleans (`pretty=true`)
    * strings (`suffix=!!!`)
    * quoted strings with spaces (`ending="..."`)
* No escaping inside quoted strings
* Whitespace is used as argument separator

---

### Filter Composition
> Interpolation is single-pass.
> If a placeholder resolves to another placeholder expression, filters are not executed immediately.
> Instead, they are appended to the resulting placeholder expression.

---

## Built-in Filters

| Filter       | Description                     |
| ------------ | ------------------------------- |
| `uppercase`  | Convert string to upper case    |
| `lowercase`  | Convert string to lower case    |
| `capitalize` | Capitalize first character      |
| `append`     | Append a suffix                 |
| `concat`     | Concatenate text                |
| `replace`    | Replace all occurrences         |
| `ltrim`      | Trim characters from start      |
| `rtrim`      | Trim characters from end        |
| `trim`       | Trim characters from both sides |
| `truncate`   | Shorten string                  |
| `default`    | Fallback for `undefined`        |
| `padStart`   | Left-pad string                 |
| `padEnd`     | Right-pad string                |
| `json`       | JSON stringify                  |

Example:

```js
interpolate(
  '{{ value | replace search=" " replace="_" }}',
  { value: 'hello world' }
)
// → "hello_world"
```

---

## Custom Filters

You can provide custom filters via the options object.

```js
interpolate(
  '{{ name | reverse }}',
  { name: 'abc' },
  {
    customFilters: {
      reverse: (value) =>
        typeof value === 'string'
          ? value.split('').reverse().join('')
          : value
    }
  }
)
// → "cba"
```

Custom filters override built-in filters with the same name.

---

## Function Values

If a replacement value is a function, it will be executed:

```js
interpolate(
  'Now: {{ now }}',
  {
    now: () => new Date().toISOString()
  }
)
```

---

## API

### `interpolate(template, replacements, options?)`

```ts
interpolate(
  template: string,
  replacements: Record<string, unknown>,
  options?: {
    keep?: boolean,
    customFilters?: Record<string, FilterFunction>
  }
): string
```

---

## Design Goals

* Explicit syntax
* Predictable behavior
* No hidden magic
* Easy to extend
* Safe defaults

This package is **not** intended to be a full template engine.

---

## License

MIT

---

---
_Source: https://npm.io/package/@pfeiferio/string-interpolate · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
