To offer a better and more integrated development experience, apps created using Shopify CLI 3.x follow a conventional directory structure, use simplified configuration files, and manage your Node-based dependencies for you. If you have an app that was created using a previous version of Shopify CLI, or you’ve created an app from scratch, then you can use this migration guide to update your app to be compatible with the newest CLI version. This process involves reorganizing your app's folder structure and adding configurations that tell Shopify CLI how your app is organized. ## Requirements - You've installed [Shopify CLI](/docs/api/shopify-cli) - The latest version of [Chrome](https://www.google.com/chrome/) or [Firefox](https://www.mozilla.org/) ## What you'll learn In this tutorial, you'll learn the following: - How to create CLI-specific configuration files for your project - How to migrate your app code > Tip: > If you want to keep the Git history for your project, then you should update your app in the current root directory instead of creating a new directory. ## Benefits of migration When you migrate your app to use Shopify CLI 3.x, you can take advantage of the following improvements to the developer experience: ### Conventional directory structure To offer a better and more integrated development experience, apps built using Shopify CLI 3.x follow a [conventional directory structure](/docs/apps/build/cli-for-apps/app-structure#directory-structure). This structure allows you to serve and deploy your app and its [app extensions](/docs/apps/build/app-extensions) at the same time, and generate new app extensions easily. ### Simplified configuration files To make reading and editing configuration files easier, apps that use Shopify CLI 3.x use [TOML](https://toml.io/en/) instead of YAML. Only a small set of files and settings are required, so configurations can be made and tracked in fewer files, and fewer manual configurations need to be made. ### Node runtime The Shopify CLI 3.x is implemented in JavaScript to run in the Node runtime, more closely aligning the Shopify CLI and app development experience. ## Web component conventions Shopify CLI builds and serves the various parts of your app using the following conventions, some of which use information that is defined in configuration files. ### Single process or frontend process The following conventions apply to apps that run on a single process, such as standard Rails apps, and to the frontend process of apps that have both a frontend and backend process. #### Configuration The CLI expects at least one [`shopify.web.toml` configuration file](#shopify-web-toml), with `roles` including `frontend`, or with no type/roles specified. This file can be at the root of the project, or in a project subdirectory. In the case of a single-process app, include `backend` in the list of roles as well. To explicitly specify the folders where Shopify CLI should look for `shopify.web.toml` files, and to avoid files being loaded twice due to symlinks, use the `web_directories` variable in the [`shopify.app.toml`](/docs/apps/build/cli-for-apps/app-structure#root-configuration-files) file. #### Provided variables The following information is provided to the process as environment variables: - `SHOPIFY_API_KEY`: The client ID of the app. - `SHOPIFY_API_SECRET`: The client secret of the app. - `HOST`/`APP_URL`: The URL that stores will load. - `PORT`/`FRONTEND_PORT`/`SERVER_PORT`: The port in which the process’ server should run. - `SCOPES`: The app's access scopes. - `BACKEND_PORT`: The port in which the second, or backend, process will run if the app is a two-process app. The frontend uses 'BACKEND_PORT' to proxy traffic to the backend process. ### Second process or backend process The following conventions apply to the backend process of two-process apps, or to single-process apps. #### Configuration The CLI expects a [`shopify.web.toml` configuration file](#shopify-web-toml) in any subdirectory of the project, with `roles` including `backend`. The frontend must proxy backend requests to the backend port defined in the environment variable `BACKEND_PORT`. #### Provided variables The following information will be provided as environment variables to the process: - `SHOPIFY_API_KEY`: The client ID of the app. - `SHOPIFY_API_SECRET`: The client secret of the app. - `HOST`/`APP_URL`: The URL that stores will load. - `SERVER_PORT`/`BACKEND_PORT`/`PORT`: The port in which the process’s server should run. - `SCOPES`: The app's access scopes. - `FRONTEND_PORT`: The port in which the frontend process will run. ### Background process You can also specify additional processes that will run in the background and don't require the behavior of frontend or backend processes. This can be useful for service-oriented architectures or custom file-watcher processes. #### Configuration The CLI accepts a [`shopify.web.toml` configuration file](#shopify-web-toml) in any subdirectory of the project, with `roles = ["background"]`. #### Provided variables The following information will be provided as environment variables to the process: - `SHOPIFY_API_KEY`: The client ID of the app. - `SHOPIFY_API_SECRET`: The client secret of the app. - `HOST`/`APP_URL`: The URL that stores will load. - `SERVER_PORT`/`PORT`: The port in which the process’s server should run, if the process includes a server. - `SCOPES`: The app's access scopes. - `FRONTEND_PORT`: The port in which the frontend process will run. - `BACKEND_PORT`: The port in which the second, or backend, process will run, if the app has a backend. ## Step 1: Migrate your embedded app Your embedded or web app components can be stored at the root of the project, or any subdirectory that contains a `shopify.web.toml` file. We recommend that you store files for your embedded app under `web/` :

If you choose to migrate using a `web/` directory or another new subdirectory, then you need to move your embedded app source code, tests, configuration files, and dependency files to this directory. This includes your `package.json` or your `Gemfile`, the entry `index.html` file, and any vite or webpack config files. Only files that are scoped to the project should remain outside of this subdirectory. This might include files like READMEs, Visual Studio Code configuration files, or CI pipelines. The steps that you need to follow depend on your project language: - [Node.js or Rails](#node-js-or-rails) - [PHP](#php) If your app only contains app extensions, then you can skip this step. > Tip: > To explicitly specify the folders where Shopify CLI should look for `shopify.web.toml` files, and to avoid files being loaded twice due to symlinks, use the `web_directories` variable in the [`shopify.app.toml`](/docs/apps/build/cli-for-apps/app-structure#root-configuration-files) file. ### Node.js or Rails Create a `shopify.web.toml` configuration file with content for your project language:


The `dev` command instructs the CLI on how to serve the project. The value might differ depending on how the process is invoked in the project. For example, you might need to use `bundle exec rails serve` if you don’t have a Rails binstub, or `pnpm run dev` if you have a Node project with pnpm as a package manager. ### PHP Create two `shopify.web.toml` configuration files, one for the frontend and one for the backend:

### App hosting At runtime, the CLI will expose the variables that you'll need to set up your app. These include `SHOPIFY_API_KEY`, `SHOPIFY_API_SECRET`, `SCOPES`, and `HOST`. Refer to the [Shopify starter Node app](https://github.com/Shopify/shopify-app-template-node/blob/b8745a80d7fc6f135c834e35628d5824a32ee1e7/server/index.js#L17) for an example of the setup in a Node app using the `@shopify/shopify-api` npm package. ## Step 2: Create a root configuration file Create a [`shopify.app.toml`](/docs/apps/build/cli-for-apps/app-structure#root-configuration-files) file in your app’s root directory. `shopify.app.toml` is a configuration file that contains app-level configurations and metadata. This file also helps Shopify CLI determine whether the directory represents a Shopify app. The TOML should contain the following information: - `name`: The name of your app. - `scopes`: If you're migrating an embedded app, then enter the value of the `SCOPES` attribute of your `.env` file. If your app contains only app extensions, then you don't need to include the `scopes` in this file.

## Step 3: Connect your app to the Partner Dashboard Run the [`dev`](/docs/api/shopify-cli/app/app-dev) command to log in to your Partner account, connect your app to your existing app in the Partner Dashboard, and view the embedded app on a development store using a tunnel:

## Step 4: Connect your app extensions For your app to work with Shopify CLI, you need to update how your app extensions are organized in your project. If your app doesn’t have app extensions, then you can skip this step. Follow the steps below for each app extension that's included in your app. For more information about the expected format of each extension, refer to [Extensions](/docs/apps/build/cli-for-apps/app-structure#extensions). ### Step 4A: Reorganize or point to your app extensions In the default Shopify CLI 3.x [app directory structure](/docs/apps/build/cli-for-apps/app-structure#directory-structure), each subdirectory under `extensions/` represents a single app extension. The `extensions/` directory is also where new app extensions are created.


For Shopify CLI to find your app extensions, you can do one of two things: - Move the files for each of your app extensions to an `extensions/` subdirectory. - Point to the location of each of your extensions in `shopify.app.toml`. > Note: > For checkout post-purchase extensions, Shopify CLI expects an extension script named `index.{ts,js,tsx,jsx}` to exist in the extension’s directory or the `src/` subdirectory. #### Option 1: Move app extension files to the default directory 1. Navigate to your app directory. 2. If you haven't done so already, create an `extensions/` subdirectory. 3. Under `extensions/`, create a new subdirectory for your extension. 4. Move the extension files to your new subdirectory. #### Option 2: Point to the locations of your app extensions If you don't want to store your app extensions in the `extensions/` subdirectory, then you can specify the directory where each app extension is stored using the `extension_directories` variable in `shopify.app.toml`. You can use a glob pattern to point to directories that contain extensions:

### Step 5B: Update package.json files You need to remove prerequisites and workflows that have been replaced by Shopify CLI. 1. Use your package manager to delete the following dependencies: - `@shopify/admin-ui-extensions-run` - `@shopify/checkout-ui-extensions-run` - `@shopify/shopify-cli-extensions`

2. In your `package.json` files, remove the following scripts: - `build` - `server` - `start` ### Step 5C: Reorganize your dependencies Shopify CLI enables you to manage your npm dependencies multiple ways. You can store all of your dependencies in the root `package.json` file, or you can use your package manager's workspaces functionality. Using workspaces is recommended, and is the default used by Shopify CLI. If you decide to use the root `package.json` as the source of truth for dependencies, then you need to move the extension’s `dependencies` and `devDependencies` from your extension's `package.json` to the root `package.json`. If the extension’s `package.json` has `typescript`, `eslint`, and `prettier` dependencies, then you should also move them to the app’s root `package.json` so the same dependency version is shared across all of the extensions in the app. If you decide to make TypeScript, ESLint, or Prettier dependencies of your entire app, then you should also move the following configuration files if they're present: - Typescript: `tsconfig.json` - ESLint: `.eslintrc.*`, or the `eslintConfig` attribute from the `package.json` - Prettier: `.prettierrc` After you reorganize your dependencies, run your package manager's `install` command to install the dependencies, and then make sure that there are no incompatibilities in the dependency graph. ### Step 5D: Migrate your configurations to TOML files Shopify CLI 3.x uses TOML files instead of YAML files and, in some cases, `.env` files. The following steps vary depending on the type of extension. #### Theme app extensions If you're migrating a theme app extension, then do the following: 1. Create a `shopify.extension.toml` in the extension’s directory. The TOML should contain the following information: - `name`: The name of your app extension. `name` should match the `EXTENSION_TITLE` from your extension's `.env` file. - `type`: Enter `theme`.

2. Optional: delete any remaining `.env`, `extension.config.yml`, and `.shopify-cli.yml` files. #### UI extensions (checkout post-purchase) If you're migrating a checkout post-purchase extension, then do the following: 1. Create a `shopify.extension.toml` in the extension’s directory. The TOML should contain the following information: - `name`: The name of your app extension. `name` should match the `EXTENSION_TITLE` from your extension's `.env` file. - `type`: Enter `checkout_post_purchase`.

2. If the extension’s `extension.config.yml` has additional attributes besides `type` and `name`, then convert them to TOML using [a YAML to TOML converter](https://www.convertsimple.com/convert-yaml-to-toml/), and then add them to the `shopify.extension.toml`. 3. If the extension's `.env` file has any user-defined variables, then move them to the root `.env` file of the app. 4. Optional: delete any remaining `.env`, `extension.config.yml`, and `.shopify-cli.yml` files. ### Step 5E: Verify the extension 1. Run the [`info`](/docs/api/shopify-cli/app/app-info) command to verify that each extension subdirectory is recognized by Shopify CLI:

2. Run the [`dev`](/docs/api/shopify-cli/app/app-dev) command to open the embedded app on a development store. If you haven't logged into your Partner account or connected your app to an app in the Partner Dashboard, then you'll be prompted to do so in this step.

3. Run the [`deploy`](/docs/api/shopify-cli/app/app-deploy) command to deploy your app extension code to Shopify. When you run this command, Shopify CLI creates an app version that contains a snapshot of all of your app extensions, including the app extensions that you manage in the Partner Dashboard, and releases the app version to users.