---
source_url: https://www.pubnub.com/docs/serverless/functions/run
title: Functions Development Guidelines
updated_at: 2026-05-19T12:14:17.904Z
---

> Documentation Index
> For a curated overview of PubNub documentation, see: https://www.pubnub.com/docs/llms.txt
> For the full list of all documentation pages, see: https://www.pubnub.com/docs/llms-full.txt


# Functions Development Guidelines

:::note Functions modules and API
For more information about Functions modules or the public REST API (for Functions v2), see the [Functions Modules](https://www.pubnub.com/docs/serverless/functions/functions-apis/xhr-module) and [REST API](https://www.pubnub.com/docs/serverless/functions/functions-rest-api/functions-api) docs.
:::

## Introduction

This page shows how to run Functions after you create and configure them. For an overview, see [Functions Basics](https://www.pubnub.com/docs/serverless/functions/overview).

* PubNub provides integrations through the [Integration Catalog](https://www.pubnub.com/integrations/).
* Functions are JavaScript modules with a default export Function. See [guidelines](#code-structure) for each event type.
* PubNub provides [modules](#modules) to help you develop Functions.
* Asynchronous operations use Promises. See [Promises](#promises).
* You can chain up to 3 Functions to run in sequence. See [Chaining Functions](#chaining).

## Development guidelines

### Code structure

For all event types except On Request, use this structure:

```javascript
export default (request) => {
    // Your business logic here
    return request.ok();
    // request.abort(); to fail execution
};
```

For all [event types](https://www.pubnub.com/docs/serverless/functions/overview#event-types) except On Request and On Interval, the `request` object has two methods: `ok()` and `abort()`. The `response` object isn’t available. For details, see [On Request](#on-request) and [On Interval](#on-interval).

#### On Request

Use this structure:

```javascript
export default (request, response) => {
    // Your code here
    return response.send();
};
```

For On Request, the `request` object has `json()`, and the `response` object has `send()`. For details, see [On Request](#on-request-inputsoutputs).

#### On Interval

Use this structure:

```javascript
export default (event) => {
    // Your code here
    return event.ok();
};
```

For On Interval, the `event` object has `ok()`. For details, see [On Interval Inputs/Outputs](#on-interval-inputsoutputs).

### Promises

Asynchronous operations use Promises (ES6). `promise` is implicitly available for every Function.

```javascript
const Promise = require('promise'); // No need to add this line
```

:::tip Learn more
See [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) and [Promise.all()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all).
:::

#### Promise.all()

You can use `Promise.all()` to run multiple async calls in parallel.

Example: fetch a username from KV Store and an IP address from a web service. When both resolve, update the request.

```javascript
export default (request) => {
    const store = require('kvstore');
    const xhr = require("xhr");

    const fullName = store.get('fullName');
    const ipAddress = xhr.fetch("https://httpbin.org/ip");

    return Promise.all([fullName, ipAddress])
        .then((values) => {

            request.message.fullNameResult = values[0];
            request.message.ip = JSON.parse(values[1].body).origin;

            return request.ok();
        })
        .catch((err) => {
            console.log(err);
            return request.abort(err);
        });
};
```

## Modules

Use modules to optimize performance and add specialized functionality. This keeps each Function focused on its event.

For the full list, see [Functions modules](https://www.pubnub.com/docs/serverless/functions/functions-apis/functions-libraries).

## Webhooks on request

You can use an On Request event type to create webhooks.

Example: check whether a username exists. Assume `username` is passed as a query parameter.

1. Extract the username and check the KV store. Create the user if missing. 1export default (request, response) => {2 3 const db = require('kvstore');4 const username = request.params.username;5 6 return db.get(username).then((dataFromDb) => {7 if (!dataFromDb) {8 console.log('The username does not exist.');9 db.set(username, {});10 response.status = 200;11 return response.send('Username is available');12 } else {13 console.log('The username already exists.');14 response.status = 409;15 return response.send('Username already exists');16 }17 });18};
2. Save changes and, depending on your Functions version (v1 or v2), either restart the module or create a new Package Revision and deploy it.

Now test the Function.

## Chaining

Functions can run in sequence or based on a condition. Use `pubnub.publish()`, `pubnub.signal()`, or `pubnub.triggerRequestFunction()`.

:::tip Modules/Packages for chained Functions
Place Functions you plan to chain in the same Module/Package. It’s easier to start/stop them.
:::

### Chain Functions

Example: capture messages on `hello-world` and send them to the `hello-logger` Function.

1. Create an On Before Publish or Fire hello-logger Function: 1export default (request) => {2 console.log(request) // show what we have inside3 return request.ok() // done4};
2. Create an On Before Publish or Fire hello-world Function: 1export default (request) => {2 const pubnub = require('pubnub');3 4 pubnub.publish({5 "channel": "hello-logger",6 "message":request.message7 }).then((publishResponse) => {8 console.log(`Publish Status: ${publishResponse[0]}:${publishResponse[1]} with TT ${publishResponse[2]}`);9 }).catch((err) => {10 console.error(err);11 });12 13 return request.ok(); // Return a promise when you're done14};
3. Save the changes and, depending on your Functions version (v1 or v2), either restart the Module or create a new Package Revision and deploy it.
4. Open PubNub Debug Console.
5. Enter hello_world, hello-logger for the channel and click Subscribe.
6. Back on the Functions screen, publish the test payload.

#### Fork Functions

Example: capture messages on `hello-world`, add `"Hello": "World"`, and publish to `hello-universe` as well as `hello-world`.

1. Create a new Before Publish or Fire Function: 1export default (request) => {2 const db = require('kvstore');3 const pubnub = require('pubnub');4 5 console.log('The message ', request.message, ' was published on ', request.channels[0], ' via ', request.meta.clientip);6 7 request.message.hello = 'world!'; // augment hello = world8 9 // To fork return pubnub.publish and include request.ok in the .then()10 return pubnub.publish({11 "channel": "hello_universe",12 "message": request.message13 }).then((publishResponse) => {14 console.log(`Publish Status: ${publishResponse[0]}:${publishResponse[1]} with TT ${publishResponse[2]}`);15 return request.ok();16 }).catch((err) => {17 console.error(err);18 });19 20 // To chain functions make pubnub.publish a synchronous operation. Meaning dont return the pubnub.publish, let pubnub publish21 // the message and then only `return` request.ok().22 // pubnub.publish({23 // "channel": "hello-logger",24 // "message":request.message25 // }).then((publishResponse) => {26 // console.log(`Publish Status: ${publishResponse[0]}:${publishResponse[1]} with TT ${publishResponse[2]}`);27 // }).catch((err) => {28 // console.error(err);29 // });30 // return request.ok();31};
2. Save the changes and, depending on your Functions version (v1 or v2), either restart the Module or create a new Package Revision and deploy it.
3. Open PubNub Debug Console.
4. Enter hello-world, hello-universe for the channel and click Subscribe.
5. Back on the Functions screen, publish the test payload.

:::warning Avoid infinite loops
You can chain or fork publishes across many channels. Avoid scenarios that can loop (for example, A -> B -> A). The system detects and blocks infinite loops, but ensure your logic doesn’t rely on this.
:::

:::note Recursion limit
The maximum recursion limit is 3 hops from one Function to another. Using `publish` or `fire`, you can execute at most three Functions.
Within a single Function execution, the combined maximum number of `KV store` operations, `XHRs`, `publish`, and `fire` is 3.
:::

## Request/Response objects

### All event types except On Request

#### request methods

| Method | Arguments | Description |
| --- | --- | --- |
| `ok` | message:String (Optional) | Returns a promise that resolves to the value of the request object. |
| `abort` | message:String (Optional) | Returns a promise that resolves to the value of the request object, with an error code. |

#### request attributes

| Attribute | Type | Definition |
| --- | --- | --- |
| `message` | Object | The actual user message sent to the channel. |
| `verb` | String | Method used by the publishing client when sending the message to PubNub. |
| `pubkey` | String | The Publish Key used when sending the message. |
| `subkey` | String | The Subscribe Key to retrieve the message. |
| `channels` | `Array<String>` | The list of channels on which the message was sent. |
| `version` | String | API Version. |
| `meta.clientip` | String | IP of the publishing client. |
| `meta.origin` | String | Origin defined on the publishing client. |
| `meta.useragent` | String | The publishing client's user agent string. |
| `params` | Object | URL parameters on the request. |
| `uri` | String | The request URI. |

### On Request Inputs/Outputs

#### request attributes

| Attribute | Type | Definition |
| --- | --- | --- |
| `verb` | String | Method used by the publishing client when sending the message to PubNub. Always set to `rest`. |
| `pubkey` | String | The Publish Key used when sending the message. |
| `subkey` | String | The Subscribe Key to retrieve the message. |
| `version` | String | API Version. |
| `meta.clientip` | String | IP of the publishing client. |
| `meta.origin` | String | Origin defined on the publishing client. |
| `meta.useragent` | String | The publishing client's user agent string. |
| `params` | Object | URL parameters on the request. |
| `uri` | String | The full path of the URI minus PubNub hostname information. |
| `path` | String | The path minus PubNub and key information. This is the path you configured for the Function. |
| `method` | String | HTTP method such as GET, PUT, POST, DELETE. |
| `body` | Object | The body content if passed in the request. |
| `headers` | Object | Header information passed in the request. |

#### response methods

| Method | Arguments | Description |
| --- | --- | --- |
| `send` | `body:String` (Optional) | Returns a promise that resolves to the value of the response object. |

##### response attributes

| Attribute | Type | Definition |
| --- | --- | --- |
| `status` | Object | HTTP status code returned to the caller. |
| `body` | Object | Response body returned to the caller. |
| `headers` | Object | Response headers returned to the caller. |

### On Interval Inputs/Outputs

#### event methods

| Method | Arguments | Description |
| --- | --- | --- |
| `ok` | N/A | Returns a promise that resolves to the value of the response object. |

#### event attributes

| Attribute | Type | Definition |
| --- | --- | --- |
| `verb` | String | Method used by the publishing client when sending the message to PubNub. Always set to `interval`. |
| `pubkey` | String | The Publish Key used when sending the message. |
| `subkey` | String | The Subscribe Key to retrieve the message. |
| `execInterval` | Number | Duration of the interval in milliseconds. |
| `lastTimestamp` | Number | Timestamp of last Function execution. |
| `timestamp` | Number | Timestamp of current Function execution. |

### Subscribe on Interval Inputs/Outputs

#### event methods

| Method | Arguments | Description |
| --- | --- | --- |
| `ok` | N/A | Returns a promise that resolves to the value of the response object. |

#### event attributes

| Attribute | Type | Definition |
| --- | --- | --- |
| `verb` | String | Method used by the publishing client when sending the message to PubNub. Always set to `interval`. |
| `pubkey` | String | The Publish Key used when sending the message. |
| `subkey` | String | The Subscribe Key to retrieve the message. |
| `execInterval` | Number | Duration of the interval in milliseconds. |
| `lastTimestamp` | Number | Timestamp of last Function execution. |
| `timestamp` | Number | Timestamp of current Function execution. |

## Create a Function

This short instruction shows how to create a simple Function in the Admin Portal. The Function changes the message before publishing it on the specified channel.

:::tip Admin Portal UI
This section shows how to use the Admin Portal to create PubNub Functions. To learn the Functions UI, see [Functions v2](https://www.pubnub.com/docs/serverless/functions/functions-in-admin-portal).
:::

### Set up configuration

You need a Package before you create a Function.

1. Log in to the Admin Portal and go to Functions v2.
2. Create a Package. Click Create package. Choose Configure your own. Enter a Package name and description. Click Next.
3. Create a Function. Enter a name and select the Before Publish or Fire event type. Set the trigger channel to hello-world. Click Create package.
4. Open the new Package to see the initial Revision. To edit code, click Edit code or Edit Latest on the Package Revision list.
5. The editor includes a sample Function. Replace the code to add simple logging and test. 1export default (request) => {2 3 console.log('request', request);4 request.message.hello = 'world!'; // augment hello = world5 console.log('The message: ', request.message, ' was published on ', request.channels[0], ' via', request.meta.clientip);6 7 return request.ok(); // Return a promise when you're done8}
6. Click Save. Changing the Function code creates a new Revision. Enter a Revision name and description and save.
7. To deploy the Package Revision with the Function, click Deploy.
8. Select Add keyset to choose the keysets to run the Function on. Click Create.
9. If you don’t assign secrets for this example, click Deploy again to create the deployment.

:::tip Maximum number of deployments
The number of deployments equals the number of keysets you selected. A Package Revision can run on up to 50 keysets.
:::

### Run and test

To test the Function:

1. Open the Function editor by clicking **Edit code** or **Edit Latest** on the Package Revision list.
2. Switch to the **Debug** tab.
3. Click **Publish** in the **Test payload** section.

### Trigger Functions

A Function triggers on one or more channels (including wildcards), except for On Request, which triggers by HTTP request.

Clients publishing and subscribing on a channel operate independently of Functions. When a parent Package Revision is running, configured Functions process messages seamlessly.

#### Start a Module/Package

Start a Package Revision by clicking the start button next to a Revision on the list.

When the Package Revision starts, each Function runs across all PubNub data centers for global availability. All Functions run hot (don't go into resource-saving mode) for low latency.

#### Stop a Module/Package

Stop a Package Revision by clicking the stop button next to a Revision on the list.

When stopped, messages continue to flow through the PubNub Network, and Web API calls to On Request Functions return `404 Not Found` until you start the Package Revision again.

## Terms in this document

* **Module** - A Functions v1 container that groups related functions for configuration and deployment on an app’s keysets.
* **Package** - A Functions v2 container that groups Functions, tracks Revisions, and is deployed to keysets.
