# Functions

Functions are designed to process data in Jitsu before it is sent to the [destination](/docs/core-concepts/#destinations). These functions, written in JavaScript, provide various data handling options:

- [Filter](#filter) - Exclude data that fails to meet your specified criteria.
- [Transform](#transform) - Modify data to fit the schema of your destination.
- [Enrich](#enrich) - Add extra information to the event.

In addition, Functions are supported by a runtime environment that includes several built-in services:

- [Persistent Storage](/docs/functions/runtime#persistent-storage) - Maintain data between different function calls.
- [Logging](/docs/functions/runtime#logging) - Log messages and access them later in [Live Events](/docs/features/live-events).
- [Fetch API](/docs/functions/runtime#fetch-api) - Perform HTTP requests to third-party services.
- [Warehouse API](/docs/functions/runtime#warehouse-api) - Query your data warehouses.

## Quick intro

```typescript
export default async function transform(event, context) {
   //  
}
```

 * `event` is a first arguments of a function. It contains an event object that is being processed
 * `ctx` is a second argument, the function context. I contain various services that can be used in the function
   * `ctx.log` - [logging service](/docs/functions/runtime#logging)
   * `ctx.store` - [persistent storage](/docs/functions/runtime#persistent-storage)
   * `ctx.fetch` - [a standard fetch API](/docs/functions/runtime#fetch-api) to make HTTP requests
   * `ctx.getWarehouse` - [warehouse API](/docs/functions/runtime#warehouse-api) to query your data warehouses
   * `ctx.geo` - geo information about the event based on IP
   * `ctx.ua` - parsed user agent
   * `ctx.headers` - incoming HTTP headers if event came through HTTP API
   * `ctx.destination` - destination object
   * `ctx.source` - where event came from. Includes `id` — source id, `type` — ingest type (`browser` or `s2s`)
 * The full specification of ctx object can be found in [`functions.d.ts`](https://github.com/jitsucom/jitsu/blob/newjitsu/types/protocols/functions.d.ts)

:::tip

See a full spec of what you can use functions on [Functions Runtime Page](/docs/functions/runtime)

:::

Here's a simple example that enriches event with geo information, and parsed user agent.


```javascript
export default async function transform(event, context) {
  if (!event.properties) {
    //initialize event properties object, just to be safe
    event.properties = {}  
  }
  //copy geo and parsed user agent to event properties
  event.properties.geo = context.geo
  event.properties.ua = context.ua
  //always return a modified event
  return event;
}
```

Function return value controls what happens with event after function execution:

 * If function returns nothing, the original event  will be used.
 * If function returns an object, it will be used as a new event.
 * If function returns magic string `"drop"`, event will be ignored and won't be sent to the destination.

See a full spec of [what function can return](/docs/functions/advanced#return-types).

## Debugging

Jitsu comes with a functions debugger/editor that allows to run function on a sample data

<Screenshot src="/docs/screenshots/functions.png" />

## Function examples

See a few examples of how to use functions to filter, transform, and enrich data.

### Filter

```javascript
export default async function transform(event, { log, props, store }) {
  //drop events coming from integration tests
  if (event.userId === "integration-tests") {
    return "drop";
  }
}
```

:::info
To ignore event, return magic string `"drop"` from the function. If function returns an object, it will be used as a new event.
cIf function returns nothing, the original event (or it's modified copy) will be used.
:::


### Transform

```javascript
export default async function transform(event, { log, props, store }) {
  //normalize event type
  if (event.type === "page_view" || event.type === "pageview" || event.type === "pageView") {
    event.type = "page";
  }
  return event;
}
```

### Change destination table

To change destination table for specific event, you need to add a special property named `JITSU_TABLE_NAME` to the resulting events with a new table name.

```javascript
export default async function transform(event, { log, props, store }) {
    //change table name to "new_table"
    event.JITSU_TABLE_NAME = "new_table";
    return event;
}
```

### Enrich

GeoIP enrichment example:

```javascript
// Enriches event with Geo IP using https://ip-api.com/ service
// For non-commercial use only
export default async function(event, { log, fetch }) {
    try {
        const url = `https://ip-api.com/json/${event.context.ip}`
        const result = await fetch(url)
        if (result.ok) {
            let json;
            json = await result.json();
            if (json.status === "success") {
                // remove status fields
                delete json.query
                delete json.status
                // add geo information to context
                event.context.geo = json
                return event
            } else {
                log.error(`GeoIP status: ${json.status}: ${json.message}`)
            }
        } else {
            log.error(`Failed to fetch GeoIP data ${url}: ${result.status} ${result.statusText}`)
        }
    } catch (e) {
      log.error(`Failed to fetch response from ${url}: ${e?.message}`);
    }
}
```

## Functions Runtime


:::tip

See a full spec of what you can use functions on [Functions Runtime Page](/docs/functions/runtime)

:::