Global Functions: A game changer for reusable logic

Global Functions: A game changer for reusable logic

Microsoft has just introduced a powerful new feature in Power Apps: Global Functions through Power FX. These functions allow us to create reusable logic that can be accessed across multiple Power Platform tools without being tied to a specific Dataverse table. Unlike traditional Power Automate flows, Unbound Actions execute directly within Power Apps, improving performance and modularity. Think about them as a library of code snippets you can instantly use and reference wherever you can use Power Fx. This will work wonders to improve low-code frameworks!

So in this blog post today we will cover the following:

  • How to create Global Functions
  • How do they work
  • Where can they be used and how
  • Use cases and advantages

All the information in this blog is up to date as of 11/02/2025 but is subject to change as this is a preview feature.


Creating Global Functions

To be fair, we have started calling them like this because they are basically custom Power Fx formulas that can be used anywhere. But as far as we've seen, Microsoft calls them Low-code plug-ins Power Fx. Here is the link if you want to reference the documentation: https://learn.microsoft.com/en-us/power-apps/maker/data-platform/low-code-plug-ins-powerfx

As for how to create them, it's really simple. From any solution, click on New, then Automation and Function. (See image below).


Working the Magic

Now, after following those steps, you should be presented with something like this:

To go through the UI, we have:

  • The Display name and Description, which are self-explanatory.
  • The inputs and outputs, of which you can have as many or as little as needed.
  • The table references, where we can select which tables we want to access in the function.
  • The formula, where we will define the logic of the function.
  • Advanced options, which as of right now only show the logical name.

The inputs and outputs can only be boolean, decimal, float, integer, or string.

The most involved part will be the formula area. This will use Power Fx to execute whatever logic you may want, the same as it would be done in Canvas Apps or a Model Driven App ribbon button. There are limitations in what power fx formulas are available, they are all listed in the previously listed documentation.

The only difference with a typical Power Fx field will be the format. If you use a formula that doesn't require outputs, like Patch, you may utilize the usual format without any changes. But if you want outputs, the formula has to be organized similarly to a Json file. (See image below)

As you see in the example, the Power Fx formula follows the following format:

{Output1Name: PowerFx Logic, Output2Name: PowerFx Logic, ...}

Inside the PowerFx logic, you may reference and utilize any of the inputs or Table references. For example, you may filter the table accounts with a name that comes from the input.

When you are done with your formula and click save, a few components will be created in your solution:

  • As many inputs as you created, as a record from the CustomApiRequestParameter table
  • As many outputs as you created, as a record from the CustomApiResponseProperty table
  • A CustomApi record with the name of the function
  • A FxExpression record with the name of the function
  • The function itself

Finally, if you want to delete your function there is a specific order to do so to avoid dependency issues. First, delete outputs and inputs, then the CustomAPI and Function, and finally the FXExpression.


How to use your function

Now that we have our Power Fx "plugin", we can use it almost anywhere we could otherwise use Power Fx. The main exception is Model Driven Apps. As of right now, there is no direct way of using this tool since we have no access to the Environment data source, meaning we can't trigger unbound actions. Still, we can use them indirectly through flows or JavaScript.

As each tool has its own way of implementing this, we are going to go through all of them individually.

Canvas Apps

In Canvas Apps, our first step will be adding the Environment table to the app. This will grant us access to any function we may have already created.

Once we have access to the Environment data source we should be able to see the functions in any PowerFx field by typing: Environment.FunctionName

In this case, I'm going to create a button and call the function we used as an example at the beginning of the blog.

As you see, the format is a bit different from the usual PowerFx formulas. In the same way we did the outputs in Json format in the function, now the inputs will also follow a similar scheme.

{Input1Name: Input value, Input2Name: Input 2 value, ...}

Now, when I click the button, the function will be called and we will be able to access the outputs in a similar way one would access fields in a record.

For this example, I have decided to use TestOutput1, which just returns "This is input 1:" followed by whatever the user entered as input 1, in this case, "Canvas Apps".

Power Automate

In Power Automate, the global functions are called through the "Perform an unbound action" Dataverse step.

In this step, we first need to select our function in the "Action Name" field. Once we have done that, we will have available the input fields.

Finally, we can access the outputs of the function from the dynamic outputs tab. Below you can see that we get the desired output in our compose.

