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

n8n-nodes-jsonata-mapper

v1.3.10

Published

An n8n community node for JSON-to-JSON mapping, JSONata transformations, JSON Schema validation, and AI-assisted mapping generation.

Downloads

635

Readme

n8n-nodes-jsonata-mapper

A community node for n8n that maps, transforms, and validates JSON documents using JSONata expressions and JSON Schema.

This node is designed for integration workflows where data from one JSON structure needs to be transformed into another structure in a controlled, repeatable, and testable way.

Features

  • Map source JSON fields to target JSON paths
  • Use JSONata expressions for flexible transformations
  • Support nested target paths using dot notation
  • Convert, clean, and reshape JSON data
  • Validate source JSON using JSON Schema
  • Validate mapped output using target JSON Schema
  • Support default values for missing fields
  • Support required field checks
  • Optional preset transforms
  • Optional JavaScript field transforms for trusted self-hosted environments
  • AI-assisted mapping generation using generic LLM providers
  • Debug output for troubleshooting mappings

Supported LLM Providers

The AI mapping feature supports multiple LLM providers:

  • OpenAI-compatible Chat Completions APIs
  • OpenRouter
  • Anthropic Claude Messages API
  • Google Gemini Generate Content API
  • Ollama local models
  • Custom HTTP JSON endpoints

The AI feature can generate JSONata mapping configurations from source JSON, target JSON, and optional JSON Schemas.

Installation

Install this package from n8n Community Nodes:

n8n-nodes-jsonata-mapper

In n8n:

Settings → Community Nodes → Install

Enter:

n8n-nodes-jsonata-mapper

Node Name

After installation, search for:

JSONata Mapper

Basic Usage

Create a workflow like this:

Manual Trigger
   ↓
JSONata Mapper

Select:

Operation: Apply Mapping
Source Document Mode: Paste Source JSON Document

Example source JSON:

{
  "customer": {
    "firstName": "John",
    "lastName": "Smith",
    "email": " [email protected] "
  },
  "order": {
    "total": "245.5"
  }
}

Example mapping config:

{
  "version": "1.1",
  "engine": "jsonata",
  "mappings": [
    {
      "target": "person.givenName",
      "expression": "customer.firstName",
      "required": true
    },
    {
      "target": "person.familyName",
      "expression": "customer.lastName",
      "required": true
    },
    {
      "target": "contact.email",
      "expression": "$lowercase($trim(customer.email))",
      "required": true
    },
    {
      "target": "purchase.amount",
      "expression": "$number(order.total)",
      "required": false
    }
  ]
}

Output:

{
  "person": {
    "givenName": "John",
    "familyName": "Smith"
  },
  "contact": {
    "email": "[email protected]"
  },
  "purchase": {
    "amount": 245.5
  }
}

Mapping Config Format

{
  "version": "1.1",
  "engine": "jsonata",
  "mappings": [
    {
      "id": "map_001",
      "sourceLabel": "Customer First Name",
      "target": "person.givenName",
      "expression": "customer.firstName",
      "required": true,
      "defaultValue": "Unknown"
    }
  ]
}

Mapping Fields

| Field | Required | Description | |---|---:|---| | target | Yes | Target JSON path using dot notation | | expression | Yes | JSONata expression evaluated against source JSON | | required | No | Fails execution if the expression returns empty | | defaultValue | No | Value used when expression returns empty | | transform | No | Optional preset or JavaScript transform applied after JSONata | | sourceLabel | No | Human-readable source field label | | confidence | No | Useful for AI-generated mappings | | reason | No | Explanation for AI-generated mappings |

JSONata Examples

Direct field mapping

{
  "target": "person.givenName",
  "expression": "customer.firstName"
}

Trim and lowercase email

{
  "target": "contact.email",
  "expression": "$lowercase($trim(customer.email))"
}

Convert string to number

{
  "target": "purchase.amount",
  "expression": "$number(order.total)"
}

Array projection

{
  "target": "items",
  "expression": "order.lines.{\"sku\": sku, \"quantity\": qty, \"lineAmount\": $number(price) * $number(qty)}"
}

Preset Transforms

Preset transforms can be used after the JSONata expression is evaluated.

{
  "target": "contact.email",
  "expression": "customer.email",
  "transform": {
    "type": "preset",
    "name": "lowercaseTrim"
  }
}

Supported preset transforms:

lowercaseTrim
uppercaseTrim
trim
toNumber
toString
toBoolean

JavaScript Field Transforms

JavaScript field transforms are an optional advanced feature. For most mappings, use JSONata or preset transforms first.

A JavaScript transform runs after the JSONata expression has produced a value.

The execution order is:

Source JSON
  ↓
JSONata expression
  ↓
Default value check
  ↓
Required field check
  ↓
Optional preset or JavaScript transform
  ↓
Write to target path

When to use JavaScript transforms

