# json-placeholder-replacer

> Javascript/Typescript library/cli to replace placeholders in an javascript object

Latest version **2.1.2** (published 2025-06-16) · MIT license · 0 weekly downloads

## Install

```sh
npm install json-placeholder-replacer
pnpm add json-placeholder-replacer
yarn add json-placeholder-replacer
bun add json-placeholder-replacer
```

Provides the commands `jpr`, `json-placeholder-replacer`.

## Health

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

Positive: has types; no vulnerabilities; high maintenance score; high quality score.

Warnings: low downloads; no esm support.

Negative: stale.

## Facts

| | |
|---|---|
| Version | 2.1.2 |
| Published | 2025-06-16 |
| First published | 2018-04-18 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 37 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 10 |
| Author | Virgs |
| Maintainers | virgs |
| Keywords | json, replacer, substitution, placeholder, cli, library, typescript, javascript, javascript-library |

## Links

- npm: https://www.npmjs.com/package/json-placeholder-replacer
- Repository: https://github.com/virgs/jsonPlaceholderReplacer
- Homepage: https://github.com/virgs/jsonPlaceholderReplacer#readme
- Issues: https://github.com/virgs/jsonPlaceholderReplacer/issues
- npm.io page: https://npm.io/package/json-placeholder-replacer

## Alternatives

