{"id":13394197,"url":"https://github.com/viewstools/yarn-workspaces-cra-crna","last_synced_at":"2025-08-17T10:31:37.800Z","repository":{"id":57160698,"uuid":"112739705","full_name":"viewstools/yarn-workspaces-cra-crna","owner":"viewstools","description":"How to use yarn workspaces with Create React App and Create React Native App (Expo) to share common code across","archived":false,"fork":false,"pushed_at":"2018-11-08T20:38:13.000Z","size":220,"stargazers_count":152,"open_issues_count":18,"forks_count":23,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-04-14T02:22:03.490Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/viewstools.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-12-01T12:52:47.000Z","updated_at":"2023-08-22T17:51:12.000Z","dependencies_parsed_at":"2022-09-13T04:51:02.864Z","dependency_job_id":null,"html_url":"https://github.com/viewstools/yarn-workspaces-cra-crna","commit_stats":null,"previous_names":["viewsdx/yarn-workspaces-cra-crna"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viewstools%2Fyarn-workspaces-cra-crna","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viewstools%2Fyarn-workspaces-cra-crna/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viewstools%2Fyarn-workspaces-cra-crna/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/viewstools%2Fyarn-workspaces-cra-crna/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/viewstools","download_url":"https://codeload.github.com/viewstools/yarn-workspaces-cra-crna/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":229591247,"owners_count":18097013,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-07-30T17:01:12.162Z","updated_at":"2024-12-17T12:16:20.161Z","avatar_url":"https://github.com/viewstools.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# How to use yarn workspaces with Create React App and Create React Native App (Expo) to share common code across\n\n[This post is on medium too!](https://medium.com/viewsdx/how-to-use-yarn-workspaces-with-create-react-app-and-create-react-native-app-expo-to-share-common-ea27bc4bad62)\n\nThe goal of this tutorial is to make a [monorepo](https://github.com/babel/babel/blob/master/doc/design/monorepo.md)\nusing [yarn workspaces](https://yarnpkg.com/lang/en/docs/workspaces/) to share\ncommon code across a [Create React App (CRA)](https://github.com/facebookincubator/create-react-app)\nand a [Create React Native App (CRNA/Expo)](https://github.com/react-community/create-react-native-app).\n\nThere are currently some issues with the projects that when fixed, these\nworkarounds shouldn't be needed anymore:\n- [facebook/metro#1](https://github.com/facebook/metro-bundler/issues/1),\n- [react-community/create-react-native-app#232](https://github.com/react-community/create-react-native-app/issues/232),\n- [react-community/create-react-native-app#340](https://github.com/react-community/create-react-native-app/issues/340),\n- [react-community/create-react-native-app#408](https://github.com/react-community/create-react-native-app/issues/408),\n- [facebookincubator/create-react-app#3405](https://github.com/facebookincubator/create-react-app/issues/3405),\n- [facebookincubator/create-react-app#3435](https://github.com/facebookincubator/create-react-app/issues/3435),\n- [yarnpkg/yarn#3882](https://github.com/yarnpkg/yarn/issues/3882).\n\nSome of the solutions below may also help for lerna setups.\n\n## Pre-requisites\nMake sure you're running node ~ version 8 and at least yarn 1.3.0 and have\n`create-react-app` and `create-react-native-app` installed.\n\n## Setup workspaces\nIn this guide, we'll setup four folders but feel free to structure it as you see\nfit:\n- `web` the CRA project,\n- `native` the CRNA project,\n- `core` common logic, and\n- `views` for shared UI.\n\n\nMake a new folder where you want your workspaces to be and add a `package.json`\nthat looks like this:\n\n```json\n{\n  \"private\": true,\n  \"workspaces\": [\n    \"web\",\n    \"native\",\n    \"core\",\n    \"views\"\n  ]\n}\n```\n\nFor the rest of this guide, we're going to assume that this folder is called\n`workspaces` and it's in your home directory. We will refer to it as `~/workspaces`.\n\n## Setup core\n`core` in our example will be just an empty project. Make a `core` folder and put\nthis `package.json` inside:\n\n```json\n{\n  \"name\": \"core\",\n  \"version\": \"0.0.1\"\n}\n```\n\nLet's put a few sample files in there to use as a test. We'll also leverage the\nproject specific extensions in web and native.\n\n`test.js`:\n```js\nimport value from './value'\nexport default value\n```\n\n`value.native.js`:\n```js\nexport default 'value in native'\n```\n\n`value.web.js`:\n```js\nexport default 'value in web'\n```\n\n## Setup views\nWe will use [Views](https://github.com/viewsdx/docs) for our UI. If you want to\nuse React directly, you may still benefit from this folder by putting shared\ncomponents across your projects here. Otherwise, just skip this section.\n\n`views` is where our UI sits. Make a `views` folder and put this `package.json` inside:\n\n```json\n{\n  \"name\": \"views\",\n  \"version\": \"0.0.1\",\n  \"scripts\": {\n    \"native\": \"views-morph . --as react-native --watch\",\n    \"native:build\": \"views-morph . --as react-native\",\n    \"web\": \"views-morph . --as react-dom --watch\",\n    \"web:build\": \"views-morph . --as react-dom\"\n  }\n}\n```\n\nThen add the latest `views-morph` to it:\n```bash\nyarn add --dev views-morph\n```\n\nAdd a file called `Test.view` with this:\n```\nTest Vertical\nbackgroundColor deepskyblue\nmargin 50\nonClick props.onClick\nText\nfontSize 28\ntext Hey I'm a button!\n```\n\nViews uses some CSS defaults that make it behave close to how React Native renders the UI, add them\nby copying [views.css](https://github.com/viewsdx/yarn-workspaces-cra-crna/blob/master/views.css) to `src/index.css`.\n\nViews is a productive way to create interfaces together with your design team\nand design in production. If you want to learn more about it, reach out at\nhttps://twitter.com/viewsdx or join the conversation at https://slack.viewsdx.com :).\n\n## Web\nThere are some issues with running CRA's init scripts inside the workspace, so\njust go to a temporary folder anywhere and make a new project:\n\n```bash\n# go to some temporary location\ncd /tmp\n# make the app\ncreate-react-app web\n# get rid of node modules and yarn.lock\nrm -rf web/node_modules web/yarn.lock\n# move it to the workspaces\nmv web ~/workspaces\ncd ~/workspaces/web\n```\n\nThe next step is to have CRA compile your other workspaces code if they're\nimported by your app.\n\nInstall `react-app-rewired` and `react-app-rewire-yarn-workspaces` in the web project:\n```bash\nyarn add --dev react-app-rewired react-app-rewire-yarn-workspaces\n```\n\nSwap the `start`, `build`, and `test` scripts in `package.json` for these:\n```json\n    \"start\": \"react-app-rewired start\",\n    \"build\": \"react-app-rewired build\",\n    \"test\": \"react-app-rewired test --env=jsdom\",\n```\n\nAnd add a file called `config-overrides.js` with this:\n```js\nconst rewireYarnWorkspaces = require('react-app-rewire-yarn-workspaces');\n\nmodule.exports = function override(config, env) {\n  return rewireYarnWorkspaces(config, env);\n};\n```\n\nTo test the connection with `core`, add this to `src/App.js`:\n\n```js\nimport test from 'core/test'\n\nalert(test)\n```\n\nIf you're using Views, test it by overwriting `App.js` with this:\n```js\nimport React, {Component} from 'react';\nimport test from 'core/test';\nimport Test from 'views/Test.view.js';\n\nalert(test);\n\nclass App extends Component {\n  render() {\n    return \u003cTest onClick={() =\u003e alert('just clicked a button!')} /\u003e;\n  }\n}\n\nexport default App;\n```\n\n## Native\nThere are some issues with running CRNA's init scripts inside the workspace, so\njust go to a temporary folder anywhere and make a new project:\n\n```bash\n# go to some temporary location\ncd /tmp\n# make the app\ncreate-react-native-app native\n# get rid of node modules and yarn.lock\nrm -rf native/node_modules native/yarn.lock\n# move it to the workspaces\nmv native ~/workspaces\ncd ~/workspaces/native\n```\n\nWe'll first need to swap CRNA's entry point because the way it picks up our\n`App.js` is very much dependent on the location of files, so it's easier this\nway. We'll call that file `crna-entry.js`.\n\nEither get the original file from\n[here](https://github.com/react-community/create-react-native-app/blob/master/react-native-scripts/src/bin/crna-entry.js).\nIf you do, make sure you change `import App from '../../../../App';` for `import App from './App';` so\nit picks up your app.\n\n...or, use this version want to avoid wrapping your app in a `View`. Add a file\ncalled `crna-entry.js` with this:\n```js\nimport App from './App';\nimport Expo from 'expo';\nimport React from 'react';\n\nconst AwakeInDevApp = props =\u003e [\n  \u003cApp key=\"app\" {...props} /\u003e,\n  process.env.NODE_ENV === 'development' ? (\n    \u003cExpo.KeepAwake key=\"keep-awake\" /\u003e\n  ) : null,\n];\nExpo.registerRootComponent(AwakeInDevApp);\n```\n\nAfter that, in `package.json`, replace:\n```json\n  \"main\": \"./node_modules/react-native-scripts/build/bin/crna-entry.js\",\n```\nfor:\n```json\n  \"main\": \"crna-entry.js\",\n```\n\nThen, replace `app.json` for this:\n```json\n{\n  \"expo\": {\n    \"sdkVersion\": \"23.0.0\",\n    \"ignoreNodeModulesValidation\": true,\n    \"packagerOpts\": {\n      \"config\": \"rn-cli.config.js\",\n      \"projectRoots\": \"\"\n    }\n  }\n}\n```\nNote that this guide was created when Expo's SDK was at v23.0.0. If your\n`app.json` has a different version, use that instead.\n\nInstall `metro-bundler-config-yarn-workspaces` and `crna-make-symlinks-for-yarn-workspaces`:\n```bash\nyarn add --dev metro-bundler-config-yarn-workspaces crna-make-symlinks-for-yarn-workspaces\n```\n\nAdd a file called `rn-cli.config.js` with this:\n\n```js\nconst getConfig = require('metro-bundler-config-yarn-workspaces')\nmodule.exports = getConfig(__dirname)\n```\n\n\u003e If your workspaces are not located in the root folder (e.g. root/packages/*) \nyou must provide a `nodeModules` option indicating where the `node_modules` root\nfolder is located as described below:\n\n```js\nimport test from 'core/test'\n\nconst getConfig = require('metro-bundler-config-yarn-workspaces')\n\nconst options = { nodeModules: path.resolve(__dirname, '..', '..') }\n\nmodule.exports = getConfig(__dirname, options)  \n```\n\nAdd a file called `link-workspaces.js` with this:\n```js\nrequire('crna-make-symlinks-for-yarn-workspaces')(__dirname)\n```\n\nAdd `prestart` script to your native project's `package.json`:\n```json\n    \"prestart\": \"node link-workspaces.js\",\n```\n\nTo test the connection with `core`, add this to `App.js`:\n\n```js\nimport test from 'core/test'\n\nalert(test)\n```\n\nIf you're using Views, test it by overwriting `App.js` with this:\n```js\nimport React, {Component} from 'react';\nimport test from 'core/test';\nimport Test from 'views/Test.view.js';\n\nalert(test);\n\nclass App extends Component {\n  render() {\n    return \u003cTest onClick={() =\u003e alert('just clicked a button!')} /\u003e;\n  }\n}\n\nexport default App;\n```\n\nIf you get an error like `Cannot find entry file crna-entry.js in any of the\nroots...`, press `shift+R` when you start the expo runner so it restarts the\npackager and clears the cache.\n\nPart of the setup may also come in handy for React Native CLI. [See this\ncomment](https://github.com/facebook/metro/issues/1#issuecomment-346502388).\nI also wanted to thank [Neil Ding @GingerBear](https://github.com/GingerBear)\nfor his gist, without it [metro-bundler-config-yarn-workspaces](https://www.npmjs.com/package/metro-bundler-config-yarn-workspaces)\nwouldn't be possible.\n\n## Before starting the apps...\n\nAt this point, I'd probably recommend wiping all the node_modules of each\nproject and starting from scratch:\n```bash\ncd ~/workspaces\nrm -rf node_modules core/node_modules views/node_modules native/node_modules web/node_modules\nyarn\n```\n\nDependencies are still added to the different project folders.\n\nIf you're using Views, you need to start the morpher by project type until\n[viewsdx/morph#31](https://github.com/viewsdx/morph/issues/31) is implemented.\n\nFor web, in the `views` folder, run:\n```bash\nyarn web\n```\n\nFor native, in the `views` folder, run:\n```bash\nyarn native\n```\n\nWe'll be providing a concurrent process runner like the one implemented in\nhttps://github.com/viewsdx/use soon.\n\nI hope the process works for you! This is the GitHub repo that contains a sample\nproject and the supporting dev packages used in here. If you find any issues or\nhave suggestions around some of the steps, feel free to open an issue.\n\nThanks to [Larissa](https://github.com/callogerasl) and [Neil](https://github.com/neil-buckley)\nfor their help 🙏.\n\nHappy hacking!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fviewstools%2Fyarn-workspaces-cra-crna","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fviewstools%2Fyarn-workspaces-cra-crna","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fviewstools%2Fyarn-workspaces-cra-crna/lists"}