Use JavaScript transforms only when JSONata or preset transforms are not enough, for example:

  • Complex business calculations
  • Special date formatting
  • Conditional formatting rules
  • Custom lookup logic
  • Data cleanup that is easier to express in JavaScript

How it works

A JavaScript transform receives two variables:

| Variable | Meaning | |---|---| | value | The value returned by the JSONata expression | | source | The full source JSON document |

The code must return the final value.

Example:

{
  "target": "purchase.amountWithTax",
  "expression": "order.total",
  "transform": {
    "type": "javascript",
    "code": "return Number(value) * 1.1;"
  }
}

If the source JSON is:

{
  "order": {
    "total": "245.5"
  }
}

The output is:

{
  "purchase": {
    "amountWithTax": 270.05
  }
}

Using full source JSON inside JavaScript

{
  "target": "customer.displayName",
  "expression": "customer.firstName",
  "transform": {
    "type": "javascript",
    "code": "return value + ' ' + source.customer.lastName;"
  }
}

JavaScript transforms are disabled by default

To use JavaScript transforms, enable this node option:

Enable JavaScript Field Transforms

If this option is off and a mapping contains "type": "javascript", the node will fail with an error. This is intentional.

Security note

JavaScript transforms execute user-provided JavaScript. Keep them disabled unless you are running in a trusted self-hosted environment and you trust the mapping configuration.

Safer alternatives are:

  • JSONata expressions
  • Preset transforms
  • Separate n8n Code node with controlled code

JSON Schema Validation

You can validate the source JSON, mapped output, or both.

When Use Source JSON Schema or Use Target JSON Schema is enabled, the node now checks that the corresponding schema is actually provided and meaningful. Empty schemas such as {} or non-restrictive object schemas such as { "type": "object", "properties": {} } are rejected with a clear error.

This prevents a common mistake where schema validation appears to be enabled, but the schema does not actually validate anything.

A meaningful schema should include validation rules such as:

  • non-empty properties
  • non-empty required
  • additionalProperties: false
  • enum or const
  • oneOf, anyOf, or allOf
  • type-specific rules such as format, pattern, minLength, minimum, or maximum

Source JSON Schema Example

{
  "type": "object",
  "required": ["customer", "order"],
  "properties": {
    "customer": {
      "type": "object",
      "required": ["firstName", "lastName", "email"],
      "properties": {
        "firstName": { "type": "string" },
        "lastName": { "type": "string" },
        "email": { "type": "string", "format": "email" }
      }
    },
    "order": {
      "type": "object",
      "required": ["total"],
      "properties": {
        "total": { "type": "string" }
      }
    }
  }
}

Enable:

Use Source JSON Schema: true
Validate Source With Schema: true

Target JSON Schema Example

{
  "type": "object",
  "required": ["person", "contact", "purchase"],
  "properties": {
    "person": {
      "type": "object",
      "required": ["givenName", "familyName"],
      "properties": {
        "givenName": { "type": "string" },
        "familyName": { "type": "string" }
      }
    },
    "contact": {
      "type": "object",
      "required": ["email"],
      "properties": {
        "email": {
          "type": "string",
          "format": "email"
        }
      }
    },
    "purchase": {
      "type": "object",
      "required": ["amount"],
      "properties": {
        "amount": { "type": "number" }
      }
    }
  }
}

Enable:

Use Target JSON Schema: true
Validate Output With Target Schema: true

AI-Assisted Mapping

The node can generate mapping suggestions using an LLM.

Select:

Operation: Generate AI Mapping

Provide:

  • Source JSON document
  • Target sample JSON
  • Optional source JSON Schema
  • Optional target JSON Schema
  • LLM provider credentials

The AI returns a mapping config that can be reviewed and used with the Apply Mapping operation.

LLM Provider Examples

OpenAI-compatible

Provider: OpenAI-Compatible Chat Completions
Base URL: https://api.openai.com/v1
Model: gpt-4.1-mini

OpenRouter

Provider: OpenAI-Compatible Chat Completions
Base URL: https://openrouter.ai/api/v1
Model: openai/gpt-4o-mini

Anthropic Claude

Provider: Anthropic Claude Messages API
Base URL: https://api.anthropic.com/v1
Model: claude-3-5-sonnet-latest

Google Gemini

Provider: Google Gemini Generate Content API
Base URL: https://generativelanguage.googleapis.com/v1beta
Model: gemini-1.5-flash

Ollama

Provider: Ollama Local Chat API
Base URL: http://host.docker.internal:11434
Model: llama3.1

When using Docker, host.docker.internal is usually required to reach Ollama running on the host machine.

Gemini Direct API Notes

For Google Gemini direct API, use:

LLM Provider: Google Gemini Generate Content API
Base URL: https://generativelanguage.googleapis.com/v1beta
Model: gemini-2.5-flash