- [@mapbox/jsonlint-lines-primitives](https://npm.io/package/@mapbox/jsonlint-lines-primitives.md) — 5.3M weekly downloads
- [reftools](https://npm.io/package/reftools.md) — 3.5M weekly downloads
- [@hey-api/openapi-ts](https://npm.io/package/@hey-api/openapi-ts.md) — 3.5M weekly downloads
- [@mapbox/geojson-rewind](https://npm.io/package/@mapbox/geojson-rewind.md) — 2.4M weekly downloads
- [turbo-stream](https://npm.io/package/turbo-stream.md) — 1.7M weekly downloads

## Recent versions

- 2.1.2 (latest) — 2025-06-16
- 2.1.1 — 2025-06-12
- 2.1.0 — 2024-09-24
- 2.0.5 — 2024-06-27
- 2.0.4 — 2023-09-04
- 2.0.3 — 2023-08-31
- 2.0.1 — 2023-08-30
- 2.0.0 — 2023-08-29
- 1.0.37 — 2023-08-29
- 1.0.35 — 2020-02-10
- 1.0.34 — 2019-06-24
- 1.0.33 — 2019-06-17
- 1.0.32 — 2019-04-02
- 1.0.31 — 2019-03-30
- 1.0.30 — 2019-03-11
- … 30 more at https://npm.io/package/json-placeholder-replacer/versions

## README

# jsonPlaceholderReplacer

[![npm version](https://badge.fury.io/js/json-placeholder-replacer.svg)](https://badge.fury.io/js/json-placeholder-replacer)
[![build status](https://circleci.com/gh/virgs/jsonPlaceholderReplacer.svg?style=shield)](https://app.circleci.com/pipelines/github/virgs/jsonPlaceholderReplacer)
[![Maintainability](https://api.codeclimate.com/v1/badges/6e586ff6eb12a67da08e/maintainability)](https://codeclimate.com/github/lopidio/jsonPlaceholderReplacer/maintainability)
[![Test Coverage](https://api.codeclimate.com/v1/badges/6e586ff6eb12a67da08e/test_coverage)](https://codeclimate.com/github/lopidio/jsonPlaceholderReplacer/test_coverage)
[![Known Vulnerabilities](https://snyk.io/test/github/virgs/jsonPlaceholderReplacer/badge.svg)](https://app.snyk.io/)

Lightweight yet really powerful typescript library/cli to replace placeholders in an javascript object/JSON.
By default, all you have to do is to use double curly brackets **{{**placeholderKey**}}** or angle brackets **<<**placeholderKey**>>**, interchangeably, to identify the placeholder.
Don't worry, if you don't like these default placeholders you can create your own.

## CLI usage

```shell
json-placeholder-replacer annotetad-json.json [...variableMaps]
```

### Example

$ json-placeholder-replacer [annotated.json](/annotated.json) [variable_map.json](/variable_map.json)
$ jpr [variable_map.json](/variable_map.json) < [annotated.json](/annotated.json)
$ cat [annotated.json](/annotated.json) | jpr [variable_map.json](/variable_map.json)
$ echo '{"curly": "{{key}}", "angle": "<<key>>"}' | jpr variable_maps

### Would result

```shell
cat replaceable.json
        # {
        #  "curly": "{{key}}",
        #  "angle": "<<key>>"
        # }
cat variable.map:
        # {
        #         "key": 10,
        #         "not-mapped": 20
        # }
json-placeholder-replacer replaceable.json variable.map
        # {
        #         "curly": 10,
        #         "angle": 10,
        #         "not-mapped": 20
        # }
```

## Library usage

```typescript
import { JsonPlaceholderReplacer } from "json-placeholder-replacer";
const placeHolderReplacer = new JsonPlaceholderReplacer();

placeHolderReplacer.addVariableMap({
  key: 100,
  otherKey: 200,
});
const afterReplace = placeHolderReplacer.replace({
  replaceable: "{{key}}",
  otherReplaceableWithSameKey: "<<key>>",
  otherReplaceable: "{{otherKey}}",
});

// afterReplace = {
//    replaceable: 100,
//    otherReplaceableWithSameKey: 100,
//    otherReplaceable: 200
// }
```

> [!NOTE]
> An object passed to `.replace()` is mutated in-place:
>
> ```ts
> const beforeReplace = { some: "{{placeholder}}" };
> const afterReplace = placeHolderReplacer.replace(beforeReplace);
> // beforeReplace === afterReplace
> ```

### You can replace the default placeholders with some as cool as you want

```typescript
const placeHolderReplacer = new JsonPlaceholderReplacer({
  delimiterTags: [{ begin: "@{{-", end: "-}}@" }],
});
placeHolderReplacer.addVariableMap({
  key: "nice",
});
const afterReplace = placeHolderReplacer.replace({
  replaceable: "@{{-key-}}@",
});

// afterReplace = {
//    replaceable: "nice",
// }
```

### It's also possible to add more than one variables map

```typescript
placeHolderReplacer.addVariableMap({
  firstMapKey: "1",
});
placeHolderReplacer.addVariableMap({
  secondMapKey: 2,
});
const afterReplace = placeHolderReplacer.replace({
  replaceable: "{{firstMapKey}}",
  otherReplaceable: "<<secondMapKey>>",
});

// afterReplace = {
//    replaceable: "1",
//    otherReplaceable: 2
// }
```

### And the last added maps have higher priority (but non-nullish values will be preserved from previous map)

```typescript
placeHolderReplacer.addVariableMap({
  id: "lowerPriority",
  name: "Name",
});
placeHolderReplacer.addVariableMap({
  id: "higherPriority",
  name: undefined,
});
const afterReplace = placeHolderReplacer.replace({
  id: "{{id}}",
  name: "{{name}}",
});

// afterReplace = {
//    id: "higherPriority"
//    name: "Name"
// }
```

### It's possible to override global values map with `.setVariableMap()`

```typescript
placeHolderReplacer.addVariableMap({
  id: "Id",
  name: "Name",
});
placeHolderReplacer.setVariableMap({
  // <- note setVariableMap() here
  id: "New Id",
  name: undefined,
});
const afterReplace = placeHolderReplacer.replace({
  id: "{{id}}",
  name: "{{name}}",
});

// afterReplace = {
//    id: "New Id"
//    name: "{{name}}"
// }
```

### It's possible to override global maps with local by `.replaceWith()`

```typescript
placeHolderReplacer.addVariableMap({
  id: "Id",
  name: "Name",
});
const afterReplace = placeHolderReplacer.replaceWith(
  {
    id: "{{id}}",
    name: "{{name}}",
  },
  { name: "New Name" },
);

// afterReplace = {
//    id: "{{id}}"
//    name: "New Name"
// }
```

### It keeps original variable types

If a variable in the map is boolean/string/number/object, it remains as boolean/string/number/object when it's replaced

```typescript
placeHolderReplacer.addVariableMap({
  booleanKey: true,
  stringKey: "string",
  numberKey: 10,
  objectKey: {
    inner: "inner",
  },
});
const afterReplace = placeHolderReplacer.replace({
  booleanReplaceable: "{{booleanKey}}",
  stringReplaceable: "{{stringKey}}",
  numberReplaceable: "{{numberKey}}",
  objectReplaceable: "{{objectKey}}",
});

// afterReplace = {
//    booleanReplaceable: true,
//    stringReplaceable: "string",
//    numberReplaceable: 10,
//    objectReplaceable: {
//      inner: "inner"
//    }
// }
```

### Just to make it clearer, it does not replace the placeholder Key

```typescript
placeHolderReplacer.addVariableMap({
  key: "someValue",
});
const afterReplace = placeHolderReplacer.replace({
  "{{key}}": "value",
});
// afterReplace = {
//    "{{key}}": "value"
// }
```

### And, of course, it handles array substitution as well

```typescript
placeHolderReplacer.addVariableMap({
  key: 987,
  objectReplaceable: {
    inner: "inner",
  },
});
const afterReplace = placeHolderReplacer.replace({
  array: ["string", "{{objectReplaceable}}", "{{key}}"],
});

// afterReplace = {
//    array: ["string", { inner: "inner" }, 987]
// }
```

### Want to get nested elements? Go for it

```typescript
placeHolderReplacer.addVariableMap({
  key: {
    nested: "value",
  },
});
const afterReplace: any = placeHolderReplacer.replace({
  replaceable: "<<key.nested>>",
});

// afterReplace = {
//    replaceable: "value"
// }
```

### This feature allows you to have default values in case you don't have them mapped

```typescript
placeHolderReplacer.addVariableMap({
  key: "value",
});
const afterReplace: any = placeHolderReplacer.replace({
  replaceable: "<<not-found-key:default-value>>",
});

// afterReplace = {
//    replaceable: "default-value"
// }
```

### Of course, you can also change what is the default value separator (defaults to ':')

```typescript
const placeHolderReplacer = new JsonPlaceholderReplacer({
  defaultValueSeparator: ":=:",
});

placeHolderReplacer.addVariableMap({
  key: "value",
});
const afterReplace: any = placeHolderReplacer.replace({
  replaceable: "<<not-found-key:=:default-value>>", // Note the ':=:'
});

// afterReplace = {
//    replaceable: "default-value"
// }
```

### Lastly, cyclic objects are also accepted

```typescript
const placeHolderReplacer = new JsonPlaceholderReplacer();

const cyclicObject: any = {
  key: "{{key1}}",
  deep: {
    nested: "{{key2}}",
  },
};
cyclicObject.deep.circular = cyclicObject;
placeHolderReplacer.addVariableMap({ key1: "value1", key2: "value2" });

const afterReplace: any = placeHolderReplacer.replace(cyclicObject);

// afterReplace = {
//    key: "value1",
//    deep: {
//      nested: "value2",
//      circular: {
//        key: "value1",
//        deep: {
//          nested: "value2",
//          circular: [CYCLE...]
//        }
//      }
//    }
// }
```

---
_Source: https://npm.io/package/json-placeholder-replacer · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
