# Create Transformations


This guide will help you add a new transformation in the [RudderStack dashboard](https://app.rudderstack.com/). It also contains the steps to capturing any event-related information in your transformation using the [`log`](#capture-event-information-with-logs) function.

{{<badge label="Node.js Version" message="18.x" color="7447fc" link="https://github.com/rudderlabs/rudder-transformer/blob/main/.nvmrc" >}} {{<badge label="Python Version" message="3.11" color="7447fc" >}}

## Required permissions

- [Admins]({{< ref "access-management/member-management.md#member-roles" >}}) have full access to create and manage transformations.
- [Members]({{< ref "access-management/member-management.md#member-roles" >}}) can have the following [permissions]({{< ref "access-management/policies-overview.md#resource-permissions" >}}) depending on their workspace policy:

| Resource | Permission | <div style="width:350px">Description</div> | 
| :----| :-----| :-----|
| Transformations | **Edit** |  Make changes to the configuration of transformations  | 
| Transformations | **Connect** | Connect a transformation to a destination | 
| Transformations | **Create & Delete** | Create or delete transformations | 

{{< warning >}}
To make a connection, that is, connect a transformation to a destination, the member must have both **Edit** and **Connect** permissions on both the resources.
{{< /warning >}}

{{< details "**Click here to see how these permissions appear in the workspace policy**." >}}
<br />

{{< figure src="images/access-management/transformations.webp" alt="Permissions to manage transformations in RudderStack dashboard" >}}

{{< /details >}}
<br />

#### Permissions for legacy RBAC system

In the [legacy Permissions Management (RBAC) system]({{< ref "archive/dashboard-guides/user-management.md" >}}):

- [Org Admins]({{< ref "archive/dashboard-guides/user-management.md#organization-roles" >}}) can create, edit, delete, and connect transformations to destinations
- Members must have the **Grant edit access** permission in **Transformations and Library** toggled on to create, edit, delete, and manage transformations
- Members with the **Connections Admin** or **Connections Editor** role in their workspace policy can only connect transformations to destinations

{{< image src="images/access-management/permissions/legacy/transformations.webp" alt="Transformations permissions in the legacy framework" >}}

## Add new transformation {#adding-a-transformation}

1. Log in to the [RudderStack dashboard](https://app.rudderstack.com/).
2. Go to **Collect** > **Transformations** and click **Create Transformation**.
3. Choose a [transformation template]({{< ref "transformations/templates.md" >}}) for implementing specific use cases on your event data. To create a transformation from scratch, click **Custom transformation**.

{{< image src="images/features/transformations/custom-transformation.webp" alt="Custom transformation option" >}}

4. Name your transformation. It must contain at least 2 characters.

{{< image src="images/features/transformations/name-transformation.webp" alt="Name your  transformation" >}}

5. In the **Transformation** window, select the language to write your transformation. RudderStack provides two options - **JavaScript** and **Python 3.11**.

{{< image src="images/features/transformations/transformation-language.webp" alt="Select transformation language" >}}

{{< info >}}
Note that:
- RudderStack uses [this Node.js version](https://github.com/rudderlabs/rudder-transformer/blob/main/.nvmrc) for JavaScript transformations and libraries.
- Python transformations are available only in the RudderStack [Growth](https://rudderstack.com/pricing/) and [Enterprise](https://www.rudderstack.com/enterprise-quote/) plans.
{{< /info >}}

{{< warning >}}
JavaScript transformations run in an isolated environment — no Node.js modules (like `fs`, `require`) or browser APIs (like `window`, `btoa`) are available. Only standard JavaScript features are supported.
{{< /warning >}}

5. Add your transformation function. You can also add other functions and call them from within the [`transformEvent`]({{< ref "transformations/usage.md#apply-transformation-on-single event" >}}) function.

{{< image src="images/features/transformations/add-transformation-function.webp" alt="Adding a Transformation" >}}

6. To test your transformation, [import a payload](#import-event-payload) using the **Import event** button. Then, click the **Run Test** button next to it.

{{< info >}}
If you don't import any event and click **Run Test** directly, RudderStack tests your transformation against a default `track` event payload.
{{< /info >}}

{{< image src="images/features/transformations/import-event-run-test.webp" alt="Import event and run test" >}}

{{< success >}}
You can also switch between the portrait and landscape views for better readability by clicking the button next to **Save Transformation**.

{{< figure src="images/features/transformations/switch-view.webp" alt="Switch between portrait and landscape views" >}}

{{< /success>}}

## Save transformation

To save the transformation, click the **Save Transformation** button at the bottom right. 

{{< image src="images/features/transformations/save-transformation.webp" alt="Save a transformation" >}}

Note that to save a transformation, it must run successfully with a test event. You will **not** be able to save a transformation in the following cases:

- Transformation code is invalid.
- Transformation gives an error upon running it with a test event, as shown:

{{< image src="images/features/transformations/save-transformation-error.webp" alt="Error while saving a transformation" >}}

## Test transformation

RudderStack lets you test your transformations to identify and prevent any transformation errors. With this feature, you can thoroughly test various scenarios and edge cases on your event payloads, and ensure effective event processing within RudderStack.

### Import event payload

To import a test payload, click the **Import Event** button.

{{< image src="images/features/transformations/import-event-run-test.webp" alt="Import event and run test" >}}

RudderStack gives you the following options to test your transformations:
- Use sample/placeholder event data within the **RudderStack Events** tab to test your transformations on default RudderStack event payloads. This is helpful when you don't have any live events in your workspace.
- Edit an event payload and save it as a new event. You can then use it to test your transformation.
- Use the **Live Events** feature to test your transformations on live events generated from your source.

{{< tabs tabTotal="2" >}}
{{% tab tabName="RudderStack Events" %}}
You can select any default RudderStack event to test your transformation. RudderStack provides four sample payloads (`identify`, `track`, `page`, and `screen`) that correspond to common RudderStack events.

{{< figure src="images/features/transformations/import-rudderstack-events.webp" alt="Default RudderStack events" >}}

{{% /tab %}}
{{% tab tabName="Live Events" %}}
From the dropdown, select the source. Then, send some events from this source - they will appear in this window automatically.

{{< figure src="images/features/transformations/import-live-events.webp" alt="Import live events">}}

Choose a live event and click **Import**. You can then test your transformation on this payload.

{{< warning >}}
Once you import a live event, all the live events shown in the window are lost. You need to send new events to import a live event again.
{{< /warning >}}
{{% /tab %}}
{{< /tabs >}}

### IP allowlisting

For testing transformations that [leverage external API calls]({{< ref "transformations/usage.md#make-external-api-requests" >}}), make sure that these API providers allowlist the following IPs depending on your RudderStack region:

{{< info >}}
Allowlisting these IPs is required when you want to make API calls to servers or services that control the IPs from which they accept API requests.
{{< /info >}}

<table>
      <tr>
        <th colspan="2"><center>Region</center></th>
      </tr>
      <tr>
        <td><b><center>US</center></b></td>
        <td><b><center>EU</center></b></td>  
      </tr>
      <tr>
          <td style="padding-left: 125px;"><ul><li>3.216.35.97</li><li>18.214.35.254</li><li>23.20.96.9</li><li>34.198.90.241</li><li>34.211.241.254</li><li>44.236.60.231</li><li>52.38.160.231</li><li>54.147.40.62</li><li>100.20.239.77</li></ul></td>
         <td style="padding-left: 125px;"><ul><li>3.64.201.167</li><li>3.66.99.198</li><li>3.123.104.182</li><li>3.125.132.33</li><li>18.196.167.201</li><li>18.198.90.215</li></ul></td>
      </tr>
</table>

{{< warning >}}
For production use cases, the IP addresses to allowlist while making external API calls depend on your [RudderStack plan](https://www.rudderstack.com/pricing) and region.

See the [IP allowlisting FAQ]({{< ref "transformations/faq.md#ip-allowlisting" >}}) for details.
{{< /warning >}}

### Limitations

- You cannot import multiple sample events to test your transformation.
- The live events contain payloads present at the source. They do not resemble the enriched events you see in the [Live Events]({{< ref "monitor/live-events.md#transformations-live-events" >}}) viewer in your transformation.

## Capture event information with logs

Once you [add a transformation](#adding-a-transformation), you can capture any event-related information in the form of logs while testing it. You can do this by including the [`log` function]({{< ref "transformations/runtime-functions.md#log" >}}) in your transformation code, as shown:

{{< tabs tabTotal="2" >}}
{{% tab tabName="JavaScript" %}}

```javascript
export function transformEvent(event, metadata) {
  const meta = metadata(event);
  event.sourceId = meta.sourceId;

  log("Event Name is", event.event, ";", "Message ID is", event.messageId);
  log("Source ID is", meta.sourceId);

  return event;
}
```

{{% /tab %}}
{{% tab tabName="Python" %}}

```python
def transformEvent(event, metadata):
    meta = metadata(event)
    event['sourceId'] = meta['sourceId']
    
    log("Event Name is", event['event'], ";", "Message ID is", event['messageId'])
    log("Source ID is", meta['sourceId'])
    
    return event
```

{{% /tab %}}
{{< /tabs >}}

On adding the above transformation and clicking **Run Test**, you can see the resulting log in the **Logs** section of the dashboard:

{{< image src="images/features/transformations/transformation-logs.webp" alt="Transformation log" >}}

<br />