Do not put /models/...:generateContent in the Base URL. The node builds that endpoint automatically. If you paste a full Gemini endpoint or models/<model> into the model field, the node normalizes it before calling Gemini.

Recommended Gemini models for new projects include gemini-2.5-flash and gemini-2.5-flash-lite. Older 1.5 model aliases may return 404 depending on API access and lifecycle.

Operations

| Operation | Description | |---|---| | Apply Mapping | Applies the JSONata mapping and returns transformed JSON | | Validate Mapping | Validates mapping config, JSONata expressions, schemas, and optionally output | | Generate AI Mapping | Calls a configured LLM provider to generate mappings | | Generate AI Prompt Only | Returns the prompt without calling an LLM |

Debugging

Turn on:

Return Debug Info

This returns:

{
  "mapped": {},
  "debug": [],
  "sourceJsonUsedByMapper": {}
}

Use this to troubleshoot:

  • Which expression ran
  • What value was produced
  • Whether a transform was applied
  • Which source JSON was used

Turn it off for clean production output.

Current External Libraries

This package uses current stable library versions in package.json:

| Library | Purpose | |---|---| | jsonata | JSON expression and transformation engine | | ajv | JSON Schema validation | | ajv-formats | Email, date, URI and other JSON Schema format validation | | Built-in path helpers | Reading source paths and writing nested target paths without deprecated lodash helpers |

The package currently targets JSONata 2.x and Ajv 8.x.

Local Development

Install dependencies:

npm install

Build:

npm run build

Run tests:

npm run test:all

Release

This package includes an n8n-style release script.

Before release, build and test locally:

npm install
npm run test:all

Log in to npm:

npm login
npm whoami

Run the release command:

npm run release

The release script uses n8n-node release. For a direct npm publish flow, you can also run:

npm publish

Package author is set to @vvrr174.

Testing

The package includes tests for:

  • Direct nested mappings
  • JSONata functions
  • Default values
  • Required fields
  • Preset transforms
  • JavaScript transform enable/disable behavior
  • Array projections
  • Bracket path array targets
  • Invalid config handling
  • Invalid JSONata expressions
  • Source JSON Schema validation
  • Target JSON Schema validation
  • Empty/non-restrictive schema toggle rejection
  • Invalid schema definition rejection
  • Email format validation
  • AI mapping prompt generation
  • Package metadata validation

Run:

npm run test:all

Docker Testing With n8n

Create a temporary n8n container:

docker run -d \
  --name n8n-test \
  -p 5680:5678 \
  -v n8n_test_data:/home/node/.n8n \
  n8nio/n8n:latest

Copy the package into the container:

docker cp ./n8n-nodes-jsonata-mapper n8n-test:/home/node/.n8n/nodes/n8n-nodes-jsonata-mapper

Install inside the container:

docker exec -it n8n-test sh
cd /home/node/.n8n/nodes
npm install ./n8n-nodes-jsonata-mapper
exit

Restart:

docker restart n8n-test

Open:

http://localhost:5680

Search for:

JSONata Mapper

Security Notes

JavaScript transforms execute user-provided JavaScript. Keep them disabled unless you are running in a trusted self-hosted environment.

For most mappings, JSONata expressions and preset transforms are safer and should be preferred.

License

MIT

npm Build and Release Notes

This package can be built and published with standard npm commands.

npm install
npm run build
npm run test:all
npm pack --dry-run
npm publish

The release script uses npm directly:

npm run release

This package does not require @n8n/node-cli for normal npm publishing.

Troubleshooting

Error: Bad escaped character in JSON

If n8n shows this error while installing or loading the community node:

Error loading package "n8n-nodes-jsonata-mapper":
Bad escaped character in JSON at position 11 (line 2 column 10)

This usually means one JSON parameter default in the published node package is being parsed by n8n and contains bad escaping.

This package avoids that issue by generating all JSON parameter defaults using JSON.stringify(...) constants instead of manually escaped JSON strings.

The package also includes a test to validate all node JSON defaults before publishing:

pnpm run test:json-defaults

Before publishing, run:

pnpm run test:all
npm pack --dry-run

Gemini returns 404 during AI mapping

Use these settings for the direct Gemini API:

LLM Provider: Google Gemini Generate Content API
Base URL: https://generativelanguage.googleapis.com/v1beta
AI Model: gemini-2.5-flash

Do not include /models/... in the Base URL. The node builds the full Gemini endpoint internally.

Dependency Notes

This package does not use lodash.get or lodash.set. Nested source path reading and target path writing are handled by small internal helper functions, avoiding deprecated lodash helper packages.

Compatibility

This package is intended for self-hosted n8n community-node installations.

It uses external runtime dependencies:

  • jsonata
  • ajv
  • ajv-formats

Because of these dependencies, it is not currently n8n Cloud verified. Self-hosted n8n installations can install and use the package normally.