# JavaScript transformations Use JavaScript transformations when you need custom logic that goes beyond what [Visual Mapping](https://www.krenalis.com/docs/transformations/visual-mapping.md) can express. They let you write a transform function with full control over conditions, data manipulation, and complex mappings. Click **Edit full mode** to open the transformation editor in full mode, where you can write and test the JavaScript transformation:
[Example of JavaScript](/docs/transformations/images/example\-javascript\.png)!
  1. Schema/Sample: Switch between the source schema and sample input to test the transformation.
  2. Source properties: Properties from the source schema that, when selected, are included in the object passed to the transformation function.
  3. Select source property: Selects the properties actually used in the transform function. Krenalis reads and passes to the function only the properties you select. If any of them later changes in the source schema — for example, if its data type changes — Krenalis stops running the transformation until you review and update the function.
  4. Settings: Opens the settings menu for the transformation. Here you can change how JSON values are passed to and returned from the function during execution.
  5. Editor: The editor used to write the transformation function. The function must be named transform and receives an object containing the user data, or event data for event transformations. The input object includes only the properties you selected from the list on the left, and the output object only the properties you selected from the list on the right.
  6. Schema/Result: Switches between the destination schema and the test output.
  7. Destination properties: Properties from the destination schema that the function returns as the result of the transformation. The function must return only the properties you select, and no others.
  8. Select destination property: Selects the properties actually returned by the transform function. If any of these properties ever changes in the destination schema — for example, if its data type changes — Krenalis stops running the transformation until you review and update the function.
  9. Expand: Expands object-type properties so you can view their nested properties.
  10. Close: Closes full mode when you're done writing and testing the transformation, and returns you to the main view where you can save your changes.