Javascript

I won't explain this in-depth since the code itself is pretty much self-explanatory, but I will give a quick overview. In this case, the code is adapted to the global function we are using as an example, but the structure is intuitive enough that it should be easy to adapt to any function you desire.

function callTestFunction(testInputValue) {
    // 1. Build the request object
    var request = {
        // Pass input parameters exactly as defined in your Action
        TestInput: testInputValue,
        
        // 2. The getMetadata function describes how to call the Action
        getMetadata: function () {
            return {
                boundParameter: null, // Unbound Action => no bound entity
                parameterTypes: {
                    "TestInput": {
                        typeName: "Edm.String",  // Change deppending on type
                        structuralProperty: 1    // 1 = 'PrimitiveType'
                    }
                },
                operationType: 0,              // 0 = Action
                operationName: "TestFunction"  // Must match the Action's schema name
            };
        }
    };

    // 3. Execute the Action using Xrm.WebApi
    Xrm.WebApi.online.execute(request).then(
        function success(response) {
            // 4. Check if the request succeeded
            if (response.ok) {
                // 5. Parse the JSON response to access output parameters
                response.json().then(function (result) {
                    var testOutput1 = result.TestOutput1;
                    var testOutput2 = result.TestOutput2;

                    console.log("TestOutput1:", testOutput1);
                    console.log("TestOutput2:", testOutput2);

                    // Optional: handle the returned values (ex. populate form fields)
                });
            }
        },
        function (error) {
            // 6. Error handling
            console.error("Error calling TestFunction:", error.message);
        }
    );
}

First, we create the request with the correct format and corresponding input values. Then we execute the request via Xrm.WebApi and check if the request succeeded. Finally, we parse the output Json and utilize the result however we may need.

In the example, we just log the outputs in the console, but we could also use them somewhere else in the code or return them to a Model Driven App.

Others

As far as we know, these are the only places where the global functions can be directly used (Well, and anywhere else where you can make an API call).

Still, we thought it was worth mentioning that through JavaScript or Power Automate, this tool could also be used in Model Driven Apps or in a Power Virtual Agent Bot.


Use Cases and Advantages

The main advantages of Global Functions are the following:

  • Great performance, since it runs inside Power Platform. (Compared to Power Automate's cloud execution)
  • Low complexity, since it works with Power Fx. This means no coding is required and is easily usable by everyone already familiar with Power Fx.
  • No API calls required from inside Power Apps.
  • Centralized and Reusable. This tool allows us to create logics that can be applied anywhere needed, meaning that it's easy to maintain and modify.
  • Its execution or trigger is not tied to a single table like Power Automate.

This is quite an impressive list of advantages, and we find that the most important is reusability. Being able to easily have Centralized Business Logic across multiple Canvas Apps, Cloud flows and JavaScripts is a game changer. This is obvious for something like creating a low-code framework, but even in daily development is quite an advantage.

To give an example, if we have a numeric field that needs a complex tax calculation, and said field is interacted with in several apps, background processes, etc... if for whatever reason that calculation were to change, you only need to modify the Global Function. Automatically every process is going to use the new calculation without needing to change them all one by one.

We also find that it's very useful even for a single use. For example, for business logic that may change frequently but is used inside a complex Power Automate flow or through code. Having it in a function means it can be easily changed without needing to modify the flow or code, giving easy access to consultants, or even just making things quicker for developers.

Finally, we can't talk about advantages without disadvantages. In this case, we feel the disadvantage is mostly self-imposed, but quite large. This is because we cannot use them directly in Model Driven App and Power Virtual Agent Bots. Especially Model Driven Apps are pretty much the most used feature of Power Platform, and being unable to use them there reduces a lot its usability.

This is mostly due to the lack of access to the environment data source in PowerFx. Without that, we cannot call unbound actions without code. If one day we get access to this feature the value of Global Functions will easily duplicate. It would allow us to create simple logics and interactions without the need for Power Automate or code, and it would work faster too!


Final Words

To conclude this post, I wanted to reiterate the usefulness of this tool if used correctly. It's an incredible feature that will only improve if we ever get access to it in Model Driven Apps.

Given how easy it is to use, I say give it a try! You may be surprised at what you are able to achieve.

Read more