{"id":41340,"date":"2025-05-28T15:20:37","date_gmt":"2025-05-28T09:50:37","guid":{"rendered":"https:\/\/www.inogic.com\/blog\/?p=41340"},"modified":"2025-05-28T17:27:54","modified_gmt":"2025-05-28T11:57:54","slug":"boost-reusability-and-performance-in-power-apps-controls-framework-with-dependent-libraries","status":"publish","type":"post","link":"https:\/\/www.inogic.com\/blog\/2025\/05\/boost-reusability-and-performance-in-power-apps-controls-framework-with-dependent-libraries\/","title":{"rendered":"Boost Reusability and Performance in Power Apps Controls Framework with Dependent Libraries"},"content":{"rendered":"<p><img decoding=\"async\" class=\"alignnone size-full wp-image-41351\" src=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/05\/Technical-blog.png\" alt=\"Power Apps\" width=\"1925\" height=\"1100\" srcset=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/05\/Technical-blog.png 1925w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/05\/Technical-blog-300x171.png 300w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/05\/Technical-blog-1024x585.png 1024w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/05\/Technical-blog-768x439.png 768w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/05\/Technical-blog-1536x878.png 1536w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/05\/Technical-blog-660x377.png 660w\" sizes=\"(max-width: 1925px) 100vw, 1925px\" \/><\/p>\n<p>In this blog, we\u2019ll explore how using dependent libraries can significantly improve maintainability, reusability, and performance in Power Apps PCF controls. Through practical scenarios, we\u2019ll uncover how this architectural choice reduces bundle size and streamlines development.<\/p>\n<p>To illustrate this, let&#8217;s dive into a recent scenario our team encountered and how dependent libraries transformed our development process.<\/p>\n<p>Recently at work, our team was assigned to build two different PCF controls \u2013 one for showing a sales summary and another for displaying a forecast chart. Even though these were two separate controls, both of them needed the same kinds of utility functions and also used the same third-party libraries, such as input validators and rich text editors.<\/p>\n<p>Initially, we bundled these libraries separately within each control. But that approach caused several issues:<\/p>\n<ul>\n<li>Duplicate code across controls<\/li>\n<li>Increased control bundle sizes<\/li>\n<li>Inconsistent logic and updates<\/li>\n<li>Slower load times<\/li>\n<\/ul>\n<p>As the application suite started to grow, these problems began to affect performance and maintainability.<\/p>\n<p>That\u2019s when we explored the concept of dependent libraries, a feature supported by Power Apps that completely changed the way we architect our controls.<\/p>\n<p>We will walk through the use cases where dependent libraries made a significant difference in the project:<\/p>\n<ol>\n<li>Sharing a utility library across multiple PCF controls<\/li>\n<li>On-demand loading of third-party libraries like TinyMCE<\/li>\n<\/ol>\n<p>The blog also discusses why the shared UMD-based external library approach was chosen over bundling directly within each control, and how UMD vs. bundled libraries differ in the PCF context.<\/p>\n<h2>Why UMD and Not Bundled?<\/h2>\n<p><strong>UMD (Universal Module Definition)<\/strong> libraries allow shared code to be loaded once and made globally available across controls. In contrast:<\/p>\n<ul>\n<li>Bundled libraries get embedded inside each PCF control&#8217;s final output, causing duplication.<\/li>\n<li>Every control ends up with its own version, increasing size and complicating updates.<\/li>\n<li>Shared UMD libraries allow centralized updates, reduced bundle size, and consistent behavior.<\/li>\n<\/ul>\n<p><strong>Approach Used in This Blog:<\/strong> We&#8217;re using the UMD external library approach by creating a separate PCF component (like CommonLibrary) which exposes utilities globally. Then, other PCF controls can declare a dependency on this component and load it via loadDependency. This provides clean separation of concerns and optimized performance.<\/p>\n<h2>Use Case #1: Sharing Utility Libraries Across Controls<\/h2>\n<h3>Scenario<\/h3>\n<p>We were working on two different PCF controls:<\/p>\n<ul>\n<li><strong>Sales Overview Grid<\/strong> \u2013 Displays currency totals for various accounts<\/li>\n<li><strong>Forecast Chart Control<\/strong> \u2013 Shows forecasts and requires formatted numeric values<\/li>\n<\/ul>\n<p>Both controls needed consistent logic for formatting currency values and validating numbers. Rather than duplicating this logic in both controls, we decided to centralize it using a shared library.<\/p>\n<p>To achieve this, we created a <strong>Library Component<\/strong>. According to Microsoft\u2019s guidance, <em>\u201cThis component can provide some functionality or only be a container for the library.\u201d<\/em> In our case, it served as a container that simply injected shared JavaScript functions.<\/p>\n<h3>The Shared Library Component (CommonLibrary)<\/h3>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-41341\" src=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/05\/1Power-Apps-Controls-FrameWork.png\" alt=\"Power Apps Controls FrameWork\" width=\"892\" height=\"313\" srcset=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/05\/1Power-Apps-Controls-FrameWork.png 892w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/05\/1Power-Apps-Controls-FrameWork-300x105.png 300w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/05\/1Power-Apps-Controls-FrameWork-768x269.png 768w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/05\/1Power-Apps-Controls-FrameWork-660x232.png 660w\" sizes=\"(max-width: 892px) 100vw, 892px\" \/><\/p>\n<p><strong>Note: This should be your folder structure and in place of dist folder you can use lib<\/strong><\/p>\n<p><strong>Both PCF controls can use the shared CommonUtils.js file, eliminating the need to duplicate code.<\/strong><\/p>\n<p>We created a dedicated PCF control named CommonLibrary. It doesn\u2019t render anything visually but is responsible for injecting a shared JavaScript file (common-utils.js) into the page.<\/p>\n<p>Here are a few functions that were commonly used in both the Sales Overview Grid and Forecast Chart Control. This utility library contains functions that handle currency formatting, input validation, percentage calculation, and empty string checks.<\/p>\n<p>Here\u2019s the content of dist\/commonUtils.js using a UMD wrapper:<\/p>\n<pre class=\"lang:css gutter:true start:1\">var CommonUtils = (function (exports) {\r\n\r\n\"use strict\";\r\n\r\nfunction formatCurrency(amount: any, currencyCode?: string): string {\r\n\r\nconst numericValue = parseFloat(amount as any) || 0;\r\n\r\nconst formatter = new Intl.NumberFormat(\"en-IN\", {\r\n\r\nstyle: \"currency\",\r\n\r\ncurrency: currencyCode || \"INR\",\r\n\r\nminimumFractionDigits: 2,\r\n\r\n});\r\n\r\nreturn formatter.format(numericValue);\r\n\r\n}\r\n\r\n\u00a0\r\n\r\nfunction isValidNumber(input: any, options = {}) {\r\n\r\nconst minimum = options.min ?? Number.MIN_SAFE_INTEGER;\r\n\r\nconst maximum = options.max ?? Number.MAX_SAFE_INTEGER;\r\n\r\nif (input == null || (typeof input === \"string\" &amp;&amp; input === \"\")) return false;\r\n\r\nconst parsed = Number(input);\r\n\r\nreturn !Number.isNaN(parsed) &amp;&amp; parsed &gt;= minimum &amp;&amp; parsed &lt;= maximum;\r\n\r\n}\r\n\r\n\u00a0\r\n\r\nfunction calculatePercentage(part: number, whole: number, decimals: number = 2) {\r\n\r\nif (!isValidNumber(part) || !isValidNumber(whole) || whole === 0) return 0;\r\n\r\nreturn Number(((part \/ whole) * 100).toFixed(decimals));\r\n\r\n}\r\n\r\n\u00a0\r\n\r\nexports.formatCurrency = formatCurrency;\r\n\r\nexports.isValidNumber = isValidNumber;\r\n\r\nexports.calculatePercentage = calculatePercentage;\r\n\r\nreturn exports;\r\n\r\n})(typeof CommonUtils === \"undefined\" ? {} : CommonUtils);<\/pre>\n<p><strong>Step-by-Step: How We Set This Up<\/strong><\/p>\n<p>First we scaffolded the control.<\/p>\n<p>pac pcf init -n CommonLibrary -ns MyCompany -t field -npm<br \/>\ncd CommonLibrary<\/p>\n<p>Drop-in the helpers<\/p>\n<p>Created <strong>dist\/commonUtils.js<\/strong>:<\/p>\n<pre class=\"lang:css gutter:true start:1\">\/\/ UMD wrapper so the module can be imported *or* attached to window\r\n\r\nvar CommonUtils = (function (exports) {\r\n\r\n\"use strict\";\r\n\r\n\u00a0\r\n\r\n\/**\r\n\r\n* Convert any numeric input into localised currency \u2013 defaults to INR.\r\n\r\n*\/\r\n\r\n\u00a0\r\n\r\nfunction formatCurrency(amount: any, currencyCode?: string): string {\r\n\r\nconst numericValue = parseFloat(amount as any) || 0;\r\n\r\nconst formatter = new Intl.NumberFormat(\"en-IN\", {\r\n\r\nstyle: \"currency\",\r\n\r\ncurrency: currencyCode || \"INR\",\r\n\r\nminimumFractionDigits: 2,\r\n\r\n});\r\n\r\nreturn formatter.format(numericValue);\r\n\r\n}\r\n\r\n\u00a0\r\n\r\n\/**\r\n\r\n* Light\u2011weight validator \u2013 NaN guard + optional range check.\r\n\r\n*\/\r\n\r\nfunction isValidNumber(input: any, options = {}) {\r\n\r\nconst minimum = options.min ?? Number.MIN_SAFE_INTEGER;\r\n\r\nconst maximum = options.max ?? Number.MAX_SAFE_INTEGER;\r\n\r\nif (input == null || (typeof input === \"string\" &amp;&amp; input === \"\")) return false;\r\n\r\nconst parsed = Number(input);\r\n\r\nreturn !Number.isNaN(parsed) &amp;&amp; parsed &gt;= minimum &amp;&amp; parsed &lt;= maximum;\r\n\r\n}\r\n\r\n\u00a0\r\n\r\n\/**\r\n\r\n* Percentage with configurable precision and full safety nets.\r\n\r\n*\/\r\n\r\nfunction calculatePercentage(part: number, whole: number, decimals:number = 2) {\r\n\r\nif (!isValidNumber(part) || !isValidNumber(whole) || whole === 0) return 0;\r\n\r\nreturn Number(((part \/ whole) * 100).toFixed(decimals));\r\n\r\n}\r\n\r\nexports.formatCurrency = formatCurrency;\r\n\r\nexports.isValidNumbe = isValidNumber;\r\n\r\nexports.calculatePercentage = calculatePercentage;\r\n\r\nreturn exports;\r\n\r\n})(typeof CommonUtils === \"undefined\" ? {} : CommonUtils);<\/pre>\n<p>Ship TypeScript\u202ftypes (optional but polite)<\/p>\n<p>The objects and functions in the library must be described in a new declaration file (d.ts).<br \/>\nSo we created a new file called common-utils.d.ts and placed it in the project&#8217;s root folder:<\/p>\n<pre class=\"lang:css gutter:true start:1\">common-utils.d.ts\r\n\r\ndeclare module \"CommonUtils\" {\r\n\r\nexport function formatCurrency(amount: number, currencyCode?: string): string;\r\n\r\nexport function isValidNumber(input: any, options?: { min?: number; max?: number }): boolean;\r\n\r\nexport function calculatePercentage(part: number, whole: number, decimals?: number): number;\r\n\r\n}\r\n\r\nWe included the variable in the global scope to expose our library as a UMD module. This required a new declaration file (.d.ts), which we added to the root directory of our project\r\n\r\n<em>global.d.ts<\/em>\r\n\r\n\r\n\/* eslint-disable no-var *\/\r\n\r\ndeclare global {\r\n\r\nvar CommonUtils: typeof import(\"CommonUtils\");\r\n\r\n}\r\n\r\nexport { };\r\n\r\ntsconfig.json which is used in our controls:\r\n\r\n{\r\n\"extends\": \".\/node_modules\/pcf-scripts\/tsconfig_base.json\",\r\n\"compilerOptions\": {\r\n\"allowJs\": true,\r\n\"allowUmdGlobalAccess\": true,\r\n\"typeRoots\": [\"node_modules\/@types\"],\r\n\"outDir\": \"dist\"\r\n}\r\n}<\/pre>\n<p>Enable preview flags &amp; keep webpack from rebundling:<\/p>\n<p>The image below shows the featureconfig.json file that we added to the root directory of our project.<\/p>\n<p><img decoding=\"async\" class=\"alignnone size-full wp-image-41348\" src=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/05\/2Power-Apps-Controls-FrameWork.png\" alt=\"Power Apps Controls FrameWork\" width=\"315\" height=\"309\" srcset=\"https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/05\/2Power-Apps-Controls-FrameWork.png 315w, https:\/\/www.inogic.com\/blog\/wp-content\/uploads\/2025\/05\/2Power-Apps-Controls-FrameWork-300x294.png 300w\" sizes=\"(max-width: 315px) 100vw, 315px\" \/><\/p>\n<pre class=\"lang:css gutter:true start:1\"><em>featureconfig.json<\/em>\r\n\r\n{\r\n\"pcfAllowCustomWebpack\": \"on\",\r\n\"pcfAllowLibraryResources\": \"on\"\r\n}<\/pre>\n<p>Why this is important:<\/p>\n<ul>\n<li>pcfAllowCustomWebpack: Enables you to customize how your control is bundled (e.g., exclude external libraries).<\/li>\n<li>pcfAllowLibraryResources: Lets your control use an external JS file like js without bundling it.<\/li>\n<\/ul>\n<p>These settings are essential when working with shared libraries because they give you full control over how dependencies are treated and ensure your control stays lean.<\/p>\n<p>Configure Webpack to Treat Library as External <em>webpack.config.js<\/em> \/* eslint-disable *\/<\/p>\n<p>&#8220;use strict&#8221;; module.exports = { externals: { &#8220;CommonUtils&#8221;: &#8220;CommonUtils&#8221; } };<\/p>\n<p>Why?<\/p>\n<p>This ensures Webpack won\u2019t include CommonUtils in your final bundle. Instead, it will expect it to be loaded externally \u2014 reducing control size and ensuring consistency across multiple controls.<\/p>\n<p>Wire the manifest of CommonLibrabry Component<\/p>\n<pre class=\"lang:css gutter:true start:1\">&lt;resources&gt;\r\n&lt;library name=\"CommonUtils\" version=\"&gt;=1\" order=\"1\"&gt;\r\n&lt;packaged_library path=\"dist\/commonUtils.js\" version=\"0.0.1\" \/&gt;\r\n&lt;\/library&gt;\r\n&lt;code path=\"index.ts\" order=\"2\" \/&gt;\r\n&lt;\/resources&gt;<\/pre>\n<p>Expose the helpers on window<\/p>\n<pre class=\"lang:css gutter:true start:1\">import * as CommonUtils from \"CommonUtils\";\r\n\r\nimport { IInputs, IOutputs } from \".\/generated\/ManifestTypes\";\r\n\r\n\u00a0\r\n\r\nexport class CommonLibrary implements ComponentFramework.StandardControl&lt;IInputs, IOutputs&gt; {\r\n\r\npublic init() { }\r\n\r\npublic updateView() { }\r\n\r\npublic getOutputs(): IOutputs {\r\n\r\nconst outputs: IOutputs = {};\r\n\r\nreturn outputs;\r\n\r\n}\r\n\r\npublic destroy() { }\r\n\r\n}\r\n\r\n\u00a0\r\n\r\n\/\/ one-liner that puts the module on the global scope \u2013 key for consumers\r\n\r\n(function () { window.CommonUtils = CommonUtils; })();<\/pre>\n<p>now we used this common library in other PCF controls<\/p>\n<p>For example one of our control which is SalesOverviewGrid<\/p>\n<p>First we Scaffolded + flag resource dependencies<\/p>\n<pre class=\"lang:css gutter:true start:1\">pac pcf init -n SalesOverviewGrid -ns MyCompany -t field -npm\r\ncd SalesOverviewGrid\r\n\r\nfeatureconfig.json\r\n\r\n{ \"pcfResourceDependency\": \"on\" }\r\n\r\nWe Included the dependency declaration in the SalesOverviewGrid manifest file.\r\n\r\n&lt;resources&gt;\r\n&lt;dependency type=\"control\" name=\"publisher_MyCompany.CommonLibrary\" order=\"1\" \/&gt;\r\n&lt;code path=\"index.ts\" order=\"2\" \/&gt;\r\n&lt;\/resources&gt;<\/pre>\n<p>Load the lib, render numbers<\/p>\n<p>This is the sample index.ts for SalesOverviewGrid control<\/p>\n<pre class=\"lang:css gutter:true start:1\">import { IInputs, IOutputs } from \".\/generated\/ManifestTypes\";\r\n\r\n\/\/ Declare the external library attached to window\r\n\r\ndeclare const window: {\r\nCommonUtils: {\r\nformatCurrency: (amount: number, currencyCode?: string) =&gt; string;\r\n};\r\n};\r\n\r\nexport class SalesOverviewGrid implements ComponentFramework.StandardControl&lt;IInputs, IOutputs&gt; {\r\nprivate table!: HTMLTableElement;\r\nprivate context!: ComponentFramework.Context&lt;IInputs&gt;;\r\n\r\npublic init(ctx: ComponentFramework.Context&lt;IInputs&gt;): void {\r\nthis.context = ctx;\r\nthis.table = document.createElement(\"table\");\r\nctx.container.appendChild(this.table);\r\n}\r\n\r\npublic updateView(ctx: ComponentFramework.Context&lt;IInputs&gt;): void {\r\n\r\n\/\/ Load external library using the recommended loadDependency approach\r\n\r\nctx.utils.loadDependency?.(\"publisher_MyCompany.CommonLibrary\")\r\n\r\n.then(() =&gt; this.render())\r\n\r\n.catch((e) =&gt; console.error(\"CommonUtils load error\", e));\r\n\r\n}\r\n\r\n\u00a0\r\n\r\nprivate render(): void {\r\n\r\nconst monthlySums = [1234.56, 9876.54, 13579.24];\r\n\r\nthis.table.innerHTML = \"\";\r\n\r\nmonthlySums.forEach(v =&gt; {\r\n\r\nconst row = this.table.insertRow();\r\n\r\nrow.insertCell().innerText = window.CommonUtils.formatCurrency(v, \"INR\");\r\n\r\n});\r\n\r\n}\r\n\r\n\u00a0\r\n\r\npublic getOutputs(): IOutputs {\r\n\r\nconst outputs: IOutputs = {};\r\n\r\nreturn outputs;\r\n\r\n}\r\n\r\n\u00a0\r\n\r\npublic destroy(): void { }\r\n\r\n}<\/pre>\n<h3>We did the same for the ForecastChartControl or any other PCF control.<\/h3>\n<p>Benefits of This Approach<\/p>\n<ul>\n<li><strong>Reusable logic across all PCF controls<\/strong><\/li>\n<li><strong>No code duplication<\/strong><\/li>\n<li><strong>Centralized updates<\/strong> \u2013 update once, reflect everywhere<\/li>\n<li><strong>Faster load times<\/strong> and smaller control bundles<\/li>\n<li><strong>Cleaner code and better maintenance<\/strong><\/li>\n<\/ul>\n<h2>Use Case #2: Lazy Loading TinyMCE Editor with Dependent Libraries<\/h2>\n<h3>Scenario:<\/h3>\n<p>We needed to include a rich text editor in a custom PCF control\u2014specifically for enhancing notes on records. We chose TinyMCE because of its full-featured capabilities. However, including it on every load significantly increased the initial load time.<\/p>\n<p>Solution: On-Demand Dependent Library<\/p>\n<p>To optimize performance, we wanted to load TinyMCE only when the control actually required it\u2014such as when the text field became active<\/p>\n<p><strong>Steps to Implement:<\/strong><\/p>\n<h4>1. Configure Manifest with On-Demand Load<\/h4>\n<p>We used load-type=&#8217;onDemand&#8217; to declare the dependency in the control&#8217;s manifest:<\/p>\n<pre class=\"lang:css gutter:true start:1\">&lt;platform-action action-type=\"afterPageLoad\" \/&gt;\r\n&lt;feature-usage&gt;\r\n&lt;uses-feature name=\"Utility\" required=\"true\" \/&gt;\r\n&lt;\/feature-usage&gt;\r\n&lt;resources&gt;\r\n&lt;code path=\"index.ts\" order=\"1\" \/&gt;\r\n&lt;dependency type=\"control\"\r\nname=Publisher_MyCompany.TinyMCEStub\"\r\nload-type=\"onDemand\" \/&gt;\r\n&lt;\/resources&gt;<\/pre>\n<p>This tells the platform to load this dependency only when explicitly requested.<\/p>\n<h4>2. Declare Required Platform Features<\/h4>\n<p>We updated the manifest to declare platform usage features:<\/p>\n<pre class=\"lang:css gutter:true start:1\">&lt;platform-action action-type=\"afterPageLoad\" \/&gt;\r\n&lt;feature-usage&gt;\r\n&lt;uses-feature name=\"Utility\" required=\"true\" \/&gt;\r\n&lt;\/feature-usage&gt;<\/pre>\n<p>This ensures on-demand loading is supported during page lifecycle execution.<\/p>\n<h4>3. Create the TinyMCE Stub Library Component<\/h4>\n<p>We Built a lightweight control that only loads the TinyMCE script:<\/p>\n<pre class=\"lang:css gutter:true start:1\">export class TinyMCEStub implements ComponentFramework.StandardControl&lt;{}, {}&gt; {\r\npublic init(): void {\r\nconst script = document.createElement(\"script\");\r\nscript.src = \"https:\/\/cdn.tiny.cloud\/1\/no-api-key\/tinymce\/6\/tinymce.min.js\";\r\nscript.async = true;\r\ndocument.head.appendChild(script);\r\n}\r\npublic updateView(): void {}\r\npublic getOutputs(): IOutputs {\r\n\r\nconst outputs: IOutputs = {};\r\n\r\nreturn outputs;\r\n\r\n}\r\npublic destroy(): void {}\r\n}<\/pre>\n<p>Once this component is defined, it can be reused anywhere you want TinyMCE available.<\/p>\n<h4>4. Load the Editor Dynamically in the Dependent Control<\/h4>\n<p>Whenever TinyMCE functionality is needed, we loaded it dynamically like below:<\/p>\n<pre class=\"lang:css gutter:true start:1\">context.utils.loadDependency?.(\"publisher_MyCompany.TinyMCE\")\r\n\r\n.then(() =&gt; {\r\n\r\n(window as any).tinymce.init({\r\n\r\ntarget: document.getElementById(\"editor\")\r\n\r\n});\r\n\r\n})\r\n\r\n.catch((err: any) =&gt; console.error(\"TinyMCE load error:\", err));<\/pre>\n<h3>Benefits:<\/h3>\n<ul>\n<li><strong>Performance Optimization<\/strong>: Editor loads only when needed<\/li>\n<li><strong>Smaller Initial Bundle Size<\/strong>: Faster load times for unrelated forms<\/li>\n<li><strong>Better User Experience<\/strong>: Reduced visual clutter and control overhead<\/li>\n<\/ul>\n<h2>Conclusion: Real Productivity Gains<\/h2>\n<p>By using <strong>dependent libraries<\/strong> in Power Apps PCF controls, We\u2019ve been able to:<\/p>\n<ul>\n<li><strong>Decouple shared logic<\/strong> into a maintainable utility component<\/li>\n<li><strong>Improve performance<\/strong> by loading heavy libraries like TinyMCE on demand<\/li>\n<li><strong>Avoid duplicate code<\/strong>, reduce control size, and speed up rendering<\/li>\n<\/ul>\n<p>These patterns not only made our PCF development more efficient but also enhanced the maintainability of the solutions we delivered. Whether you&#8217;re building a complex UI component or just trying to avoid redundancy, dependent libraries are an underrated but powerful feature in the Power Apps toolkit.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this blog, we\u2019ll explore how using dependent libraries can significantly improve maintainability, reusability, and performance in Power Apps PCF controls. Through practical scenarios, we\u2019ll uncover how this architectural choice reduces bundle size and streamlines development. To illustrate this, let&#8217;s dive into a recent scenario our team encountered and how dependent libraries transformed our development\u2026 <span class=\"read-more\"><a href=\"https:\/\/www.inogic.com\/blog\/2025\/05\/boost-reusability-and-performance-in-power-apps-controls-framework-with-dependent-libraries\/\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":15,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[44,2361],"tags":[1170],"class_list":["post-41340","post","type-post","status-publish","format-standard","hentry","category-power-apps","category-technical","tag-microsoft-powerapps"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/posts\/41340","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/users\/15"}],"replies":[{"embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/comments?post=41340"}],"version-history":[{"count":0,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/posts\/41340\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/media?parent=41340"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/categories?post=41340"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.inogic.com\/blog\/wp-json\/wp\/v2\/tags?post=41340"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}