# Use Custom Buildpacks

The Salesforce Function build system uses [Cloud Native Buildpacks](https://buildpacks.io/) to transform your function code into a runnable image.

Buildpacks are composed of a set of executables that inspects your source code to detect the programming language, install dependencies, compile code and assets, and more.

Salesforce provides a set of official buildpacks to support Java, JavaScript, and TypeScript. With the custom buildpacks feature, Functions developers can change build behavior to suit their needs with third-party buildpacks or their own custom buildpack.

You can learn more about buildpacks [here](https://buildpacks.io/docs/concepts/components/buildpack/).

:::warning
Salesforce Support can't provide help with custom buildpacks you create or other third-party buildpacks.
:::

## Use Cases

Custom buildpacks allow you to use features that are otherwise not available by default. For example:

- A custom buildpack gives you the freedom to write a function in any language, beyond the officially supported ones.
- You can extend the build system with libraries or binaries that aren't included by default. For instance, a [custom buildpack](https://github.com/CSGAMERSServices/puppeteer-heroku-buildpack) can set up and install PDF authoring tools like [`puppeteer`](https://pptr.dev), which depend on Chromium executables.
- Change the command that's executed to launch your function. Learn more in the [Buildpacks' official docs](https://buildpacks.io/docs/buildpack-author-guide/create-buildpack/specify-multiple-process-types/).

## Supported Buildpack API Versions

Whether you're using a third-party buildpack or creating your own, Salesforce Functions only supports buildpacks with the following [Buildpack API spec](https://github.com/buildpacks/spec/blob/main/buildpack.md) range:

Buildpack API: 0.7 - 0.9

## Find a Third-Party Custom Buildpack

You can use custom buildpacks that follow the spec from [Cloud Native Buildpacks](https://buildpacks.io/). You can find existing third-party buildpacks in the [Cloud Native Buildpack registry](https://registry.buildpacks.io). Not every buildpack listed works with Functions. Test out the buildpack before adding it to production.

## Create a Custom Buildpack

Writing a custom buildpack from scratch is out of scope for this documentation. For a complete guide, see the [official Buildpack Author Guide](https://buildpacks.io/docs/buildpack-author-guide/) from the Cloud Native Buildpacks project.

The following example is from the [Heroku Procfile buildpack](https://github.com/heroku/procfile-cnb). This buildpack allows a developer to specify a custom process using the `Procfile`.

Salesforce Functions run on the most recently updated version of the [stack](https://devcenter.heroku.com/articles/stack). Buildpacks have a configuration file, [buildpack.toml](https://buildpacks.io/docs/buildpack-author-guide/create-buildpack/building-blocks-cnb/#buildpacktoml). As part of the configuration, buildpack authors list what stacks are compatible. You must include `heroku-22`, which is the current Salesforce Functions stack, or `*`, which is a wildcard for [any stack](https://github.com/buildpacks/rfcs/blob/main/text/0056-any-stack-buildpacks.md). With some sections cut for brevity, the Procfile buildpack has a `buildpack.toml` that looks like:

```toml
api = "0.8"

[buildpack]
id = "heroku/procfile"
version = "2.0.0"
name = "Procfile"

[[stacks]]
id = "*"
```

## Add Buildpacks to Your Function

Add the buildpack by including a [`[[io.buildpacks.group]]`](https://github.com/buildpacks/spec/blob/main/extensions/project-descriptor.md#iobuildpacksgroup-optional) in your [`project.toml`](/docs/platform/functions/guide/toml.md) file. For example, to use the Procfile buildpack in a JavaScript function:

```toml
[_]
schema-version = "0.2"

[com.salesforce]
schema-version = "0.1"
id = "jsfn"
description = "My Function"
type = "function"
salesforce-api-version = "57.0"

[[io.buildpacks.group]]
id = "heroku/nodejs-function"

[[io.buildpacks.group]]
uri = "https://github.com/heroku/procfile-cnb/releases/download/v2.0.0/heroku_procfile_2.0.0.cnb"
```

Buildpack groupings are executed sequentially. `heroku/nodejs-function` is the official buildpack that provides JavaScript support for Functions. In the example, that buildpack is listed first in the buildpack groupings so that it runs before the Procfile buildpack.

:::callout
You must set the `uri` field for custom buildpacks.
:::

### Pre and Post Buildpack Groups

You can also insert buildpacks at the beginning or end of the buildpack group using [`[[io.buildpacks.pre.group]]`](https://github.com/buildpacks/spec/blob/main/extensions/project-descriptor.md#iobuildpackspregroup-optional) and [`[[io.buildpacks.post.group]]`](https://github.com/buildpacks/spec/blob/main/extensions/project-descriptor.md#iobuildpackspostgroup-optional) respectively. With this feature, you decide if the custom buildpack runs before or after the normal buildpack grouping.

For example, to run the Procfile buildpack after the normal buildpack grouping in a JavaScript function:

```toml
[_]
schema-version = "0.2"

[com.salesforce]
schema-version = "0.1"
id = "jsfn"
description = "My Function"
type = "function"
salesforce-api-version = "57.0"

[[io.buildpacks.post.group]]
uri = "https://github.com/heroku/procfile-cnb/releases/download/v2.0.0/heroku_procfile_2.0.0.cnb"
```

If you don't specify `[[io.buildpacks.group]]` in your file, the default buildpack group is used. So in this Javscript function example, `heroku/nodejs-function` runs as part of the default buildpack group, followed by the Procfile buildpack specified in `[[io.buildpacks.post.group]]`.

## Remove Buildpacks From Your Function

There's no way to remove a particular buildpack from the default buildpack group, but specifying `[[io.buildpacks.group]]` replaces the entire group. This change takes effect on your next function [deploy](/docs/platform/functions/guide/deploy.md).

## Buildpack Errors

You can check for buildpack-related errors in the build output when [deploying your function](/docs/platform/functions/guide/deploy.md) with `sf deploy functions`.
