{"id":2147,"date":"2016-05-26T18:55:34","date_gmt":"2016-05-26T18:55:34","guid":{"rendered":"https:\/\/www.microsoft.com\/reallifecode\/index.php\/2016\/05\/26\/creating-universal-windows-apps-with-react-native\/"},"modified":"2020-03-15T07:26:33","modified_gmt":"2020-03-15T14:26:33","slug":"creating-universal-windows-apps-with-react-native","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/ise\/creating-universal-windows-apps-with-react-native\/","title":{"rendered":"Creating Universal Windows Apps with React Native"},"content":{"rendered":"<p><a href=\"https:\/\/facebook.github.io\/react\/\">React.js<\/a> is a popular JavaScript library for building reusable UI components. <a href=\"https:\/\/facebook.github.io\/react-native\">React Native<\/a> takes all the great features of React, from the one-way binding and virtual DOM to <a href=\"http:\/\/facebook.github.io\/react-native\/docs\/debugging.html\">debugging tools<\/a>, and applies them to mobile app development on iOS and Android. With the React Native Universal Windows platform extension, you can now make your React Native applications run on the Universal Windows family of devices, including desktop, mobile, and Xbox, as well as Windows IoT, Surface Hub, and HoloLens.<\/p>\n<p>This code story will walk you through the process of setting up a Universal Windows project for React Native, importing core Windows-specific modules to your JavaScript components, and running the app with Visual Studio.<\/p>\n<h1 id=\"installing-react-native-for-windows\">Installing React Native for Windows<\/h2>\n<p>Installing the React Native Universal Windows platform extension is easy, whether you want to add the Windows platform to your existing app, or you want to start from scratch building an app just for Windows.<\/p>\n<h2 id=\"adding-react-native-for-windows-to-existing-projects\">Adding React Native for Windows to Existing Projects<\/h2>\n<p>React Native developers are probably familiar with the <a href=\"https:\/\/www.npmjs.com\/package\/react-native-cli\">react-native-cli<\/a>, a tool for initializing React Native projects, deploying apps to devices, capturing JavaScript logs, upgrading versions, etc.<\/p>\n<p>To start, make sure you have <code class=\"highlighter-rouge\">react-native-cli<\/code> installed globally.<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>npm install -g react-native-cli\r\n<\/code><\/pre>\n<\/div>\n<p>Once <code class=\"highlighter-rouge\">react-native-cli<\/code> is installed, install the Windows plugin for React Native. The Windows plugin will expose new commands to the <code class=\"highlighter-rouge\">react-native-cli<\/code>, specifically the <code class=\"highlighter-rouge\">react-native windows<\/code> command, which you will use to initialize your project.<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>npm install --save-dev rnpm-plugin-windows\r\nreact-native windows\r\n<\/code><\/pre>\n<\/div>\n<p>The <code class=\"highlighter-rouge\">windows<\/code> command will do the following:<\/p>\n<ul>\n<li>Install <code class=\"highlighter-rouge\">react-native-windows<\/code> from <a href=\"https:\/\/www.npmjs.com\/package\/react-native-windows\">NPM<\/a><\/li>\n<li>Read the name of your project from <code class=\"highlighter-rouge\">package.json<\/code><\/li>\n<li>Use <a href=\"http:\/\/yeoman.io\/\">Yeoman<\/a> to generate the Windows project files.<\/li>\n<\/ul>\n<p>The <code class=\"highlighter-rouge\">react-native-cli<\/code> plugin architecture searches your local package.json <code class=\"highlighter-rouge\">dependencies<\/code> and <code class=\"highlighter-rouge\">devDependencies<\/code> for modules that match <code class=\"highlighter-rouge\">rnpm-plugin-*<\/code>, hence the <code class=\"highlighter-rouge\">--save-dev<\/code> above.<\/p>\n<p>Head to <a href=\"http:\/\/github.com\/ReactWindows\/react-native-windows\/tree\/master\/local-cli\/rnpm\">GitHub<\/a> for more information on <code class=\"highlighter-rouge\">rnpm-plugin-windows<\/code>.<\/p>\n<h2 id=\"creating-a-react-native-for-windows-project-from-scratch\">Creating a React Native for Windows Project from Scratch<\/h2>\n<p>You have a few different options to create a React Native Universal Windows project from scratch. If your eventual intent is to also build apps for iOS and Android from the same code base, then the recommendation is first to use the <a href=\"https:\/\/facebook.github.io\/react-native\/docs\/tutorial.html\">existing tutorial<\/a> to set up your React Native project, and then follow the steps above. For example:<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>npm install -g react-native-cli\r\nreact-native init myapp\r\n<\/code><\/pre>\n<\/div>\n<p><strong>Note:<\/strong> the <code class=\"highlighter-rouge\">react-native-windows<\/code> NPM package is only compatible with the latest versions of <code class=\"highlighter-rouge\">react-native<\/code>, from version 0.27 forward.<\/p>\n<p>Otherwise, you can easily set yourself up with <code class=\"highlighter-rouge\">npm init<\/code>.<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>mkdir myapp\r\ncd myapp\r\nnpm init\r\nnpm install --save-dev rnpm-plugin-windows\r\nreact-native windows\r\n<\/code><\/pre>\n<\/div>\n<p><strong>Note:<\/strong> the default behavior for choosing the version of <code class=\"highlighter-rouge\">react-native-windows<\/code> is to install the latest version if the <code class=\"highlighter-rouge\">package.json<\/code> does not yet have a <code class=\"highlighter-rouge\">react-native<\/code> dependency. Otherwise, if a <code class=\"highlighter-rouge\">react-native<\/code> dependency already exists, the plugin will attempt to install a version of <code class=\"highlighter-rouge\">react-native-windows<\/code> that matches the major and minor version of <code class=\"highlighter-rouge\">react-native<\/code>.<\/p>\n<p>The Windows plugin for React Native will automatically install the <code class=\"highlighter-rouge\">react-native<\/code> and <code class=\"highlighter-rouge\">react<\/code> peer dependencies for <code class=\"highlighter-rouge\">react-native-windows<\/code> if they have not yet been installed.<\/p>\n<h1 id=\"react-native-for-windows-project-structure\">React Native for Windows Project Structure<\/h2>\n<p>There are a few boilerplate files that get generated for the Universal Windows App. The important ones include:<\/p>\n<ul>\n<li><code class=\"highlighter-rouge\">index.windows.js<\/code> is the entry point to your React application.<\/li>\n<li><code class=\"highlighter-rouge\">windows\/myapp.sln<\/code> is where you should start to launch your app and debug native code.<\/li>\n<li><code class=\"highlighter-rouge\">windows\/myapp\/MainPage.cs<\/code> is where you can tweak the native bridge settings, like available modules and components.<\/li>\n<\/ul>\n<p>Here\u2019s the full output:<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>\u251c\u2500\u2500 index.windows.js\r\n\u251c\u2500\u2500 windows\r\n    \u251c\u2500\u2500 myapp.sln\r\n    \u251c\u2500\u2500 myapp\r\n        \u251c\u2500\u2500 Properties\r\n            \u251c\u2500\u2500 AssemblyInfo.cs\r\n            \u251c\u2500\u2500 Default.rd.xml\r\n        \u251c\u2500\u2500 Assets\r\n            \u251c\u2500\u2500 ...\r\n        \u251c\u2500\u2500 App.xaml\r\n        \u251c\u2500\u2500 App.xaml.cs\r\n        \u251c\u2500\u2500 MainPage.cs\r\n        \u251c\u2500\u2500 project.json\r\n        \u251c\u2500\u2500 Package.appxmanifest\r\n        \u251c\u2500\u2500 myapp_TemporaryKey.pfx\r\n<\/code><\/pre>\n<\/div>\n<p>We ship the core C# library for React Native as source on NPM. Having direct access to the source will help with debugging and making small tweaks where necessary. As long as the core ships as source, third party modules will also need to follow suit (although their dependencies may be binary). We\u2019ll be working with the React Native community on <code class=\"highlighter-rouge\">react-native link<\/code> support to make dependency management as simple as possible. Instructions for how to link dependencies are available on <a href=\"https:\/\/github.com\/ReactWindows\/react-native-windows\/blob\/master\/docs\/LinkingLibrariesWindows.md\">GitHub<\/a>.<\/p>\n<h1 id=\"building-and-extending-apps-for-the-windows-platform\">Building and Extending Apps for the Windows Platform.<\/h2>\n<p>The core components and modules for React Native are imported as follows:<\/p>\n<div class=\"language-js highlighter-rouge\">\n<pre class=\"highlight\"><code><span class=\"kr\">import<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"nx\">View<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"nx\">Text<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"nx\">Image<\/span>\r\n<span class=\"p\">}<\/span> <span class=\"nx\">from<\/span> <span class=\"s1\">'react-native'<\/span><span class=\"p\">;<\/span>\r\n<\/code><\/pre>\n<\/div>\n<p>Currently, the same goes for Android- and iOS-specific modules:<\/p>\n<div class=\"language-js highlighter-rouge\">\n<pre class=\"highlight\"><code><span class=\"kr\">import<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"nx\">TabBarIOS<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"nx\">DrawerLayoutAndroid<\/span>\r\n<span class=\"p\">}<\/span> <span class=\"nx\">from<\/span> <span class=\"s1\">'react-native'<\/span><span class=\"p\">;<\/span>\r\n<\/code><\/pre>\n<\/div>\n<p>Since Windows is a plugin to the framework, core modules specific to Windows are imported from <code class=\"highlighter-rouge\">react-native-windows<\/code>:<\/p>\n<div class=\"language-js highlighter-rouge\">\n<pre class=\"highlight\"><code><span class=\"kr\">import<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"nx\">FlipViewWindows<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"nx\">SplitViewWindows<\/span>\r\n<span class=\"p\">}<\/span> <span class=\"nx\">from<\/span> <span class=\"s1\">'react-native-windows'<\/span><span class=\"p\">;<\/span>\r\n<\/code><\/pre>\n<\/div>\n<p>So, a typical imports section of a React component with a mixture of core and Windows-specific modules will look like:<\/p>\n<div class=\"language-js highlighter-rouge\">\n<pre class=\"highlight\"><code><span class=\"kr\">import<\/span> <span class=\"nx\">React<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span> <span class=\"nx\">Component<\/span> <span class=\"p\">}<\/span> <span class=\"nx\">from<\/span> <span class=\"s1\">'react'<\/span><span class=\"p\">;<\/span>\r\n<span class=\"kr\">import<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"nx\">AppRegistry<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"nx\">StyleSheet<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"nx\">Text<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"nx\">View<\/span>\r\n<span class=\"p\">}<\/span> <span class=\"nx\">from<\/span> <span class=\"s1\">'react-native'<\/span><span class=\"p\">;<\/span>\r\n<span class=\"kr\">import<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"nx\">SplitViewWindows<\/span>\r\n<span class=\"p\">}<\/span> <span class=\"nx\">from<\/span> <span class=\"s1\">'react-native-windows'<\/span><span class=\"p\">;<\/span>\r\n<\/code><\/pre>\n<\/div>\n<p>There is a list of the core modules available on React Native for Windows on <a href=\"http:\/\/github.com\/ReactWindows\/react-native-windows\/tree\/master\/docs\/CoreParityStatus.md\">GitHub<\/a>.<\/p>\n<p>There are multiple ways to add conditional behavior to your apps based on the platform. One way that you might already recognize is the use of the <code class=\"highlighter-rouge\">*.platform.js<\/code> pattern, that is, <code class=\"highlighter-rouge\">index.[android|ios|windows].js<\/code>. The <a href=\"https:\/\/github.com\/facebook\/node-haste\"><code class=\"highlighter-rouge\">node-haste<\/code><\/a> dependency graph will choose the filename that matches the active platform choice, and fallback to the filename without any platform indicator, if available. For example, if you have files <code class=\"highlighter-rouge\">MyComponent.windows.js<\/code> and <code class=\"highlighter-rouge\">MyComponent.js<\/code>, <code class=\"highlighter-rouge\">node-haste<\/code> will choose <code class=\"highlighter-rouge\">MyComponent.js<\/code> for Android and iOS and <code class=\"highlighter-rouge\">MyComponent.windows.js<\/code> for Windows.<\/p>\n<p>Another way is to use conditional logic inside a component, as demonstrated in the simple component below.<\/p>\n<div class=\"language-js highlighter-rouge\">\n<pre class=\"highlight\"><code><span class=\"kr\">import<\/span> <span class=\"nx\">React<\/span><span class=\"p\">,<\/span> <span class=\"p\">{<\/span><span class=\"nx\">Component<\/span><span class=\"p\">}<\/span> <span class=\"nx\">from<\/span> <span class=\"s1\">'react'<\/span><span class=\"p\">;<\/span>\r\n<span class=\"kr\">import<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"nx\">Platform<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"nx\">Text<\/span><span class=\"p\">,<\/span>\r\n  <span class=\"nx\">View<\/span>\r\n<span class=\"p\">}<\/span> <span class=\"nx\">from<\/span> <span class=\"s1\">'react-native'<\/span><span class=\"p\">;<\/span>\r\n\r\n<span class=\"kr\">class<\/span> <span class=\"nx\">HelloComponent<\/span> <span class=\"kr\">extends<\/span> <span class=\"nx\">Component<\/span> <span class=\"p\">{<\/span>\r\n  <span class=\"nx\">render<\/span><span class=\"p\">()<\/span> <span class=\"p\">{<\/span>\r\n    <span class=\"kd\">var<\/span> <span class=\"nx\">text<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">\"Hello world!\"<\/span><span class=\"p\">;<\/span>\r\n    <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">Platform<\/span><span class=\"p\">.<\/span><span class=\"nx\">OS<\/span> <span class=\"o\">===<\/span> <span class=\"s1\">'android'<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n      <span class=\"nx\">text<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">\"Hello Android!\"<\/span><span class=\"p\">;<\/span>\r\n    <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"nx\">Platform<\/span><span class=\"p\">.<\/span><span class=\"nx\">OS<\/span> <span class=\"o\">===<\/span> <span class=\"s1\">'windows'<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span>\r\n      <span class=\"nx\">text<\/span> <span class=\"o\">=<\/span> <span class=\"s2\">\"Hello Windows!\"<\/span><span class=\"p\">;<\/span>\r\n    <span class=\"p\">}<\/span>\r\n    \r\n    <span class=\"k\">return<\/span> <span class=\"p\">(<\/span>\r\n      <span class=\"o\">&lt;<\/span><span class=\"nx\">View<\/span><span class=\"o\">&gt;<\/span>\r\n        <span class=\"o\">&lt;<\/span><span class=\"nx\">Text<\/span><span class=\"o\">&gt;<\/span><span class=\"p\">{<\/span><span class=\"nx\">text<\/span><span class=\"p\">}<\/span><span class=\"o\">&lt;<\/span><span class=\"sr\">\/text<\/span><span class=\"err\">&gt;\r\n<\/span>      <span class=\"o\">&lt;<\/span><span class=\"sr\">\/View<\/span><span class=\"err\">&gt;\r\n<\/span>    <span class=\"p\">);<\/span>\r\n  <span class=\"p\">}<\/span>\r\n<span class=\"p\">}<\/span>\r\n<\/code><\/pre>\n<\/div>\n<p>Facebook has a very good article on cross-platform design with React Native at <a href=\"http:\/\/makeitopen.com\/tutorials\/building-the-f8-app\/design\/\">makeitopen.com<\/a>.<\/p>\n<h1 id=\"running-the-universal-windows-app\">Running the Universal Windows App<\/h2>\n<p>There are a few options for running your React Native Universal Windows app. The easiest way is to use the <code class=\"highlighter-rouge\">run-windows<\/code> command that is enabled once <code class=\"highlighter-rouge\">react-native-windows<\/code> is installed in your project:<\/p>\n<div class=\"highlighter-rouge\">\n<pre class=\"highlight\"><code>react-native run-windows\r\n<\/code><\/pre>\n<\/div>\n<p>This command will deploy your app to the desktop. There are other options and flags you can use to deploy to emulators and devices, which you can read about using <code class=\"highlighter-rouge\">react-native run-windows --help<\/code>. The easiest way, however, to deploy to other devices such as emulators and Xbox is to launch the app in Visual Studio. After initializing the project, open the Visual Studio solution at <code class=\"highlighter-rouge\">.\/windows\/myapp.sln<\/code> in <a href=\"https:\/\/www.visualstudio.com\/downloads\/download-visual-studio-vs\">Visual Studio 2015<\/a> (Community Edition is supported). From Visual Studio, choose which platform you want to build for (x86, x64, or ARM), choose the target you want to deploy to, and press F5.<\/p>\n<p>The instructions for running React Native UWP apps, both from Visual Studio and from the CLI, will be evolving on <a href=\"https:\/\/github.com\/ReactWindows\/react-native-windows\/blob\/master\/docs\/RunningOnDeviceWindows.md\">GitHub<\/a>.<\/p>\n<p>If you have any problems getting started with building or running your React Windows application, reach out on <a href=\"https:\/\/discord.gg\/0ZcbPKXt5bWJVmUY\">Discord<\/a> or <a href=\"https:\/\/github.com\/ReactWindows\/react-native-windows#opening-issues\">open an issue<\/a>. We look forward to hearing your feedback and reviewing your <a href=\"https:\/\/github.com\/ReactWindows\/react-native-windows#contributing\">contributions<\/a>!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Using a plugin built by Microsoft, developers can build apps for Windows using React Native.<\/p>\n","protected":false},"author":21361,"featured_media":11132,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[17],"tags":[306,307,370],"class_list":["post-2147","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-frameworks","tag-react-native","tag-reactjs","tag-universal-windows-platform-uwp"],"acf":[],"blog_post_summary":"<p>Using a plugin built by Microsoft, developers can build apps for Windows using React Native.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/posts\/2147","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/users\/21361"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/comments?post=2147"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/posts\/2147\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/media\/11132"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/media?parent=2147"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/categories?post=2147"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/ise\/wp-json\/wp\/v2\/tags?post=2147"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}