Setup Macbook M1 for Web and React Native development
🕑 This article was originally written on March 14, 2021. Since then, it has been updated many times to reflect my setup process. In 2023, I decided to re-write this article from scratch.
It's 2023, and I am still coming back to this article. I wrote this originally in 2021 to keep track of what I need to start when setting up a new laptop. Since then, I have had two Macbook Pros using an Apple Silicon processor (M1). I try to keep this article up to date.
I believe small optimizations help you go faster in the long run. Also, a flavor of personalization makes my developer experience more enjoyable. I like to keep two separate setups, one for work and the other for personal use and fun. However, often I end up switching between both. Having the same set of tools and configurations helps me just be me. It also helps me keep my setup portable and up-to-date (have had those days where I lost everything).
Step 1: Install Xcode and Command Line Tools
🔗To get started, open the App Store on the Mac and install Xcode. It's a large download, so it might take a while.
Once installed, open the Terminal app on the Mac and run:
xcode-select --install && sudo xcodebuild -license
Step 1.1: Verify Command Line Tools installation
🔗After installing Xcode and command line tools, open the app. Then, from the menu bar, open Xcode > Preferences > Locations and make sure that Command Line Tools point towards the current Xcode app.
Step 2: Install Warp terminal
🔗Previously, I've used iTerm2 as y default terminal app over the years. Find more info about iterm2 in the Alternate tools section at the end of this post.
I recently started using Warp as my first choice for a terminal app on Mac. After downloading the app, start the app:
- Go to Appearance
- Set theme to Dracula
- Window Opacity: 95
- Window Blur Radius: 17
Step 2.1: Install Oh My Zsh
🔗ZSH is the default shell in macOS. However, I like to use Oh My Zsh to manage the ZSH configuration, plugins, and a theme to prettify the terminal (especially when using iterm2 previously).
To install, run the command below:
sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"
After installation, make sure that the file .zshrc
is exporting the below path at the top:
# Path to your oh-my-zsh installationexport ZSH="$HOME/.oh-my-zsh"
The $HOME
should be /Users/<your-macos-username>
. You can verify this by running:
$ echo $HOME
Step 2.2: Install syntax highlighting plugin
🔗The first I like to do after setting up the bare minimum ZSH configuration is to install a plugin called zsh-syntax-highlighting. It provides syntax highlighting for the ZSH shell. Execute the series below commands in the terminal window:
# depending on the /plugins folder in your local setupcd $HOME/.oh-my-zsh/plugins# then clone the git repositorygit clone https://github.com/zsh-users/zsh-syntax-highlighting.gitecho "source ${(q-)PWD}/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh" >> ${ZDOTDIR:-$HOME}/.zshrc
On iterm2, after installing the syntax highlight plugin, it starts to recognize the commands:
Only for iterm2: Install a theme
🔗The next step is to install spaceship-prompt theme. Follow the steps described in oh-my-sh section.
Final ZSH configuration
🔗This is my final ZSH configuration in the file ~/.zshrc
file:
# Path to your oh-my-zsh installationexport ZSH="/Users/amanhimself/.oh-my-zsh"export PATH=/opt/homebrew/bin:$PATHexport ANDROID_HOME=$HOME/Library/Android/sdkexport PATH=$PATH:$ANDROID_HOME/emulatorexport PATH=$PATH:$ANDROID_HOME/toolsexport PATH=$PATH:$ANDROID_HOME/tools/binexport PATH=$PATH:$ANDROID_HOME/platform-tools# ZSH_THEME="spaceship"# Uncomment the following line to disable bi-weekly auto-update checks.DISABLE_AUTO_UPDATE="true"plugins=(gitnodevscodezsh-syntax-highlighting)source $ZSH/oh-my-zsh.shsource /Users/amanhimself/.oh-my-zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
Step 3: Change system settings
🔗System preferences and settings that I prefer. These settings are available in the Systems Settings:
- Siri:
- Disable Ask Siri
- Desktop & Dock:
- Enable "Automatically hide and show the Dock"
- Set "Automatically hide and show the menu bar in full screen" to "In Full Screen Only"
- Set Recent documents, applications and servers to "None"
- Size: 30%
- Magnification: 45%-50%
- Trackpad:
- Point & click
- Enable secondary click with the bottom right corner
- Enable Tap to click with one finger
- Tracking speed: 90%
- Click: Medium
- Force click and haptic feedback: Disable
- Look up & data detectors: Disable
- Scroll & zoom
- Natural scrolling: Disable
- More Gestures
- Swipe between pages: Off
- Point & click
- Spotlight:
- Disable search except for Applications, Calculator, Conversion, Developer, Definition, and System Settings.
- Finder settings:
- Advanced > Show filename extensions
- Enable showing hidden files (hold Cmd + Shift dot(
.
) in a Finder window) - Enable: View -> Show Path Bar, Show Status Bar
- Lock Screen:
- Start screen saver when inactive: 1 hour
- Turn display off on battery when inactive: For 3 hours
- Turn display off on power adapter when inactive: For 3 hours
Step 4: Install homebrew
🔗On December 1, 2020, the Homebrew team announced on their website about the version release 2.6.0
. The most significant changes they listed were:
- The support for macOS Big Sur.
- Using
brew
commands instead ofbrew cask
. - Beginning to support macOS M1 and Apple Silicon or ARM-based chips.
Using the terminal, you can install the Homebrew by executing the default command:
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Step 5: Install Git
🔗To install Git, run the command:
brew install git
To authenticate GitHub to be used from the terminal environment, I recommend you check out the official document on creating and accessing personal tokens.
🔥 Tip: As of Git version
2.28
, there is a new config option to set the default branch tomain
. Set it globally and forget about it.
git config --global init.defaultBranch main
To enable colors in the output, run the command:
git config --global color.ui auto
Step 6: Install homebrew packages
🔗- Node.js and npm via Node Version Manager (NVM). Read the entire blog post on how to install Node.js using NVM.
Run the following script to install other packages from homebrew:
brew install yarnbrew install scrcpybrew install watchmanbrew install exabrew install imageoptim
Some highlights from the above script:
- Watchman to watch changes in the filesystem.
- scrcpy (control Android devices connect via USB on Mac)
- exa a modern replacement for
ls
. - [imageoptim]((https://imageoptim.com/mac) for compressing image files. See ImageOptim Settings for how to set it up.
Step 7: After installing Node.js
🔗Node.js comes with the default package manager npm
. Set defaults for it:
npm config set init-author-name "your name"npm config set init-author-url "example.com"npm config set init-license MIT
Step 8: Install global npm packages
🔗- eas-cli For work and personal use:
npm i -g eas-cli
Also, I use the following command to update global packages:
npx npm-check -gu
Step 9: VSCode
🔗VSCode and VS Code Insiders are currently supported on ARM chips (March 13, 2021). Download the installer for Insiders edition from here and for VSCode here.
I am using the following VSCode configuration:
1{2 "workbench.startupEditor": "welcomePage",3 "workbench.iconTheme": "material-icon-theme",4 "workbench.editor.tabSizing": "shrink",5 "security.workspace.trust.untrustedFiles": "open",6 "explorer.confirmDelete": false,7 "explorer.confirmDragAndDrop": false,8 "workbench.editor.enablePreview": false,9 "window.restoreFullscreen": true,10 "editor.tabSize": 2,11 "editor.fontSize": 13.5,12 "editor.minimap.enabled": false,13 "editor.cursorBlinking": "phase",14 "editor.fontLigatures": false,15 "editor.wordWrap": "on",16 "editor.cursorSmoothCaretAnimation": "on",17 "editor.tabCompletion": "on",18 "editor.formatOnPaste": true,19 "editor.formatOnSave": true,20 "editor.semanticHighlighting.enabled": true,21 "editor.guides.bracketPairs": true,22 "explorer.openEditors.visible": 0,23 "files.trimTrailingWhitespace": true,24 "search.exclude": {25 "**/node_modules": true,26 "**/*.code-search": true,27 "dist/": true,28 "yarn.lock": true,29 "package-lock.json": true,30 ".gitignore": true,31 ".expo": true,32 ".vscode": true33 },34 "extensions.autoUpdate": false,35 // --------------------------------------36 // --------------------------------------37 // CODE::STATS EXTENSION38 // --------------------------------------39 // READ TIME EXTENSION40 "readTime.enabled": true,41 // --------------------------------------42 // HIGHLIGHT MATCHING TAG EXTENSION43 "highlight-matching-tag.styles": {44 "opening": {45 "name": {46 // surround is border47 "surround": "yellow"48 }49 }50 },51 // --------------------------------------52 // INTEGRATED TERMINAL53 "terminal.external.osxExec": "iTerm.app",54 // "terminal.external.osxExec": "warp.app",55 "terminal.integrated.fontSize": 12,56 // --------------------------------------57 // NPM58 "npm-intellisense.importES6": true,59 // --------------------------------------60 // TS IMPORT SUGGESTION61 "typescript.suggest.paths": false,62 // --------------------------------------63 // NATIVE BRACKET PAIR COLOR SETTINGS64 "editor.bracketPairColorization.enabled": true,65 "workbench.colorCustomizations": {66 "editorBracketHighlight.foreground1": "#ffb86c",67 "editorBracketHighlight.unexpectedBracket.foreground": "#ff5555",68 "[morgan.codes]": {69 "gitDecoration.ignoredResourceForeground": "#434343"70 },71 "[Expo Dark]": {72 // "activityBar.background": "#635985",73 "activityBarBadge.background": "#fc4384",74 "activityBarBadge.foreground": "#ffffff",75 // "activityBar.activeBackground": "#bd93f9",76 "activityBar.activeBorder": "#fc4384",77 "gitDecoration.ignoredResourceForeground": "#434343",78 "statusBar.background": "#fc4384",79 "statusBar.noFolderBackground": "#fc4384",80 // Gutter81 "editorGutter.deletedBackground": "#ff0055",82 "editorGutter.addedBackground": "#fc4384",83 "editorGutter.modifiedBackground": "#9765c9",8485 // Selection and matches86 "editor.selectionHighlightBorder": "#e18cc9",87 "editor.selectionHighlightBackground": "#635985",88 "editor.selectionForeground": "#eff8ff",89 "editor.findMatchHighlightBackground": "#ff2b7c8e",90 "editor.hoverHighlightBackground": "#ff000013",91 "editor.lineHighlightBackground": "#2b2b2b50",92 "editor.lineHighlightBorder": "#00000000",93 "editorOverviewRuler.bracketMatchForeground": "#635985"94 }95 },96 // --------------------------------------97 "editor.defaultFormatter": "esbenp.prettier-vscode",98 // Markdown99 "[markdown]": {100 "editor.quickSuggestions": {101 "comments": "on",102 "strings": "on",103 "other": "on"104 }105 },106 // JSON107 "[json]": {108 "editor.defaultFormatter": "esbenp.prettier-vscode"109 },110 // JavaScript111 "[javascript]": {112 "editor.defaultFormatter": "esbenp.prettier-vscode"113 },114 // JavaScript + React115 "[javascriptreact]": {116 "editor.defaultFormatter": "esbenp.prettier-vscode"117 },118 // TypeScript119 "[typescript]": {120 "editor.defaultFormatter": "esbenp.prettier-vscode"121 },122 // TypeScript + React123 "[typescriptreact]": {124 "editor.defaultFormatter": "esbenp.prettier-vscode"125 },126 // JSON with Comments127 "[jsonc]": {128 "editor.defaultFormatter": "esbenp.prettier-vscode"129 },130 // HTML131 "[html]": {132 "editor.defaultFormatter": "esbenp.prettier-vscode"133 },134 // ----------------------------------135 // ESLINT136 "eslint.validate": [137 "javascript",138 "javascriptreact",139 "typescript",140 "typescriptreact"141 ],142 // --------------------------------------143 // ERROR LENS144 // "errorLens.fontSize": "11",145 // "errorLens.onSave": true,146 // "errorLens.enabledDiagnosticLevels": ["error", "warning", "hint"],147 // "workbench.colorCustomizations": {148 // "errorLens.hintForeground": "#ffc600A1",149 // "errorLens.hintBackground": "#ff00dd2f",150 // "errorLens.errorBackground": "#ff000005",151 // "editor.selectionBackground": "#ff1493",152 // "editor.selectionHighlightBackground": "#ff1493",153 // "editor.findMatchBackground": "#ff1493",154 // "editor.findMatchHighlightBackground": "#3cb371"155 // },156 // "errorLens.exclude": ["never (read|used)"],157 // --------------------------------------158 // LANGUAGES SPECIFIC159 "javascript.updateImportsOnFileMove.enabled": "always",160 "security.workspace.trust.banner": "never",161 "emmet.includeLanguages": {162 "typescript": "typescriptreact",163 "javascript": "javascriptreact"164 },165 "cSpell.userWords": [166 "Appbar",167 "asyncstorage",168 "backgrounded",169 "backoff",170 "Cacheable",171 "cancelation",172 "Chakra",173 "concurrencies",174 "Contentful",175 "Ecommerce",176 "Entypo",177 "Firestore",178 "Grammarly",179 "Ionicons",180 "launchable",181 "nocheck",182 "Parens",183 "Podfile",184 "prefetch",185 "Pressable",186 "Transifex",187 "Turborepo",188 "undeployed",189 "Vercel",190 "vercelians",191 "yantramanav",192 "zustand"193 ],194 "git.autofetch": true,195 "cSpell.language": "en,en-US",196 "cSpell.enableFiletypes": ["markdown", "mdx"],197 "editor.inlineSuggest.enabled": true,198 "github.copilot.enable": {199 "*": true,200 "yaml": true,201 "plaintext": true,202 "markdown": true203 },204 "workbench.colorTheme": "Expo Light",205 "window.commandCenter": true,206 "customizeUI.fontSizeMap": {207 "13px": "12px",208 "12px": "11px",209 "window-title": "12px", // Window title font when using custom titlebar210 "tab-title": "12px", // Used for editor tab titles211 "monospace": "11px" // Used for monospace fonts in user interface212 },213 "react-native-tools.showUserTips": false,214 "errorLens.fontSize": "12",215 "grammarly.files.include": [216 "**/README.md",217 "**/readme.md",218 "**/*.txt",219 "**/*.md",220 "**/*.mdx"221 ],222 "css.lint.unknownAtRules": "ignore",223 "workbench.editorAssociations": {224 "*.js": "default"225 },226 "githubPullRequests.pullBranch": "never"
VSCode themes
🔗I usually like to switch between a dark and a light theme.
For a light theme, I prefer:
- Quiet Light (built-in)
- Expo Light (unreleased -- based on Expo Docs)
For the dark theme where I spent most of my time with fairyFloss.
- fairyFloss
- Expo Dark theme (unreleased -- based on Expo Docs)
For file icons, I love Material-Icon-Theme.
VSCode extensions
🔗- Auto Close tag
- Auto Complete Tag
- Auto Rename Tag
- Babel JavaScript
Bracket Pair Colorizer 2- VSCode now supports this natively. See How to configure VSCode Bracket Pair Colors Natively- Code Spell Checker
- Code::Stats
- Color Highlight
- Customize UI
- DotENV
- Error Lens
- ESLint
- Expo Tools
- GitHub Copilot
- GitHub Pull Requests and Issues
- Grammarly
- Highlight Matching Tag
- Indent rainbow
- iOS common files
- Material Icon Theme
- MDX - For syntax highlighting of
.mdx
files - npm intellisense
- Prettier
- Paste JSON as code
- React Native Tools
- Read Time
- TODO Highlight
- Version Lens
- WakaTime
- Word Count
Apps
🔗Step 10: Download browsers
🔗- Arc Browser from Gmail as it is in private beta. Login to work Gmail and Calendar.
- Google Chrome Login to work and personal Gmail.
- Brave Browser.
Use Safari for personal email.
Other apps on my macOS
🔗- Android Studio
- Insomnia as a REST API client
- Slack and Discord (for work and community)
- There (to track team mate's timezones)
- Zoom (for work)
- GitHub Desktop App
- Cleanshot (for screenshots and recording videos)
- Spotify
- Bandwidth +
- Linear (for work)
- Skype
- Discord
- The Unarchiver
- HiddenMe
- Numbers
- Telegram
- Android file transfer
Chrome settings
🔗- Sync settings and switch "Developer Mode" on.
- Extensions that I use:
ImageOptim settings
🔗The custom config I use for ImageOptim app:
Copy dotfiles
For React Native Development
🔗Follow React Native documentation for info on how to install open JDK and Android Studio.
Alternate tools
🔗Tools and apps that I've used in the past that I may come back to one day.
iterm2
🔗My favorite terminal app that I have been using for years is iTerm2.
- Enable Working Directory for New Split Panes: General -> Advanced Configuration
- Text:
- Colors: For the overall looks and appearance, I use Dracula Pro Color Presets created by Zen Rocha.
- Window:
- Transparency: 5
- Blur: 20
Rosetta 2
🔗Update: I am not using the Rosetta environment to install anything on the secondary machine since August 2021. That is why I've mentioned it at the end of the post.
Rosetta 2 is the lifeline that allows you to run apps designed for Intel-based chips that use x86
architecture on ARM-based chips (in this case M1). This solution is provided by Apple as an emulator and doesn't come pre-installed. You have to install it manually. Fire up the Terminal application that comes pre-installed on the macOS and execute the following command:
/usr/sbin/softwareupdate --install-rosetta --agree-to-license
If you decide not to put the flag --agree-to-license
, you will be prompted by Apple's interactive install, and you will have to agree to their terms and license conditions to use it.
Conclusion
🔗That’s the setup I now use for my JavaScript, Node.js, React, React Native and documentation work. I think it's a great machine. Hopefully, M1 is just the beginning of a new era of powerful computers for daily work use.
🤔 The only thing left for me is to find a way to transfer all laptop swag/stickers from my Macbook Air 2017 to Pro. I miss having them on this one.
isapplesiliconready.com is another helpful link I found to check what is compatible to work on Apple Silicon chips natively or using Rosetta or not optimized at all.
More Posts
Browse all posts