{"id":2983144,"date":"2026-09-30T02:07:35","date_gmt":"2026-09-30T09:07:35","guid":{"rendered":"https:\/\/www.esri.com\/arcgis-blog\/?post_type=blog&#038;p=2983144"},"modified":"2026-09-30T02:07:35","modified_gmt":"2026-09-30T09:07:35","slug":"rethinking-application-migrations","status":"publish","type":"blog","link":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations","title":{"rendered":"Rethinking Application Migrations"},"author":354432,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","format":"standard","meta":{"_acf_changed":false,"_searchwp_excluded":""},"categories":[770712,738191],"tags":[781189,24921,27911],"industry":[],"product":[36831],"class_list":["post-2983144","blog","type-blog","status-publish","format-standard","hentry","category-geoai","category-developers","tag-agentic-ai","tag-javascript","tag-tutorial","product-js-api-arcgis"],"acf":{"authors":[{"ID":354432,"user_firstname":"Dagmara","user_lastname":"Pasiak","nickname":"Dagmara Pasiak","user_nicename":"dpasiak","display_name":"Dagmara Pasiak","user_email":"dpasiak@esri.com","user_url":"","user_registered":"2024-03-08 09:07:30","user_description":"","user_avatar":"<img alt='' src='https:\/\/secure.gravatar.com\/avatar\/1aff95728839c2e72ababc153ddcb464bc941705aeb2659f59b512866816414c?s=96&#038;d=blank&#038;r=g' srcset='https:\/\/secure.gravatar.com\/avatar\/1aff95728839c2e72ababc153ddcb464bc941705aeb2659f59b512866816414c?s=192&#038;d=blank&#038;r=g 2x' class='avatar avatar-96 photo' height='96' width='96' loading='lazy' decoding='async'\/>"},{"ID":26321,"user_firstname":"Sascha","user_lastname":"Brunner","nickname":"sbrunner","user_nicename":"sbrunner","display_name":"Sascha Brunner","user_email":"sbrunner@esri.com","user_url":"","user_registered":"2020-04-15 20:26:04","user_description":"","user_avatar":"<img alt='' src='https:\/\/secure.gravatar.com\/avatar\/9aff9e1fc3d82a5e9f73e29b461481fecf512006a4d49db0600d8c41fb0fd7e2?s=96&#038;d=blank&#038;r=g' srcset='https:\/\/secure.gravatar.com\/avatar\/9aff9e1fc3d82a5e9f73e29b461481fecf512006a4d49db0600d8c41fb0fd7e2?s=192&#038;d=blank&#038;r=g 2x' class='avatar avatar-96 photo' height='96' width='96' loading='lazy' decoding='async'\/>"}],"short_description":"Learn how to use AI to capture an existing application's requirements, recreate it using modern technologies, and validate the result.","flexible_content":[{"acf_fc_layout":"content","content":"<h1>Migrating&#8230; but Smarter This Time<\/h1>\n"},{"acf_fc_layout":"content","content":"<p><span data-contrast=\"auto\">Migrating applications can be time-consuming and repetitive, yet keeping them up to date is essential. Without regular modernization, years of investment can become increasingly difficult to maintain or may eventually be lost. This article shows how we used AI to capture an existing application&#8217;s requirements, recreate it using modern technologies, and validate the result.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">With the transition from widgets to components in version 5.x of the ArcGIS Maps SDK for JavaScript, we took the opportunity to modernize our showcase applications and ensure they reflect current development patterns and technologies. We explored how AI could help automate large parts of the process, freeing up more time to focus on work that creates new value.<\/span><span data-ccp-props=\"{&quot;134233117&quot;:false,&quot;134233118&quot;:false,&quot;201341983&quot;:0,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559685&quot;:0,&quot;335559737&quot;:0,&quot;335559738&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:279}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">Not every migration requires the same approach. If your application only needs a small refactor, a version update, or limited widget changes, it is often perfectly reasonable to build on top of the existing codebase. Larger migrations are a different story. When you are not only upgrading the SDK, but also changing frameworks, adopting a new architecture, or jumping across multiple major releases, incremental upgrades can become increasingly time consuming. In these situations, it may be more efficient to focus on capturing the application&#8217;s requirements and recreating it from scratch using the desired technologies.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">As with most migrations, there is no one-size-fits-all solution.<\/span> <span data-contrast=\"auto\">For complex projects, the decision is more nuanced and depends on both the scope of the migration and the complexity of the application itself. To compare different workflows, see the <a class=\"Hyperlink SCXW52772615 BCX8\" href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/ai-assisted-development\/\" target=\"_blank\" rel=\"noreferrer noopener\"><span class=\"TextRun Underlined SCXW52772615 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW52772615 BCX8\" data-ccp-charstyle=\"Hyperlink\">migration guides<\/span><\/span><\/a><\/span><span data-contrast=\"auto\">\u00a0available in the SDK documentation.<\/span><span data-ccp-props=\"{&quot;134233117&quot;:false,&quot;134233118&quot;:false,&quot;201341983&quot;:0,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559685&quot;:0,&quot;335559737&quot;:0,&quot;335559738&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:279}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">To show how large migrations work in practice, w<\/span><span data-contrast=\"auto\">e migrated the <\/span><a href=\"https:\/\/developers.arcgis.com\/javascript\/latest\/showcase\/building-viewer\/\"><span data-contrast=\"none\">Building Viewer<\/span><\/a><span data-contrast=\"auto\"> showcase by capturing its requirement and recreating the application from scratch. You can explore the new version here: <\/span><a href=\"https:\/\/esri.github.io\/building-viewer\/\"><span data-contrast=\"none\">Building Viewer<\/span><\/a><span data-contrast=\"auto\"> and compare it with the original version here: <\/span><a href=\"https:\/\/github.com\/Esri\/building-viewer\/tree\/version-4\"><span data-contrast=\"none\">building-viewer\/version-4.<\/span><\/a><span data-ccp-props=\"{&quot;134233117&quot;:false,&quot;134233118&quot;:false,&quot;201341983&quot;:0,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559685&quot;:0,&quot;335559737&quot;:0,&quot;335559738&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:279}\">\u00a0<\/span><\/p>\n"},{"acf_fc_layout":"image","image":{"ID":2983146,"id":2983146,"title":"Building Viewer App","filename":"building-viewer-scaled.png","filesize":2240191,"url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/building-viewer-scaled.png","link":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations\/building-viewer-2","alt":"Building Viewer App","author":"354432","description":"","caption":"Building Viewer Showcase","name":"building-viewer-2","status":"inherit","uploaded_to":2983144,"date":"2026-09-28 08:30:12","modified":"2026-09-28 10:54:12","menu_order":0,"mime_type":"image\/png","type":"image","subtype":"png","icon":"https:\/\/www.esri.com\/arcgis-blog\/wp-includes\/images\/media\/default.png","width":2560,"height":1387,"sizes":{"thumbnail":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/building-viewer-213x200.png","thumbnail-width":213,"thumbnail-height":200,"medium":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/building-viewer-scaled.png","medium-width":464,"medium-height":251,"medium_large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/building-viewer-scaled.png","medium_large-width":768,"medium_large-height":416,"large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/building-viewer-scaled.png","large-width":1920,"large-height":1040,"1536x1536":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/building-viewer-1536x832.png","1536x1536-width":1536,"1536x1536-height":832,"2048x2048":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/building-viewer-2048x1110.png","2048x2048-width":2048,"2048x2048-height":1110,"card_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/building-viewer-826x448.png","card_image-width":826,"card_image-height":448,"wide_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/building-viewer-1920x1040.png","wide_image-width":1920,"wide_image-height":1040}},"image_position":"center","orientation":"horizontal","hyperlink":""},{"acf_fc_layout":"content","content":"<h1>How we did it<\/h1>\n"},{"acf_fc_layout":"content","content":"<p><span data-contrast=\"auto\">The goal was to upgrade ArcGIS Maps SDK, move from Dojo\/Grunt to Vite, TypeScript and ArcGIS Components. Because several major changes were happening at once, recreating the application proved more practical than attempting a series of incremental upgrades.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">Throughout this process we used GitHub Copilot Chat in Visual Studio Code and a frontier model at the time (GPT-5.6), although the workflow itself is largely model and tool independent. What matters most is providing good context, clear instructions, and validating the results.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">The general process looked like this:<\/span><\/p>\n"},{"acf_fc_layout":"image","image":{"ID":2983147,"id":2983147,"title":"General migration process","filename":"Drawing-2026-08-28-11.05.28.excalidraw.png","filesize":34889,"url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/Drawing-2026-08-28-11.05.28.excalidraw.png","link":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations\/drawing-2026-08-28-11-05-28-excalidraw","alt":"General migration process diagram","author":"354432","description":"","caption":"","name":"drawing-2026-08-28-11-05-28-excalidraw","status":"inherit","uploaded_to":2983144,"date":"2026-09-28 10:56:55","modified":"2026-09-28 10:57:25","menu_order":0,"mime_type":"image\/png","type":"image","subtype":"png","icon":"https:\/\/www.esri.com\/arcgis-blog\/wp-includes\/images\/media\/default.png","width":848,"height":97,"sizes":{"thumbnail":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/Drawing-2026-08-28-11.05.28.excalidraw-213x97.png","thumbnail-width":213,"thumbnail-height":97,"medium":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/Drawing-2026-08-28-11.05.28.excalidraw.png","medium-width":464,"medium-height":53,"medium_large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/Drawing-2026-08-28-11.05.28.excalidraw.png","medium_large-width":768,"medium_large-height":88,"large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/Drawing-2026-08-28-11.05.28.excalidraw.png","large-width":848,"large-height":97,"1536x1536":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/Drawing-2026-08-28-11.05.28.excalidraw.png","1536x1536-width":848,"1536x1536-height":97,"2048x2048":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/Drawing-2026-08-28-11.05.28.excalidraw.png","2048x2048-width":848,"2048x2048-height":97,"card_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/Drawing-2026-08-28-11.05.28.excalidraw-826x94.png","card_image-width":826,"card_image-height":94,"wide_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/Drawing-2026-08-28-11.05.28.excalidraw.png","wide_image-width":848,"wide_image-height":97}},"image_position":"center","orientation":"horizontal","hyperlink":""},{"acf_fc_layout":"content","content":"<h2>Capture the requirements<\/h2>\n"},{"acf_fc_layout":"content","content":"<p><span data-contrast=\"auto\">The first step was creating a Product Requirements Document (PRD) describing the application&#8217;s functionality, interface, and behavior. Screenshots captured by the agent were particularly helpful because they provided visual context for UI states and interactions that would have been difficult to capture through text alone.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">The goal was to document what the application does rather than how it was implemented. This helped avoid carrying over legacy implementation details and allowed us to focus on recreating the same experience using modern technologies.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">We iterated on the PRD prompt several times to make it both useful for the AI and easy for humans to review. You can use the prompt below as a starting point for your own migration:<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n"},{"acf_fc_layout":"sidebar","content":"<p><em>Create a PRD from this codebase only. I want to rebuild the exact same application from scratch using new technology. Document all current functionality, user flows, interactions, UI behavior, states (visible data, zoom levels, etc.), and requirements needed to recreate it. Focus only on extracting and documenting what exists today. Do not suggest implementation details, architecture, timelines, technology choices, improvements, or redesigns. Clearly distinguish between verified behavior, assumptions, and unknowns.\u00a0<\/em><br \/>\n<em>\u00a0<\/em><br \/>\n<em>Use the integrated browser to run and test the application, not just inspect the source code. Include screenshots captured with Playwright throughout the document and place them in the relevant sections to illustrate views, workflows, dialogs, UI states, and important interactions.\u00a0<\/em><br \/>\n<em>\u00a0<\/em><br \/>\n<em>At the beginning of the document, include a &#8220;Non-Conclusive Findings&#8221; section listing anything that could not be verified from code inspection or runtime testing and must be specified manually. Immediately below, include a &#8220;Data &amp; Configuration Inventory&#8221; section containing:\u00a0<\/em><br \/>\n<em>&#8211; WebScene\/WebMap IDs and URLs\u00a0<\/em><br \/>\n<em>&#8211; Links\/URLs to referenced data sources and services\u00a0<\/em><br \/>\n<em>&#8211; Configuration values like descriptions, titles or file paths\u00a0<\/em><br \/>\n<em>&#8211; Any other discovered IDs, URLs, or externally referenced resources\u00a0<\/em><br \/>\n<em>\u00a0<\/em><br \/>\n<em>If you find anything that you think is broken in the current version of the app, ask if it should be recorded as it is in the current state or improved.<\/em><\/p>\n","image_reference":false,"layout":"standard","image_reference_figure":"","snippet":"","spotlight_name":"","section_title":"","position":"Center","spotlight_image":false},{"acf_fc_layout":"content","content":"<p><span class=\"TextRun SCXW179087691 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW179087691 BCX8\">You can check the PRD generated for our showcase here:<\/span> <\/span><a class=\"Hyperlink SCXW179087691 BCX8\" href=\"https:\/\/github.com\/Esri\/building-viewer\/blob\/main\/prd\/PRD.md\" target=\"_blank\" rel=\"noreferrer noopener\"><span class=\"TextRun Underlined SCXW179087691 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW179087691 BCX8\" data-ccp-charstyle=\"Hyperlink\">PRD<\/span><\/span><\/a><span class=\"TextRun SCXW179087691 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW179087691 BCX8\">.<\/span><\/span><span class=\"EOP Selected SCXW179087691 BCX8\" data-ccp-props=\"{&quot;134233117&quot;:false,&quot;134233118&quot;:false,&quot;201341983&quot;:0,&quot;335551550&quot;:1,&quot;335551620&quot;:1,&quot;335559685&quot;:0,&quot;335559737&quot;:0,&quot;335559738&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:279}\">\u00a0<\/span><\/p>\n"},{"acf_fc_layout":"content","content":"<h2><span class=\"TextRun SCXW95464792 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW95464792 BCX8\" data-ccp-parastyle=\"heading 2\">Recreate the application<\/span><\/span><span class=\"EOP Selected SCXW95464792 BCX8\" data-ccp-props=\"{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;335559738&quot;:160,&quot;335559739&quot;:80}\">\u00a0<\/span><\/h2>\n"},{"acf_fc_layout":"content","content":"<p><span class=\"TextRun SCXW199275426 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"auto\"><span class=\"NormalTextRun SCXW199275426 BCX8\">Using the PRD as a reference, we generated a completely new application based on the desired technology stack. Here is the prompt we used:<\/span><\/span><span class=\"EOP Selected SCXW199275426 BCX8\" data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n"},{"acf_fc_layout":"sidebar","content":"<p><em>Build the new app from the PRD and screenshots. Use @arcgis\/create with Vite (references: https:\/\/developers.arcgis.com\/javascript\/latest\/get-started\/#use-arcgiscreate,\u00a0 https:\/\/www.npmjs.com\/package\/@arcgis\/create). Do not update any existing files, create a separate folder with the new app.\u00a0<\/em><\/p>\n","image_reference":false,"layout":"standard","image_reference_figure":"","snippet":"","spotlight_name":"","section_title":"","position":"Center","spotlight_image":false},{"acf_fc_layout":"content","content":"<p><span class=\"NormalTextRun SCXW226924615 BCX8\">The <\/span><span class=\"NormalTextRun SCXW226924615 BCX8\">initial<\/span><span class=\"NormalTextRun SCXW226924615 BCX8\"> result got us surprisingly far. The main workflows were <\/span><span class=\"NormalTextRun SCXW226924615 BCX8\">in <\/span><span class=\"NormalTextRun SCXW226924615 BCX8\">place, <\/span><span class=\"NormalTextRun SCXW226924615 BCX8\">and the overall structure was correct, but many smaller details, especially map behavior, had been overlooked along the way.<\/span><\/p>\n<p><span data-contrast=\"auto\">To improve the results, we maintained an agent guidance file in the repository (<\/span><a href=\"https:\/\/github.com\/Esri\/building-viewer\/blob\/main\/.github\/copilot-instructions.md\"><span data-contrast=\"none\">.github\/copilot-instructions.md<\/span><\/a><span data-contrast=\"auto\"> and AGENTS.md in other environment). This Markdown file held reusable project context and working rules, separate from the task-specific prompts we entered in chat.\u00a0<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">After each review cycle, we updated the file to capture lessons from the generated code and application behavior. The guidance covered three areas:<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<ul>\n<li><span data-contrast=\"auto\">Agent workflow: project structure, validation, and keeping changes scoped. <\/span><span data-ccp-props=\"{&quot;335559685&quot;:720}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">JavaScript Maps SDK practices: current component-based patterns and official documentation.<\/span><span data-ccp-props=\"{&quot;335559685&quot;:720}\">\u00a0<\/span><\/li>\n<li><span data-contrast=\"auto\">Security considerations. <\/span><span data-ccp-props=\"{&quot;335559685&quot;:720}\">\u00a0<\/span><\/li>\n<\/ul>\n<p><span data-contrast=\"auto\">These updates addressed recurring issues from early migration attempts. For example, when the agent recreated existing map-component functionality using custom code or older widget-era patterns, we clarified that it should use the available map components. When a component such as the legend worked but differed from the original application, we clarified the expected placement, styling, and behavior. Recording these lessons as reusable agent guidance improved consistency across subsequent migration attempts.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n"},{"acf_fc_layout":"image","image":{"ID":2983151,"id":2983151,"title":"Screenshot of the migration process","filename":"Pasted-image-20260803142320.png","filesize":638572,"url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/Pasted-image-20260803142320.png","link":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations\/pasted-image-20260803142320","alt":"Screenshot of the migration process","author":"354432","description":"","caption":"Initial migration result showing a component with no styling applied ","name":"pasted-image-20260803142320","status":"inherit","uploaded_to":2983144,"date":"2026-09-28 11:08:31","modified":"2026-09-28 11:09:36","menu_order":0,"mime_type":"image\/png","type":"image","subtype":"png","icon":"https:\/\/www.esri.com\/arcgis-blog\/wp-includes\/images\/media\/default.png","width":2070,"height":1162,"sizes":{"thumbnail":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/Pasted-image-20260803142320-213x200.png","thumbnail-width":213,"thumbnail-height":200,"medium":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/Pasted-image-20260803142320.png","medium-width":464,"medium-height":261,"medium_large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/Pasted-image-20260803142320.png","medium_large-width":768,"medium_large-height":431,"large":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/Pasted-image-20260803142320.png","large-width":1920,"large-height":1078,"1536x1536":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/Pasted-image-20260803142320-1536x862.png","1536x1536-width":1536,"1536x1536-height":862,"2048x2048":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/Pasted-image-20260803142320-2048x1150.png","2048x2048-width":2048,"2048x2048-height":1150,"card_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/Pasted-image-20260803142320-826x465.png","card_image-width":826,"card_image-height":465,"wide_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/Pasted-image-20260803142320-1920x1078.png","wide_image-width":1920,"wide_image-height":1078}},"image_position":"center","orientation":"horizontal","hyperlink":""},{"acf_fc_layout":"content","content":"<p><span data-contrast=\"auto\">These experiments gave us a reusable starting point, although each application still needs its own review and refinement. You can use the instruction file as a starting point for your own migrations and focus your iterations on fixing application-specific issues rather than rediscovering the same SDK and workflow guidelines.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">You can read the full instructions and adapt them for your own project here: <a class=\"Hyperlink SCXW80082987 BCX8\" href=\"https:\/\/github.com\/Esri\/building-viewer\/blob\/main\/.github\/copilot-instructions.md\" target=\"_blank\" rel=\"noreferrer noopener\"><span class=\"TextRun Underlined SCXW80082987 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW80082987 BCX8\" data-ccp-charstyle=\"Hyperlink\">.github\/copilot-instructions.md<\/span><\/span><\/a><\/span><\/p>\n"},{"acf_fc_layout":"content","content":"<h2><span class=\"TextRun SCXW76399541 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW76399541 BCX8\" data-ccp-parastyle=\"heading 2\">Review and test<\/span><\/span><span class=\"EOP Selected SCXW76399541 BCX8\" data-ccp-props=\"{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;335559738&quot;:160,&quot;335559739&quot;:80}\">\u00a0<\/span><\/h2>\n"},{"acf_fc_layout":"content","content":"<p><span data-contrast=\"auto\">Validation is critical, even for an application that appears complete. We compared the original and new applications side by side to verify that functionality and behavior matched and there were no console errors.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">A good rule of thumb is that after the initial <em>create app<\/em> prompt, the generated application should already be fairly close to the original. If you&#8217;re still seeing major differences, it is often faster to improve the PRD, refine the project instructions, or use a recent frontier model capable of handling the application&#8217;s complexity than to keep iterating on a long list of fixes.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">Once we had refined both the PRD and the <\/span><span data-contrast=\"auto\">copilot-instructions<\/span><span data-contrast=\"auto\"> file, the Building Viewer application was already very close to the original. Only a few minor issues remained, which we documented for the agent and resolved within a few short iterations.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">A migration does not always have to be a perfect one-to-one copy of the original application. During the PRD creation process, we identified a few known issues in the existing application and explicitly noted that they should be fixed rather than reproduced. We also kept some minor UI changes because we preferred the updated experience and they did not affect the application&#8217;s core workflows.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n<p><span data-contrast=\"auto\">The closer your case gets to production use, the more important this review becomes. An application can look correct at first glance while still hiding technical issues or, more commonly, unnecessary complexity. For us, code clarity was especially important because showcases are designed as learning resources. After resolving the remaining bugs, we asked the agent to refactor parts of the application to use HTML templates instead of embedding large chunks of markup directly in TypeScript files, a pattern carried over from the previous TSX-based implementation. The original approach worked, but the refactored version was easier to understand and better reflected the practices we wanted developers to learn from.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/p>\n"},{"acf_fc_layout":"content","content":"<h1><span class=\"TextRun SCXW210385996 BCX8\" lang=\"EN-US\" xml:lang=\"EN-US\" data-contrast=\"none\"><span class=\"NormalTextRun SCXW210385996 BCX8\" data-ccp-parastyle=\"heading 1\">Lessons learned<\/span><\/span><span class=\"EOP Selected SCXW210385996 BCX8\" data-ccp-props=\"{&quot;134245418&quot;:true,&quot;134245529&quot;:true,&quot;335559738&quot;:360,&quot;335559739&quot;:80}\">\u00a0<\/span><\/h1>\n"},{"acf_fc_layout":"content","content":"<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"1\" data-aria-level=\"1\"><span data-contrast=\"auto\">Invest in good inputs. A well-defined PRD and clear project instructions had a bigger impact on the results than additional iterations and helped avoid mixing patterns from different SDK generations.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/li>\n<\/ul>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"2\" data-aria-level=\"1\"><span data-contrast=\"auto\">Treat the generated application as a starting point. Validate functionality and code quality until the result meets the same standards as a manually developed application.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/li>\n<\/ul>\n<ul>\n<li data-leveltext=\"\uf0b7\" data-font=\"Symbol\" data-listid=\"2\" data-list-defn-props=\"{&quot;335552541&quot;:1,&quot;335559685&quot;:720,&quot;335559991&quot;:360,&quot;469769226&quot;:&quot;Symbol&quot;,&quot;469769242&quot;:[8226],&quot;469777803&quot;:&quot;left&quot;,&quot;469777804&quot;:&quot;\uf0b7&quot;,&quot;469777815&quot;:&quot;hybridMultilevel&quot;}\" data-aria-posinset=\"3\" data-aria-level=\"1\"><span data-contrast=\"auto\">The recreated application did not always match the original implementation internally, and that was often a good thing. Modern SDK capabilities and components can replace large amounts of custom code, making the application simpler and easier to maintain. The goal should be to deliver the same user experience using current tools and SDK capabilities.<\/span><span data-ccp-props=\"{}\">\u00a0<\/span><\/li>\n<\/ul>\n"}],"related_articles":"","show_article_image":true,"card_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/Image-preview-1.png","wide_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/Image-preview.png"},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.9 (Yoast SEO v25.9) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Rethinking Application Migrations<\/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.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Rethinking Application Migrations\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations\" \/>\n<meta property=\"og:site_name\" content=\"ArcGIS Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/esrigis\/\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:site\" content=\"@ESRI\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data1\" content=\"8 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":[\"Article\",\"BlogPosting\"],\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations\"},\"author\":{\"name\":\"Dagmara Pasiak\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/f3e58e9d975d390d246956f37f92dea7\"},\"headline\":\"Rethinking Application Migrations\",\"datePublished\":\"2026-09-30T09:07:35+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations\"},\"wordCount\":3,\"publisher\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#organization\"},\"keywords\":[\"agentic AI\",\"JavaScript\",\"Tutorial\"],\"articleSection\":[\"AI\",\"Developers\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations\",\"name\":\"Rethinking Application Migrations\",\"isPartOf\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#website\"},\"datePublished\":\"2026-09-30T09:07:35+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.esri.com\/arcgis-blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Rethinking Application Migrations\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#website\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/\",\"name\":\"ArcGIS Blog\",\"description\":\"Get insider info from Esri product teams\",\"publisher\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.esri.com\/arcgis-blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#organization\",\"name\":\"Esri\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2018\/04\/Esri.png\",\"contentUrl\":\"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2018\/04\/Esri.png\",\"width\":400,\"height\":400,\"caption\":\"Esri\"},\"image\":{\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.facebook.com\/esrigis\/\",\"https:\/\/x.com\/ESRI\",\"https:\/\/www.linkedin.com\/company\/5311\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/f3e58e9d975d390d246956f37f92dea7\",\"name\":\"Dagmara Pasiak\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/1aff95728839c2e72ababc153ddcb464bc941705aeb2659f59b512866816414c?s=96&d=blank&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/1aff95728839c2e72ababc153ddcb464bc941705aeb2659f59b512866816414c?s=96&d=blank&r=g\",\"caption\":\"Dagmara Pasiak\"},\"sameAs\":[\"https:\/\/www.linkedin.com\/in\/dagmara-pasiak\"],\"url\":\"\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Rethinking Application Migrations","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.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations","og_locale":"en_US","og_type":"article","og_title":"Rethinking Application Migrations","og_url":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations","og_site_name":"ArcGIS Blog","article_publisher":"https:\/\/www.facebook.com\/esrigis\/","twitter_card":"summary_large_image","twitter_site":"@ESRI","twitter_misc":{"Est. reading time":"8 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":["Article","BlogPosting"],"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations#article","isPartOf":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations"},"author":{"name":"Dagmara Pasiak","@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/f3e58e9d975d390d246956f37f92dea7"},"headline":"Rethinking Application Migrations","datePublished":"2026-09-30T09:07:35+00:00","mainEntityOfPage":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations"},"wordCount":3,"publisher":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/#organization"},"keywords":["agentic AI","JavaScript","Tutorial"],"articleSection":["AI","Developers"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations","url":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations","name":"Rethinking Application Migrations","isPartOf":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/#website"},"datePublished":"2026-09-30T09:07:35+00:00","breadcrumb":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.esri.com\/arcgis-blog\/"},{"@type":"ListItem","position":2,"name":"Rethinking Application Migrations"}]},{"@type":"WebSite","@id":"https:\/\/www.esri.com\/arcgis-blog\/#website","url":"https:\/\/www.esri.com\/arcgis-blog\/","name":"ArcGIS Blog","description":"Get insider info from Esri product teams","publisher":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.esri.com\/arcgis-blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.esri.com\/arcgis-blog\/#organization","name":"Esri","url":"https:\/\/www.esri.com\/arcgis-blog\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2018\/04\/Esri.png","contentUrl":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2018\/04\/Esri.png","width":400,"height":400,"caption":"Esri"},"image":{"@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/esrigis\/","https:\/\/x.com\/ESRI","https:\/\/www.linkedin.com\/company\/5311\/"]},{"@type":"Person","@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/f3e58e9d975d390d246956f37f92dea7","name":"Dagmara Pasiak","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.esri.com\/arcgis-blog\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/1aff95728839c2e72ababc153ddcb464bc941705aeb2659f59b512866816414c?s=96&d=blank&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/1aff95728839c2e72ababc153ddcb464bc941705aeb2659f59b512866816414c?s=96&d=blank&r=g","caption":"Dagmara Pasiak"},"sameAs":["https:\/\/www.linkedin.com\/in\/dagmara-pasiak"],"url":""}]}},"text_date":"September 30, 2026","author_name":"Multiple Authors","author_page":"https:\/\/www.esri.com\/arcgis-blog\/products\/js-api-arcgis\/geoai\/rethinking-application-migrations","custom_image":"https:\/\/www.esri.com\/arcgis-blog\/app\/uploads\/2026\/09\/Image-preview.png","primary_product":"ArcGIS Maps SDK for JavaScript","tag_data":[{"term_id":781189,"name":"agentic AI","slug":"agentic-ai","term_group":0,"term_taxonomy_id":781189,"taxonomy":"post_tag","description":"","parent":0,"count":4,"filter":"raw"},{"term_id":24921,"name":"JavaScript","slug":"javascript","term_group":0,"term_taxonomy_id":24921,"taxonomy":"post_tag","description":"","parent":0,"count":152,"filter":"raw"},{"term_id":27911,"name":"Tutorial","slug":"tutorial","term_group":0,"term_taxonomy_id":27911,"taxonomy":"post_tag","description":"","parent":0,"count":187,"filter":"raw"}],"category_data":[{"term_id":770712,"name":"AI","slug":"geoai","term_group":0,"term_taxonomy_id":770712,"taxonomy":"category","description":"","parent":0,"count":80,"filter":"raw"},{"term_id":738191,"name":"Developers","slug":"developers","term_group":0,"term_taxonomy_id":738191,"taxonomy":"category","description":"","parent":0,"count":461,"filter":"raw"}],"product_data":[{"term_id":36831,"name":"ArcGIS Maps SDK for JavaScript","slug":"js-api-arcgis","term_group":0,"term_taxonomy_id":36831,"taxonomy":"product","description":"","parent":36601,"count":373,"filter":"raw"}],"primary_product_link":"https:\/\/www.esri.com\/arcgis-blog\/?s=#&products=js-api-arcgis","_links":{"self":[{"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/blog\/2983144","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/blog"}],"about":[{"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/types\/blog"}],"author":[{"embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/users\/354432"}],"replies":[{"embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/comments?post=2983144"}],"version-history":[{"count":13,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/blog\/2983144\/revisions"}],"predecessor-version":[{"id":2983269,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/blog\/2983144\/revisions\/2983269"}],"wp:attachment":[{"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/media?parent=2983144"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/categories?post=2983144"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/tags?post=2983144"},{"taxonomy":"industry","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/industry?post=2983144"},{"taxonomy":"product","embeddable":true,"href":"https:\/\/www.esri.com\/arcgis-blog\/wp-json\/wp\/v2\/product?post=2983144"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}