Skip to main content
Glama
functions.md7.45 kB
--- title: TypeScript functions description: Learn how to create and use EAS Build functions in your custom build configurations. --- EAS Build functions are a great way to extend the functionality of custom builds. You can use them to create reusable steps, and to write your logic in JavaScript, TypeScript, or Bash (more information in [`command` in the config schema](./schema.md#functionsfunction_namecommand)). This guide provides a walkthrough of creating a function in TypeScript. ## Initialize an EAS Build function module The easiest way to create an EAS Build function is to use the `create-eas-build-function` CLI tool. By running the following command from the same directory as your **eas.json** file, you can create a new custom TypeScript function: This creates a new module called `myFunction` in the **.eas/build** directory. The module will contain a pre-generated module configuration and the **src** directory with the **index.ts** file containing the default TypeScript function template. ```ts .eas/build/myFunction/src/index.ts // This file was autogenerated by `create-eas-build-function` command. // Go to README.md to learn more about how to write your own custom build functions. // interface FunctionInputs { // // specify the type of the inputs value and whether they are required here // // example: name: BuildStepInput<BuildStepInputValueTypeName.STRING, true>; // } // interface FunctionOutputs { // // specify the function outputs and whether they are required here // // example: name: BuildStepOutput<true>; // } async function myFunction( ctx: BuildStepContext // { // inputs, // outputs, // env, // }: { // inputs: FunctionInputs; // outputs: FunctionOutputs; // env: BuildStepEnv; // } ): Promise<void> { ctx.logger.info('Hello from my TypeScript function!'); } ``` ## Compile the function Functions must be compiled to a single JavaScript file that can be run without installing any dependencies. The default `build` script for generated functions uses [ncc](https://github.com/vercel/ncc) to compile your function into a single file with all its dependencies. If you don't have the `ncc` installed globally on your machine, run `npm install -g @vercel/ncc` to install it. Next, run the build script in the **.eas/build/myFunction** directory: This command triggers the `build` script placed in the **package.json** file of your custom function module. ```json package.json { ... "scripts": { ... "build": "ncc build ./src/index.ts -o build/ --minify --no-cache --no-source-map-register" /* @end */ ... }, ... } ``` The `build` script generates **build/index.js**. This file must be uploaded to EAS Build as a part of your project archive, so that the builder can run your function. Ensure that the file is not excluded by a **.gitignore** file or **.easignore** file. ## Expose the function to the custom build config > **Note**: The following example assumes that you have already set up a custom build workflow and configured it in your **eas.json**. If not, see [Get started with custom builds](/custom-builds/get-started/#create-a-workflow) before proceeding. Let's assume that you have a **config.yml** file in the **.eas/build** directory. It contains the following content: ```yaml .eas/build/config.yml build: name: My example config steps: - eas/checkout - eas/install_node_modules - run: name: Finished command: echo Finished ``` To add your function to the config, you need to add the following lines to the **config.yml** file: ```yaml .eas/build/config.yml build: name: My example config steps: - eas/checkout - eas/install_node_modules - run: name: Finished command: echo Finished # @info # functions: my_function: name: My function path: ./myFunction # @end # ``` The `path` property should be a relative path from the config file to your function directory. In this case, it's just `./myFunction`. Now, add a call to the `my_function` function in the **config.yml** file: ```yaml .eas/build/config.yml build: name: My example config steps: - eas/checkout - eas/install_node_modules # @info # - my_function # @end # - run: name: Finished command: echo Finished functions: my_function: name: My function path: ./myFunction ``` ## Working on the function For a more advanced example, let's say you want to make a function calculate the sum of two numbers and print the result to the console, and then output that value from the function. To do this, modify the **config.yml** and **index.ts** files to make the function accept two inputs called `num1` and `num2` and return their sum as an output called `sum`. ```yaml .eas/build/config.yml build: name: My example config steps: - eas/checkout - eas/install_node_modules # @info # - my_function: inputs: num1: 1 num2: 2 id: sum_function # @end # - run: name: Print the sum inputs: sum: ${ steps.sum_function.sum } command: echo ${ inputs.sum } - run: name: Finished command: echo Finished functions: my_function: name: My function # @info # inputs: - name: num1 type: number - name: num2 type: number outputs: - name: sum # @end # path: ./myFunction ``` ```ts .eas/build/myFunction/src/index.ts // This file was autogenerated by `create-eas-build-function` command. // Go to README.md to learn more about how to write your own custom build functions. import { BuildStepContext, BuildStepInput, BuildStepInputValueTypeName, BuildStepOutput, } from '@expo/steps'; /* @info */ interface FunctionInputs { // first template argument is the type of the input value, second template argument is a boolean indicating if the input is required num1: BuildStepInput<BuildStepInputValueTypeName.NUMBER, true>; num2: BuildStepInput<BuildStepInputValueTypeName.NUMBER, true>; } /* @end */ /* @info */ interface FunctionOutputs { // template argument is a boolean indicating if the output is required sum: BuildStepOutput<true>; } /* @end */ async function myFunction( ctx: BuildStepContext, { inputs, outputs, }: // env, { inputs: FunctionInputs; outputs: FunctionOutputs; // env: BuildStepEnv; } ): Promise<void> { /* @info */ ctx.logger.info(`num1: ${inputs.num1.value}`); ctx.logger.info(`num2: ${inputs.num2.value}`); const sum = inputs.num1.value + inputs.num2.value; ctx.logger.info(`sum: ${sum}`); outputs.sum.set(sum.toString()); // Currently, outputs must be strings. This will improve in the future. /* @end */ } ``` > **Info** Remember to compile your function each time you make changes to it: `npm run build`. ## Summary - Writing functions is a great way to extend the functionality of custom builds with your own logic. - EAS Build functions are reusable — you can use them in multiple custom build configurations. - Using EAS Build functions is a great option for more advanced use cases that are not easy to do by writing shell scripts. - Most of the [built-in functions](/custom-builds/schema/#built-in-eas-functions) are open-source and can be forked or used as a reference for writing your own functions. Check out the **example repository** for more detailed examples:

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jaksm/expo-docs-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server