## Transformation examples To transform either user data or events, Krenalis calls the JavaScript function `transform`. The function receives a single argument: * an **event** object for event transformations * a **user** object for user transformations Below are example transformations illustrating how user and event data can be reshaped in JavaScript. ### Collecting a user ```js const transform = (user) => { return { email: user.email, first_name: user.firstName, last_name: user.lastName, full_name: `${user.firstName} ${user.lastName}`, is_adult: user.age >= 18, signup_year: new Date(user.createdAt).getFullYear(), phone_number: user.phone?.replace(/\D/g, ''), } } ``` ### Collecting a user via event ```js const transform = (event) => { return { customer_id: event.userId, email: event.properties.email, first_name: event.properties.firstName, last_name: event.properties.lastName, full_name: `${event.properties.firstName} ${event.properties.lastName}`, is_adult: event.properties.age >= 18, signup_year: new Date(event.properties.createdAt).getFullYear(), phone_number: event.properties.phone?.replace(/\D/g, '') ?? null, } } ``` ### Activating an event ```js const transform = (event) => { // Adapt the "products" field into the "items" structure required by Google Analytics. const items = (event.properties.products || []).map((p) => ({ item_id: p.id, item_name: p.name, price: p.unitPrice, quantity: p.qty, })) return { currency: event.properties.currency, value: items.reduce((sum, item) => sum + item.price * item.quantity, 0), items: items, } } ``` ## Configure the JavaScript execution engine Krenalis supports two JavaScript transformers: * **AWS Lambda** — runs JavaScript transformations using your AWS Lambda environment. * **Local** — runs JavaScript transformations on the same machine as Krenalis, for development and testing. Start Krenalis with one of the following configurations. ### AWS Lambda To use JavaScript transformations via AWS Lambda, in addition to configuring your environment for AWS access, provide these configuration values in the environment variables below when starting Krenalis: | Variable | Description | |---------------------------------------------------|-----------------------------------------------------------------| | `KRENALIS_TRANSFORMERS_AWS_LAMBDA_ROLE` | ARN of the IAM Role assumed to execute Lambda functions. | | `KRENALIS_TRANSFORMERS_AWS_LAMBDA_NODEJS_RUNTIME` | Node.js runtime version for Lambda (for example: `nodejs22.x`). | | `KRENALIS_TRANSFORMERS_AWS_LAMBDA_NODEJS_LAYER` | (Optional) ARN of a Node.js Lambda Layer. | ### Local In local mode, Krenalis uses the Node.js installation available on the machine running Krenalis. Set the following environment variables at startup: | Variable | Description | |-------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | `KRENALIS_TRANSFORMERS_LOCAL_NODEJS_EXECUTABLE` | Path to the Node.js executable. Example: `/usr/bin/node`. | | `KRENALIS_TRANSFORMERS_LOCAL_FUNCTIONS_DIR` | Directory where local transformation functions are stored. A subdirectory named `krenalis-functions` will be created inside it. Must be writable by the user running Krenalis. | | `KRENALIS_TRANSFORMERS_LOCAL_SUDO_USER` | System user under which transformation functions should run. If left empty, Krenalis keeps the current user and does not invoke `sudo`. | | `KRENALIS_TRANSFORMERS_LOCAL_DOAS_USER` | System user under which to run local transformation function processes. Switching to this user is done in Krenalis via `doas`. If left blank, the current user is retained and `doas` is not invoked. | If you change the directory after creating pipelines with transformation functions, you must copy the existing `krenalis-functions` directory to the new location and update the corresponding environment variable. ### Local using Docker Compose When running Krenalis [using Docker Compose](https://www.krenalis.com/docs/installation/using-docker-compose.md), JavaScript transformations are executed inside the container. The container includes the Node.js runtime as part of the Krenalis Docker image, and transformations run under a dedicated system user configured within the container. This mode is intended solely for local development and testing and works immediately without any additional setup. If you prefer to run Krenalis with Docker Compose while delegating JavaScript transformations to **AWS Lambda**, update your `compose.yaml` file. Comment out the `KRENALIS_TRANSFORMERS_LOCAL_*` variables and add the environment variables required to enable AWS Lambda. > **Note:** Switching between local mode and Lambda mode is only possible if no JavaScript or Python transformation functions currently exist in your Krenalis instance. ## Types reference The table below outlines the Krenalis data types and their corresponding JavaScript representations. | Krenalis type | JavaScript type | JavaScript example | |---------------------------|------------------|-----------------------------------------------| | string | String | `'123 Main Street'` | | boolean | Boolean | `true` | | int(n) n≤32 | Number | `-2586` | | int(64) | BigInt [^1] | `72750672843726543n` | | unsigned int(n) n≤32 | Number | `4063` | | unsigned int(64) | BigInt [^1] | `160386761048264895n` | | float(n) | Number [^2] | `37.81` | | decimal(p,s) | String | `"5930174.18"` | | datetime | String [^3] [^4] | `"2025-12-18T12:53:44.822508315Z"` | | date | String | `"2025-12-18"` | | time | String | `"12:53:44.822508315"` | | year | Number | `2024` | | uuid | String | `'f956622d-c421-4eca-8d20-efef87f9749c'` | | json | _any type_ [^5] | `{ "score": 10 }` | | ip | String | `'172.16.254.1'` | | array | Array | `[472,182,604]` | | object | Object | `{ firstName: 'Emily', lastName: 'Johnson' }` | | map | Object | `{ a: 8073, c: 206 }` | [^1]: A `String` is also accepted as a return value (e.g. `"72750672843726543"`). [^2]: `"NaN"`, `"Infinity"`, and `"-Infinity"` strings are also accepted as a return value. [^3]: Return values may use any timezone; Krenalis converts them to UTC. [^4]: A `Date` is also accepted as a return value (e.g. `new Date("2025-12-18T12:53:44.822Z")`). [^5]: Serialized JSON values are deserialized into JavaScript values. When returning a value, Krenalis serializes it to JSON. If **Preserve JSON** is selected for the transformation, JSON values are passed and received as strings in their original format, without being decoded or encoded.