{"id":12972,"date":"2021-01-14T17:00:40","date_gmt":"2021-01-15T01:00:40","guid":{"rendered":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/power-apps\/source-code-files-for-canvas-apps\/"},"modified":"2025-06-11T07:55:58","modified_gmt":"2025-06-11T14:55:58","slug":"source-code-files-for-canvas-apps","status":"publish","type":"post","link":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/power-apps\/source-code-files-for-canvas-apps\/","title":{"rendered":"Source code files for Canvas apps"},"content":{"rendered":"<p>Imagine using GitHub with a Canvas app.\u00a0 And I mean using GitHub as it was meant to be used, with text diffs between versions, and not just storing opaque .msapp blobs.\u00a0 \u00a0Teams can collaborate on apps: they can work on private branches, diff changes, create pull requests for review, and merge into master.<\/p>\n<p>Imagine using Visual Studio Code with a Canvas app, a full screen editor with search and replace.<\/p>\n<p>We are very pleased to announce the experimental release of a tool that enables these modern miracles.\u00a0 It is but the first step as we make application lifecycle management easier for formulas and Canvas apps.<\/p>\n<p>To illustrate, in this short video we will change the Icon property of an Icon control with these steps:<\/p>\n<ol>\n<li>Export an app as an .msapp file with <strong>Save As<\/strong>.<\/li>\n<li>Unpack the .msapp to individual source files using our new tool.<\/li>\n<li>Make a simple change to a formula using Visual Studio Code.<\/li>\n<li>Pack the modified source files back into an .msapp file.<\/li>\n<li>Open the modified .msapp file in Studio and see the result of my change.<\/li>\n<\/ol>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" class=\"alignnone size-full wp-image-12973\" height=\"768\" src=\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-content\/uploads\/2021\/01\/2021-01-14_00h42_41.gif\" width=\"1368\"\/><\/p>\n<p>This new tool enables the source code of a Canvas app to be effectively managed in GitHub or Azure DevOps.\u00a0 Diffs, pull requests, and comments can be based on lines of formula text rather than .msapp blob files.<\/p>\n<p>In this next example, we&#8217;ll make the same change to the Canvas app stored in GitHub as text source code files.\u00a0 We&#8217;ll go through all the steps required to manage the change, have it reviewed, commented on, merged in to master, and the result tested.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" class=\"alignnone size-full wp-image-12997\" height=\"768\" src=\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-content\/uploads\/2021\/01\/g1.gif\" width=\"1368\"\/><\/p>\n<p>We&#8217;ll work with this GitHub repo in Visual Studio Code.\u00a0 First we&#8217;ll create a new branch, make modifications there (change the icon from &#8220;Person&#8221; to &#8220;People&#8221;), and push the changes to our new branch on GitHub.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" class=\"alignnone size-full wp-image-12998\" height=\"768\" src=\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-content\/uploads\/2021\/01\/g2.gif\" width=\"1368\"\/><\/p>\n<p>Back on GitHub, we&#8217;ll create a pull request for this new branch to merge into master.\u00a0 We&#8217;ll have an opportunity to review the one line change, to comment on the change, and to approve the merge.\u00a0 Canvas apps become a part of your existing application lifecycle management workflow.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" class=\"alignnone size-full wp-image-12999\" height=\"768\" src=\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-content\/uploads\/2021\/01\/g3.gif\" width=\"1368\"\/><\/p>\n<p>And after the merge has been made, we sync changes back to our client and recreate the .msapp file.\u00a0 We can now load the file into Power Apps Studio and see our change.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"\" class=\"alignnone size-full wp-image-13000\" height=\"768\" src=\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-content\/uploads\/2021\/01\/2021-01-14_10h04_56.gif\" width=\"1368\"\/><\/p>\n<p>Excited?\u00a0 These examples only scratches the surface of what is possible.\u00a0 By supporting text files, all the tools that you love and all the unique workflows that you have created can now be used with Canvas apps too.<\/p>\n<h2>Limitations<\/h2>\n<p>But before you get too excited, let&#8217;s reiterate that this is experimental.\u00a0 We are making this available now for your feedback and to find issues.<\/p>\n<p>Please do not convert all your .msapp files to source files and throw away the originals.\u00a0 We are working toward a day when you can do this, but that is not today.\u00a0 \u00a0By far, Power Apps Studio is still the best place to edit a Canvas app.\u00a0 We are introducing a new way to manage and edit Canvas apps, a companion to Studio, not a replacement.<\/p>\n<p>There are some known limitations and gotchas:<\/p>\n<ul>\n<li>Outside of Studio, don&#8217;t add a control with the same name as one that already exists.\u00a0 This can happen easily if two different authors use Power Apps Studio to add a button control, resulting in two different <strong>Button1<\/strong> controls.\u00a0 When collaborating with others, we recommend renaming controls to something appropriate and hopefully unique within the app.<\/li>\n<li>The source code file may expose options that Studio does not.\u00a0 For example, the <strong>ZIndex<\/strong> property is exposed on controls.\u00a0 In Studio, this isn&#8217;t a full fledged property and can only be moved up or down with a static value.\u00a0 If you put a formula here, the app may not operate properly.<\/li>\n<\/ul>\n<h2>Distribution<\/h2>\n<p>So, how do you get the cool <strong>PASopa<\/strong> tool used above?\u00a0 \u00a0To download and use:<\/p>\n<ol>\n<li>Install <a href=\"https:\/\/dotnet.microsoft.com\/download\/dotnet-core\/3.1\">.NET Core SDK 3.1.x (x64)<\/a>.<\/li>\n<li>Clone the repo at\u00a0<a href=\"https:\/\/github.com\/microsoft\/PowerApps-Language-Tooling\">https:\/\/github.com\/microsoft\/PowerApps-Language-Tooling<\/a><\/li>\n<li>Run <strong>build.cmd<\/strong> in the root directory.<\/li>\n<li>You can find <strong>PASopa.exe<\/strong> and needed dependencies in the <strong>bin\\Debug\\PASopa<\/strong> directory.<\/li>\n<\/ol>\n<p>More details on building are available in the <a href=\"https:\/\/github.com\/microsoft\/PowerApps-Language-Tooling\/blob\/master\/README.md#setting-up-a-dev-box\">GitHub readme<\/a>.<\/p>\n<p>I did say this was experimental. \ud83d\ude42 This isn&#8217;t going to be for everyone at this time and that is OK.\u00a0 At this early juncture we are looking for savvy early adopters that can give us good feedback on the directory structure and file format.\u00a0 Eventually we will be integrating this directly with the <a href=\"https:\/\/docs.microsoft.com\/en-us\/powerapps\/developer\/data-platform\/powerapps-cli\">Power Apps CLI<\/a>\u00a0and it can be run by anyone without needing to do a build.\u00a0 PASopa is just a test harness that we are using in the meantime.<\/p>\n<p>We are releasing this tool as open source, and that will still be true even after we integrate with the Power Apps CLI.\u00a0 We&#8217;d love your feedback and issue reports directly through GitHub.\u00a0 Eventually, we will also welcome your pull requests, but are limiting outside contributions until we are better established.<\/p>\n<h2>YAML File Format<\/h2>\n<p>We adopted a subset of YAML as our file format.\u00a0 Our first priority was a format that was super easy to read and write by humans.\u00a0 But we also wanted something that could be embedded in other places within the Power Platform, and many of them use YAML already or are considering this move.\u00a0 \u00a0We wanted to leverage existing libraries and tools and not create something completely new.<\/p>\n<p>There are three unique aspects to how we embed within YAML:<\/p>\n<ul>\n<li><strong>All formulas start with a leading =.\u00a0<\/strong> \u00a0Just like Excel, the <strong>=<\/strong> introduces a formula rather than a static value.\u00a0 \u00a0We don&#8217;t make you write the leading equals in Power Apps Studio but if you notice the formula bar it is always there.\u00a0 The leading <strong>=<\/strong>\u00a0also helped us avoid the normal data type interpretation that YAML does for static value, that is not appropriate for formulas.<\/li>\n<li><strong>Some formulas must be expressed in YAML multi-line.\u00a0<\/strong> \u00a0Using the leading <strong>=<\/strong> helps us a great deal, but it doesn&#8217;t address everything.\u00a0 If you have a formula that contains a string with an embedded <strong>#<\/strong>, it is interpreted by YAML as the start of a comment, and the rest of the line will be truncated.\u00a0 In these cases, the formula must be expressed using YAML&#8217;s multi-line facilities, most likely being a variant of the <strong>|<\/strong> syntax.<\/li>\n<li><strong>Controls are typed with the As keyword.\u00a0<\/strong> Normally YAML has only a single name to the left of the <strong>:<\/strong> when providing a property value.\u00a0 But there is nothing to say that left hand side can&#8217;t be more complex and we are taking advantage of this to not only name the property but also provide its type.\u00a0 We know our use of\u00a0<strong>As<\/strong> here is different from how we use it in\u00a0<strong>ForAll<\/strong> and other record scope functions, and we considered lots of other alternatives, but the resounding feedback from early reviews was to stick with what Visual Basic used.<\/li>\n<\/ul>\n<p>Full details on the file format are available in <a href=\"https:\/\/github.com\/microsoft\/PowerApps-Language-Tooling\/blob\/master\/docs\/YAMLFileFormat.md\">docs included in the GitHub repo<\/a>.<\/p>\n<p>Note that we support only a very specific subset of YAML.\u00a0 Properties with static values, such as trying to set <strong>Size: 24<\/strong>\u00a0(without a leading <strong>=<\/strong>) won&#8217;t work.\u00a0 We also deliberately avoided YAML line comments that start with a\u00a0<strong>#<\/strong> because of the confusion they can cause.\u00a0 \u00a0Over time and based on your feedback we may support more YAML, but for now, it is very restrictive and that is by design.<\/p>\n<p>Here is a simple example form the <a href=\"https:\/\/docs.microsoft.com\/en-us\/powerapps\/sample-apps\/emergency-response\/overview\">Hospital Emergency Response solution<\/a> we shipped last spring.\u00a0 Note that as with all YAML, the indentation level indicates what is inside a container (<strong>SplashScreen<\/strong> in this case) and is also used for line continuation of the <strong>OnHidden<\/strong> property.<\/p>\n<div>\n<div>\n<pre>SplashScreen\u00a0As\u00a0screen:\n\u00a0\u00a0\u00a0\u00a0Width:\u00a0=Max(App.Width,\u00a0App.DesignWidth)\n\u00a0\u00a0\u00a0\u00a0Height:\u00a0=Max(App.Height,\u00a0App.DesignHeight)\n\u00a0\u00a0\u00a0\u00a0Size:\u00a0=1\u00a0+\u00a0CountRows(App.SizeBreakpoints)\u00a0-\u00a0CountIf(App.SizeBreakpoints,\u00a0Value\u00a0&gt;=\u00a0SplashScreen.Width)\n\u00a0\u00a0\u00a0\u00a0Orientation:\u00a0=If(SplashScreen.Width\u00a0&lt;\u00a0SplashScreen.Height,\u00a0Layout.Vertical,\u00a0Layout.Horizontal)\n\u00a0\u00a0\u00a0\u00a0OnHidden:\u00a0|-\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0=\/\/Check\u00a0to\u00a0see\u00a0if\u00a0this\u00a0is\u00a0a\u00a0mobile\u00a0device\u00a0if\u00a0so,\u00a0then\u00a0save\u00a0data\u00a0for\u00a0all\u00a0other\u00a0apps\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/Notify(\"Trying\u00a0Save\",NotificationType.Information);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0If(\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Value(AltCheck_Lbl_1.Text)\u00a0&gt;\u00a00,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SaveData(\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0MySplashSelectionsCollection,\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\"MySplashSelections\"\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/Notify(\"Did\u00a0Save\",NotificationType.Information);\u00a0\u00a0\u00a0\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0);\n\u00a0\u00a0\u00a0\u00a0OnVisible:\u00a0=Refresh(Systems);Refresh(Regions);\n\n\u00a0\u00a0\u00a0\u00a0Splash_Main_Icon\u00a0As\u00a0image:\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Image:\u00a0=SplashIcon\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ZIndex:\u00a0=1\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0HoverFill:\u00a0=ColorFade(Splash_Main_Icon.Fill,\u00a020%)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0PressedFill:\u00a0=ColorFade(Splash_Main_Icon.Fill,\u00a0-20%)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Height:\u00a0=499\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Width:\u00a0=638\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0FocusedBorderColor:\u00a0=Splash_Main_Icon.BorderColor\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0HoverBorderColor:\u00a0=ColorFade(Splash_Main_Icon.BorderColor,\u00a020%)\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0PressedBorderColor:\u00a0=ColorFade(Splash_Main_Icon.BorderColor,\u00a0-20%)<\/pre>\n<\/div>\n<\/div>\n<h2>Directory Structure<\/h2>\n<p>Not everything gets the YAML treatment.\u00a0 There are a number of app resources and settings that retain their original not-meant-for-humans treatment and are not intended to be edited outside of Power Apps Studio.\u00a0 The full directory structure and how to deal with merge conflicts in other files is outlined in the <a href=\"https:\/\/github.com\/microsoft\/PowerApps-Language-Tooling#folder-structure\">GitHub readme<\/a>.<\/p>\n<p>For the simple one Icon control app that started this blog post, let&#8217;s walk through the files we find after <strong>PASopa -unpack<\/strong> has done it&#8217;s work.<\/p>\n<p>First, let&#8217;s look at the files that are the most critical, that truly define the app.\u00a0 These should never be deleted and merges should be handled as you normally would in GitHub:<\/p>\n<ul>\n<li><strong>\\src\\App.pa.yaml<\/strong> &#8211; The <strong>*.pa.yaml<\/strong> files are where the formulas are located.\u00a0 This file contains the formulas associated with the app, such as <strong>App.OnStart<\/strong>.\u00a0 Since there is nothing set here, this file contains simply <strong>App As appinfo<\/strong>.<\/li>\n<li><strong>\\src\\Screen1.pa.yaml<\/strong> &#8211; Control hierarchy and formulas for Screen1.\u00a0 Each screen is broken out individually into a separate file.\u00a0 In our case:<\/li>\n<\/ul>\n<div>\n<pre>Screen1\u00a0As\u00a0screen:\n\n\u00a0\u00a0\u00a0\u00a0Icon1\u00a0As\u00a0icon.Person:\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Icon:\u00a0=Icon.People\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Width:\u00a0=1366\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Height:\u00a0=768\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ZIndex:\u00a0=1<\/pre>\n<\/div>\n<ul>\n<li><strong>\\CanvasManifest.json<\/strong> &#8211; Information about the published app.<\/li>\n<li><strong>\\ComponentReferences.json<\/strong> &#8211; If this app used any components, they would be listed here.\u00a0 As it does not, it is empty: <strong>[ ]<\/strong><\/li>\n<li><strong>\\Assets\\resources.xml<\/strong> &#8211; Listing of resources embedded in the app.\u00a0 For this simple app it is empty:\u00a0\u00a0<strong><span style=\"font-size: 1rem;\">{<\/span><span style=\"font-size: 1rem;\">\u00a0 &#8220;Resources&#8221;:\u00a0[]\u00a0<\/span><span style=\"font-size: 1rem;\">}<\/span><\/strong><span style=\"font-size: 1rem;\">.<\/span><\/li>\n<li><strong>\\Connections\\Connections.json<\/strong> &#8211; Listing of data sources in this app.\u00a0 For this simple app it is empty: <strong>{ }<\/strong>.<\/li>\n<\/ul>\n<p><span style=\"font-size: 1rem;\">Next comes files that are boiler plate, copied in when the app was created.\u00a0 Normally these will not change.\u00a0 If the Theme of the app is changed, the entire file will be swapped out.<\/span><\/p>\n<ul>\n<li><strong>\\Assets\\logo.jpg<\/strong> &#8211; Logo for the app, referenced in <strong>\\CanvasManifest.json<\/strong>.<\/li>\n<li><strong>\\ControlTemplates.json<\/strong> &#8211; Information on three base classes used in this app, the Icon control, the Screen, and the App.<\/li>\n<li><strong>\\Other\\References\\Theme.json<\/strong> &#8211; Theme for the app.\u00a0 Each individual color and size is enumerated.<\/li>\n<li><strong>\\pkgs\\icon_2.3.0.xml<\/strong> &#8211; The control template for the one control we used, the Icon control.<\/li>\n<\/ul>\n<p>Power Apps Studio maintains state between sessions, so you can get back to where you were\u00a0 \u00a0These can be deleted at any time and are not a concern for merge conflicts.<\/p>\n<ul>\n<li><strong>\\src\\EditorState\\App.editorstate.json<\/strong> &#8211; Information about the app.<\/li>\n<li><strong>\\src\\EditorState\\Screen1.editorstate.json<\/strong> &#8211; Same as App.editorstate.json, scoped to Screen1.<\/li>\n<\/ul>\n<p>And finally, there are a set of files that the\u00a0<strong>PASopa\u00a0<\/strong>tool uses to ensure proper roundtripping of an app between .msapp and source files.\u00a0 It is safe to keep the latest version of these files if there is a merge conflict.<\/p>\n<ul>\n<li><strong>\\Other\\checksum.json<\/strong> &#8211; Checksums of the original files in the .msapp file.\u00a0 This file will not match the layout on the file system that -pack\/-unpack read and write, it matches instead the zip file directory structure in the .msapp.\u00a0 This is used internally to detect differences to ensure we are roundtripping correctly.<\/li>\n<li><strong>\\Other\\entropy.json<\/strong> &#8211; A file where we collect all the other bits of information that are needed for us to faithfully roundtrip the app, but can be easily ignored and\/or deleted at any time.<\/li>\n<\/ul>\n<h2>Feedback<\/h2>\n<p>We are experimental.\u00a0 Have I mentioned that yet? \ud83d\ude42 Now is the time to let us know what you think, now is the time to make any needed changes.\u00a0 Please use <a href=\"https:\/\/github.com\/microsoft\/PowerApps-Language-Tooling\/issues\">GitHub issues<\/a> to the fullest, for comments, questions, actual issues, and any other feedback you may have.<\/p>\n<p>\u00a0<\/p>\n<p>\u00a0<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Imagine using GitHub and Visual Studio Code with the text formulas of a Canvas app.\u00a0 Teams can collaborate on apps: they can work on private branches, diff changes, create pull requests for review, and merge into master.  We are very pleased to announce the experimental release of a tool that enables these modern miracles.\u00a0 It is but the first step as we make application lifecycle management easier for formulas and Canvas apps.<\/p>\n","protected":false},"author":86,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"ms_queue_id":[],"ep_exclude_from_search":false,"_classifai_error":"","_classifai_text_to_speech_error":"","_alt_title":"","ms-ems-related-posts":[],"footnotes":""},"audience":[3378],"content-type":[3424],"job-role":[],"product":[3473],"property":[],"topic":[3421,3422],"coauthors":[2104],"class_list":["post-12972","post","type-post","status-publish","format-standard","hentry","audience-it-professional","content-type-news","product-power-apps","topic-application-modernization","topic-hyperautomation"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.2 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Source code files for Canvas apps - Microsoft Power Platform Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Source code files for Canvas apps - Microsoft Power Platform Blog\" \/>\n<meta property=\"og:description\" content=\"Imagine using GitHub and Visual Studio Code with the text formulas of a Canvas app.\u00a0 Teams can collaborate on apps: they can work on private branches, diff changes, create pull requests for review, and merge into master. We are very pleased to announce the experimental release of a tool that enables these modern miracles.\u00a0 It is but the first step as we make application lifecycle management easier for formulas and Canvas apps.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/power-apps\/source-code-files-for-canvas-apps\/\" \/>\n<meta property=\"og:site_name\" content=\"Microsoft Power Platform Blog\" \/>\n<meta property=\"article:published_time\" content=\"2021-01-15T01:00:40+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-11T14:55:58+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-content\/uploads\/2021\/01\/2021-01-14_00h42_41.gif\" \/>\n\t<meta property=\"og:image:width\" content=\"1368\" \/>\n\t<meta property=\"og:image:height\" content=\"768\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/gif\" \/>\n<meta name=\"author\" content=\"Greg Lindhorst\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Greg Lindhorst\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"10 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/\"},\"author\":[{\"@id\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/author\/greg-lindhorst\/\",\"@type\":\"Person\",\"@name\":\"Greg Lindhorst\"}],\"headline\":\"Source code files for Canvas apps\",\"datePublished\":\"2021-01-15T01:00:40+00:00\",\"dateModified\":\"2025-06-11T14:55:58+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/\"},\"wordCount\":1868,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-content\/uploads\/2021\/01\/2021-01-14_00h42_41.gif\",\"keywords\":[\"Code first\",\"Formulas\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/\",\"url\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/\",\"name\":\"Source code files for Canvas apps - Microsoft Power Platform Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-content\/uploads\/2021\/01\/2021-01-14_00h42_41.gif\",\"datePublished\":\"2021-01-15T01:00:40+00:00\",\"dateModified\":\"2025-06-11T14:55:58+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/#primaryimage\",\"url\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-content\/uploads\/2021\/01\/2021-01-14_00h42_41.gif\",\"contentUrl\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-content\/uploads\/2021\/01\/2021-01-14_00h42_41.gif\",\"width\":1368,\"height\":768,\"caption\":\"graphical user interface, application, PowerPoint\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Source code files for Canvas apps\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/#website\",\"url\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/\",\"name\":\"Microsoft Power Platform Blog\",\"description\":\"Innovate with Business Apps\",\"publisher\":{\"@id\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/#organization\",\"name\":\"Microsoft Power Platform Blog\",\"url\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-content\/uploads\/2020\/03\/Microsoft-Logo-e1685482038800.png\",\"contentUrl\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-content\/uploads\/2020\/03\/Microsoft-Logo-e1685482038800.png\",\"width\":194,\"height\":145,\"caption\":\"Microsoft Power Platform Blog\"},\"image\":{\"@id\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/#\/schema\/person\/dbd4cb8af4503e696f240353831f05d4\",\"name\":\"Greg Lindhorst\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/secure.gravatar.com\/avatar\/d2e26bc357423265c4eeeb6a4ed51bd71fb29b8eced3e31f4bc1ccd5bedaf80f?s=96&d=mm&r=g0133d144d5ed416197bd3b29ccd9a59c\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/d2e26bc357423265c4eeeb6a4ed51bd71fb29b8eced3e31f4bc1ccd5bedaf80f?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/d2e26bc357423265c4eeeb6a4ed51bd71fb29b8eced3e31f4bc1ccd5bedaf80f?s=96&d=mm&r=g\",\"caption\":\"Greg Lindhorst\"},\"url\":\"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/author\/gregli\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Source code files for Canvas apps - Microsoft Power Platform Blog","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/","og_locale":"en_US","og_type":"article","og_title":"Source code files for Canvas apps - Microsoft Power Platform Blog","og_description":"Imagine using GitHub and Visual Studio Code with the text formulas of a Canvas app.\u00a0 Teams can collaborate on apps: they can work on private branches, diff changes, create pull requests for review, and merge into master. We are very pleased to announce the experimental release of a tool that enables these modern miracles.\u00a0 It is but the first step as we make application lifecycle management easier for formulas and Canvas apps.","og_url":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/power-apps\/source-code-files-for-canvas-apps\/","og_site_name":"Microsoft Power Platform Blog","article_published_time":"2021-01-15T01:00:40+00:00","article_modified_time":"2025-06-11T14:55:58+00:00","og_image":[{"width":1368,"height":768,"url":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-content\/uploads\/2021\/01\/2021-01-14_00h42_41.gif","type":"image\/gif"}],"author":"Greg Lindhorst","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Greg Lindhorst","Est. reading time":"10 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/#article","isPartOf":{"@id":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/"},"author":[{"@id":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/author\/greg-lindhorst\/","@type":"Person","@name":"Greg Lindhorst"}],"headline":"Source code files for Canvas apps","datePublished":"2021-01-15T01:00:40+00:00","dateModified":"2025-06-11T14:55:58+00:00","mainEntityOfPage":{"@id":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/"},"wordCount":1868,"commentCount":0,"publisher":{"@id":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/#organization"},"image":{"@id":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/#primaryimage"},"thumbnailUrl":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-content\/uploads\/2021\/01\/2021-01-14_00h42_41.gif","keywords":["Code first","Formulas"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/","url":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/","name":"Source code files for Canvas apps - Microsoft Power Platform Blog","isPartOf":{"@id":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/#primaryimage"},"image":{"@id":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/#primaryimage"},"thumbnailUrl":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-content\/uploads\/2021\/01\/2021-01-14_00h42_41.gif","datePublished":"2021-01-15T01:00:40+00:00","dateModified":"2025-06-11T14:55:58+00:00","breadcrumb":{"@id":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/#primaryimage","url":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-content\/uploads\/2021\/01\/2021-01-14_00h42_41.gif","contentUrl":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-content\/uploads\/2021\/01\/2021-01-14_00h42_41.gif","width":1368,"height":768,"caption":"graphical user interface, application, PowerPoint"},{"@type":"BreadcrumbList","@id":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/2021\/01\/14\/source-code-files-for-canvas-apps\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/"},{"@type":"ListItem","position":2,"name":"Source code files for Canvas apps"}]},{"@type":"WebSite","@id":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/#website","url":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/","name":"Microsoft Power Platform Blog","description":"Innovate with Business Apps","publisher":{"@id":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/#organization","name":"Microsoft Power Platform Blog","url":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-content\/uploads\/2020\/03\/Microsoft-Logo-e1685482038800.png","contentUrl":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-content\/uploads\/2020\/03\/Microsoft-Logo-e1685482038800.png","width":194,"height":145,"caption":"Microsoft Power Platform Blog"},"image":{"@id":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/#\/schema\/person\/dbd4cb8af4503e696f240353831f05d4","name":"Greg Lindhorst","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/d2e26bc357423265c4eeeb6a4ed51bd71fb29b8eced3e31f4bc1ccd5bedaf80f?s=96&d=mm&r=g0133d144d5ed416197bd3b29ccd9a59c","url":"https:\/\/secure.gravatar.com\/avatar\/d2e26bc357423265c4eeeb6a4ed51bd71fb29b8eced3e31f4bc1ccd5bedaf80f?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d2e26bc357423265c4eeeb6a4ed51bd71fb29b8eced3e31f4bc1ccd5bedaf80f?s=96&d=mm&r=g","caption":"Greg Lindhorst"},"url":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/author\/gregli\/"}]}},"bloginabox_animated_featured_image":null,"bloginabox_display_generated_audio":false,"distributor_meta":false,"distributor_terms":false,"distributor_media":false,"distributor_original_site_name":"Microsoft Power Platform Blog","distributor_original_site_url":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog","push-errors":false,"_links":{"self":[{"href":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-json\/wp\/v2\/posts\/12972","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-json\/wp\/v2\/users\/86"}],"replies":[{"embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-json\/wp\/v2\/comments?post=12972"}],"version-history":[{"count":1,"href":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-json\/wp\/v2\/posts\/12972\/revisions"}],"predecessor-version":[{"id":130456,"href":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-json\/wp\/v2\/posts\/12972\/revisions\/130456"}],"wp:attachment":[{"href":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-json\/wp\/v2\/media?parent=12972"}],"wp:term":[{"taxonomy":"audience","embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-json\/wp\/v2\/audience?post=12972"},{"taxonomy":"content-type","embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-json\/wp\/v2\/content-type?post=12972"},{"taxonomy":"job-role","embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-json\/wp\/v2\/job-role?post=12972"},{"taxonomy":"product","embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-json\/wp\/v2\/product?post=12972"},{"taxonomy":"property","embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-json\/wp\/v2\/property?post=12972"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-json\/wp\/v2\/topic?post=12972"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/power-platform\/blog\/wp-json\/wp\/v2\/coauthors?post=12972"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}