10680b787SAman Mittal--- 20680b787SAman Mittaltitle: Tools, workflows and extensions 30680b787SAman Mittalsidebar_title: Tools, workflows and extensions 40680b787SAman Mittaldescription: Learn more about different tools, workflows and extensions available when working with development builds. 50680b787SAman Mittal--- 60680b787SAman Mittal 70680b787SAman Mittalimport ImageSpotlight from '~/components/plugins/ImageSpotlight'; 80680b787SAman Mittalimport { Terminal } from '~/ui/components/Snippet'; 90680b787SAman Mittalimport { Tab, Tabs } from '~/ui/components/Tabs'; 100680b787SAman Mittal 110680b787SAman MittalDevelopment builds allow you to iterate quickly. However, you can extend the capabilities of your development build to provide a better developer experience when working in teams or customize the build to suit your needs. 120680b787SAman Mittal 130680b787SAman Mittal## Tools 140680b787SAman Mittal 150680b787SAman Mittal### Tunnel URLs 160680b787SAman Mittal 170680b787SAman MittalSometimes, restrictive network conditions make it difficult to connect to the development server. The `npx expo start` command exposes your development server on a publicly available URL that is accessible through firewalls from around the globe. This option is helpful if you are not able to connect to your development server with the default LAN option or if you want to get feedback on your implementation while you are developing. 180680b787SAman Mittal 19d92bb961SAman MittalTo get a tunneled URL, pass the `--tunnel` flag to `npx expo start` from the command line. For more information, see [Tunneling](/more/expo-cli/#tunneling). 200680b787SAman Mittal 210680b787SAman Mittal### Published updates 220680b787SAman Mittal 230680b787SAman MittalEAS CLI's `eas update` command bundles the current state of your JavaScript and asset files into an optimized "update". This update is stored on a hosting service by Expo. A development build of your app can load published updates without needing to check out a particular commit or leave a development machine running. 240680b787SAman Mittal 250680b787SAman Mittal### Manually entering an update's URL 260680b787SAman Mittal 270680b787SAman MittalWhen a development build launches, it will expose UI to load a development server, or to "Enter URL manually". You can provide a URL manually that will launch a specific branch. The URL follows this pattern: 280680b787SAman Mittal 290680b787SAman Mittal``` 300680b787SAman Mittalhttps://u.expo.dev/[your-project-id]?channel-name=[channel-name] 310680b787SAman Mittal 320680b787SAman Mittal# Example 330680b787SAman Mittalhttps://u.expo.dev/F767ADF57-B487-4D8F-9522-85549C39F43F?channel-name=main 340680b787SAman Mittal``` 350680b787SAman Mittal 3619498846SAman MittalTo get your project's ID, use the URL in the [app config's `expo.updates.url`](/versions/latest/config/app/#url) field. To see a list of channels, run `eas channel:list`. 370680b787SAman Mittal 380680b787SAman Mittal{/* TODO: @aman move this section out of this page -- make it part of the main path or a standalone guide, this is important part that should be searchable for eg: Deep linking URLs for Development builds/EAS Builds (when using expo-dev-client) */} 390680b787SAman Mittal 400680b787SAman Mittal### Deep linking URLs 410680b787SAman Mittal 420680b787SAman MittalYou can load your app on a device that has a compatible build of your custom client by opening a URL of the form `{scheme}://expo-development-client/?url={manifestUrl}`. You'll need to pass the following parameters: 430680b787SAman Mittal 440680b787SAman Mittal| parameter | value | 4519498846SAman Mittal| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | 4619498846SAman Mittal| `scheme` | URL scheme of your client (defaults to `exp+{slug}` where [`slug`](/versions/latest/config/app/#slug) is the value set in the app config) | 470680b787SAman Mittal| `manifestUrl` | URL-encoded URL of an update manifest to load. The URL will be `https://u.expo.dev/[your-project-id]?channel-name=[channel-name]` | 480680b787SAman Mittal 490680b787SAman MittalExample: 500680b787SAman Mittal 510680b787SAman Mittal``` 520680b787SAman Mittalexp+app-slug://expo-development-client/?url=https%3A%2F%2Fu.expo.dev%2F767ADF57-B487-4D8F-9522-85549C39F43F%2F%3Fchannel-name%3Dmain 530680b787SAman Mittal``` 540680b787SAman Mittal 550680b787SAman MittalIn the example above, the `scheme` is `exp+app-slug`, and the `manifestUrl` is a project with an ID of `F767ADF57-B487-4D8F-9522-85549C39F43F` and a channel of `main`. 560680b787SAman Mittal 57*a16ac082SAman Mittal### QR codes 580680b787SAman Mittal 590680b787SAman MittalYou can use our endpoint to generate a QR code that can be easily loaded by a development build. 600680b787SAman Mittal 610680b787SAman MittalRequests send to `https://qr.expo.dev/development-client` when supplied the query parameters such as `appScheme` and `url` will receive a response with an SVG image containing a QR code that can be easily scanned to load a version of your project in your development build. 620680b787SAman Mittal 630680b787SAman Mittal| parameter | value | 6419498846SAman Mittal| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | 6519498846SAman Mittal| `appScheme` | URL-encoded deeplinking scheme of your development build (defaults to `exp+{slug}` where [`slug`](/versions/latest/config/app/#slug) is the value set in the app config) | 660680b787SAman Mittal| `url` | URL-encoded URL of an update manifest to load. The URL will be `https://u.expo.dev/[your-project-id]?channel-name=[channel-name]` | 670680b787SAman Mittal 680680b787SAman MittalExample: 690680b787SAman Mittal 700680b787SAman Mittal``` 710680b787SAman Mittalhttps://qr.expo.dev/development-client?appScheme=exp%2Bapps-slug&url=https%3A%2F%2Fu.expo.dev%2FF767ADF57-B487-4D8F-9522-85549C39F43F0%3Fchannel-name%3Dmain 720680b787SAman Mittal``` 730680b787SAman Mittal 740680b787SAman MittalIn the example above, the `scheme` is `exp+app-slug`, and the `url` is a project with an ID of `F767ADF57-B487-4D8F-9522-85549C39F43F` and a channel of `main`. 750680b787SAman Mittal 760680b787SAman Mittal## Example workflows 770680b787SAman Mittal 780680b787SAman MittalThese are a few examples of workflows to help your team get the most out of your development build. If you come up with others that would be useful for other teams, please [submit a PR](https://github.com/expo/expo/tree/main/CONTRIBUTING.md#-updating-documentation) to share your knowledge! 790680b787SAman Mittal 800680b787SAman Mittal### PR previews 810680b787SAman Mittal 822c0ba911SKeith KurakYou can set up your CI process to publish an EAS Update whenever a pull request is updated and add a QR code that is used to view the change in a compatible development build. 830680b787SAman Mittal 842c0ba911SKeith KurakSee [instructions for publishing app previews on pull requests](/eas-update/github-actions/#publish-previews-on-pull-requests) to implement this workflow in your project using GitHub Actions or serve as a template in your CI of choice. 850680b787SAman Mittal 860680b787SAman Mittal## Extensions 870680b787SAman Mittal 880680b787SAman MittalExtensions allow you to extend your development client with additional capabilities. 890680b787SAman Mittal 900680b787SAman Mittal### Extending the dev menu 910680b787SAman Mittal 920680b787SAman MittalThe dev menu can be extended to include extra buttons by using the `registerDevMenuItems` API: 930680b787SAman Mittal 940680b787SAman Mittal```tsx 950680b787SAman Mittalimport { registerDevMenuItems } from 'expo-dev-menu'; 960680b787SAman Mittal 970680b787SAman Mittalconst devMenuItems = [ 980680b787SAman Mittal { 990680b787SAman Mittal name: 'My Custom Button', 1000680b787SAman Mittal callback: () => console.log('Hello world!'), 1010680b787SAman Mittal }, 1020680b787SAman Mittal]; 1030680b787SAman Mittal 1040680b787SAman MittalregisterDevMenuItems(devMenuItems); 1050680b787SAman Mittal``` 1060680b787SAman Mittal 1070680b787SAman MittalThis will create a new section in the dev menu that includes the buttons you have registered: 1080680b787SAman Mittal 1090680b787SAman Mittal<ImageSpotlight 1100680b787SAman Mittal alt="An example of a custom menu button in expo-dev-menu" 1110680b787SAman Mittal src="/static/images/dev-client/custom-menu-button.png" 1120680b787SAman Mittal style={{ maxWidth: 400 }} 1130680b787SAman Mittal/> 1140680b787SAman Mittal 1150680b787SAman Mittal> Subsequent calls of `registerDevMenuItems` will override all previous entries. 1160680b787SAman Mittal 1170680b787SAman Mittal### EAS Update 1180680b787SAman Mittal 1190680b787SAman Mittal<ImageSpotlight 1200680b787SAman Mittal alt="An example list of EAS Update that can be loaded in the expo-dev-client." 1210680b787SAman Mittal src="/static/images/dev-client/eas-updates-screen.png" 1220680b787SAman Mittal style={{ maxWidth: 400 }} 1230680b787SAman Mittal/> 1240680b787SAman Mittal 1250680b787SAman MittalThe EAS Update extension provides the ability to view and load published updates in your development client. 1260680b787SAman Mittal 1277ae0ec0dSAman MittalIt's available for all development clients `v0.9.0` and above. To install it, you'll need the most recent publish of `expo-updates`: 1280680b787SAman Mittal 1290680b787SAman Mittal<Terminal cmd={['$ npx expo install expo-dev-client expo-updates']} /> 1300680b787SAman Mittal 1310680b787SAman Mittal#### Configure EAS Update 1320680b787SAman Mittal 1330680b787SAman MittalIf you have not yet configured EAS Updates in your project, you can find [additional instructions on how to do so here.](/eas-update/getting-started/) 1340680b787SAman Mittal 1350680b787SAman MittalYou can now view and load EAS Updates in your development build via the `Extensions` panel. 1360680b787SAman Mittal 13719498846SAman Mittal## Set runtimeVersion in app config 1380680b787SAman Mittal 1397ae0ec0dSAman MittalWhen you create a development build of your project, you'll get a stable environment to load any changes to your app that are defined in JavaScript or other asset-related changes. Other changes to your app, whether defined directly in **android** and **ios** directories or by packages or SDKs you choose to install, will require you to create a new build of your development build. 1400680b787SAman Mittal 14119498846SAman MittalTo enforce an API contract between the JavaScript and native layers of your app, you should set the [`runtimeVersion`](/distribution/runtime-versions) value in the app config. Each build you make will have this value embedded and will only load bundles with the same `runtimeVersion`, in both development and production. 142