Latest Tutorials

Learn about the latest technologies from fellow newline community members!

  • React
  • Angular
  • Vue
  • Svelte
  • NextJS
  • Redux
  • Apollo
  • Storybook
  • D3
  • Testing Library
  • JavaScript
  • TypeScript
  • Node.js
  • Deno
  • Rust
  • Python
  • GraphQL
  • React
  • Angular
  • Vue
  • Svelte
  • NextJS
  • Redux
  • Apollo
  • Storybook
  • D3
  • Testing Library
  • JavaScript
  • TypeScript
  • Node.js
  • Deno
  • Rust
  • Python
  • GraphQL

Converting a React Native for macOS Application into a Menu Bar Application

The status menus (also known as menu bar icons) of a macOS menu bar let users quickly access status information and perform actions without launching an application inside a new, separate window. For example, upon installation, a popular desktop application like Dropbox automatically adds a status menu to the macOS menu bar for monitoring and reporting the status of uploads. With the single click of an icon/title, the status menu toggles open a condensed version of the Dropbox desktop application. You can get the latest uploads and share them immediately without having to change your active window. Status menus helps to maximize your workflow and keep you productive. They run in the background and periodically update with new notifications and content to avoid distracting you while you are focused on completing your work. With so many status bar applications available, you can customize this section of the macOS menu bar and arrange the items in any order to best complement your workflow. However, if you cannot find a status bar application that addresses a specific aspect of your workflow, such as aggregating and displaying relevant information about the status of jobs triggered by a CI build pipeline, then you can build your own status bar application with React Native for macOS . Unlike a desktop application, building a status bar application involves quite a few steps beyond the installation steps listed in the React Native for macOS documentation . Below, I'm going to show you how to convert a React Native for macOS application into a menu bar application. To get started, let's create a new React Native for macOS project from a standard React Native template. Verify that the project was initialized correctly by running it: The status bar application consists of two components: a status item and a popover. A status item is a clickable icon/title that sits in the system menu bar. A popover is a self-contained view that hovers over its surrounding context and displays content within a non-modal dialog. It is anchored to the element responsible for making it appear, which is indicated by the direction of its tooltip arrow. Both of these parts will be implemented in Swift. Unlike a pull-down menu, which simply lists options, the layout of a popover's content is flexible. This content will come directly from the React application whose root component <App /> is registered with AppRegistry inside of the project's index.js file. To transition to Swift, we must first remove the existing Objective-C code from the project. Delete the following files: Even if you delete these files inside of Finder or within your terminal, Xcode still references these from the project navigator. Therefore, open the project inside of Xcode by either... Then, delete those files manually from the project navigator. Keep Xcode opened for the remainder of this tutorial. To add a status bar item and popover into our application, let's first create two new files: Note : The casing of projectname must match the casing of the parent project directory's name. For example, if the project's directory name is rnmacmenubar (despite the project being named rnMacMenubar during initialization via npx react-native init ), then projectname will be rnmacmenubar . The <projectname>-macOS-Bridging-Header.h bridging header file exposes Objective-C libraries to Swift. For this project, the specified libraries provide APIs for integrating React Native into native code and rendering the React Native application within a UIView . ( <projectname>-macOS-Bridging-Header.h ) The AppDelegate.swift file serves as the application's initial entry file and defines a AppDelegate class, which handles application lifecycle events like applicationDidFinishLaunching and how the application responds to these events. ( AppDelegate.swift ) Inside of AppDelegate , define the properties popover and statusBarItem , which will reference the application's popover and status bar item respectively. An additional window property will be defined to reference a "development" window. ( AppDelegate.swift ) Once the application has launched, initialize the React Native application with RCTRootView , which displays the React Native application whose root component <App /> is registered inside of the project's index.js file (development environment) or from the compiled bundle (production build). This base view is embedded within a NSViewController . ( AppDelegate.swift ) Note : #if DEBUG is a pre-processor directive. Code inside of this directive are pre-processed before compilation. In the above code, we initialize the React Native bridge within this directive. Initialize the popover by setting its base dimensions to 700px by 800px and behavior to transient. Enable animation for its dismissal and emergence. Set its content to the NSViewController that has the React application embedded within it. ( AppDelegate.swift ) Initialize the status bar item by allocating 60px (in width) within the macOS status bar for it. Using the button property, we can customize the appearance and behavior of this item. Whenever the status item is clicked, the togglePopover method is called. The status item will be shown in the status bar via the project's name, not a typical icon, to make this example simpler. ( AppDelegate.swift ) The togglePopover dismisses the popover when its opened, and vice-versa. ( AppDelegate.swift ) Note : The @objc attribute marks the method as accessible and executable in Objective-C. The "development" window allows us to iterate upon the React application and immediately see changes without having to open the popover to see changes anytime they occur. Both the window and popover share the same rootViewController to avoid having two separate instances of the application. ( AppDelegate.swift ) Note : Once the popover opens, the window will no longer possess the controller, and the React application will only be rendered in the popover. For development, this is fine. applicationDidFinishLaunching tells the delegate when the application has launched. We will place all of the initialization code within the body of this instance method to execute this code once the application has launched. Altogether... ( AppDelegate.swift ) Note : Replace all instances of <projectName> with your project's name. This is the project name specified during initialization via npx react-native init . Drag and drop the <projectname>-macOS-Bridging-Header.h and AppDelegate.swift files from Finder into Xcode's project navigator (under <projectname>/<projectname>-macOS directory). When presented with the "Choose options for adding these files" modal, accept the default selected options. Inside of Xcode, check that the run destination is "My Mac" in the workspace toolbar. If not, then change the scheme to <projectname>-macOS . This is what the workspace toolbar should display: To avoid Swift linking errors, let's enable dead code stripping by visiting the project's build settings and switching the "Dead Code Stripping" setting to "YES." Now, let's tell Xcode to include Swift standard libraries in the final application bundle. To enable the DEBUG flag only when building and running the application from Xcode, search for the OTHER_SWIFT_FLAGS setting under the "User-Defined" section of the target <projectname>-macOS 's settings. Set the -DDEBUG flag only for the "Debug" mode, not for "Release." Otherwise, when you release the application to users, it will try to connect to the metro packager. If you encounter the following issue: Then resolve it by switching the "Don't Dead-strip Inits and Terms" project setting under the "Linking" section to "Yes" for both "Project" and "Target." To import Objective-C libraries from the Objective-C bridging header file <projectname>-macOS-Bridging-Header.h into Swift code, visit the project's build settings and set the "Objective-C Bridging Header" setting under the "Swift Compiler - General" section to the header file's path. Upon setting this path, SRCROOT and PROJECT_NAME are automatically substituted with their values. To inform the compiler of the AppDelegate.swift source file that must be compiled during the build process, add this source file as a "Compile Source" within the target's "Build Phase" settings. Click on project in project navigator. Clean the project by selecting "Product" from the upper menu and clicking the "Clean Build Folder" option. With the old AppDelegate class deleted (from the deleted AppDelegate.m file), we need to reselect AppDelegate class to ensure the new AppDelegate class (from the AppDelegate.swift file) is selected. Select the Main.storyboard file from the project navigator. Under "Application Scene" in the left-sidebar of the project editor. In the right-sidebar, select the "Attributes Inspector" tab and enter "AppDelegate" as the App Delegate class. Run the application via the shortcut CMD + r . This launches... If you click on the status item labeled with the project's name in the menu bar, a popover pops open and the development window no longer displays the React application. Inside of the popover is the React application. Click on the status item again and the popover is dismissed. The smaller window is an initial window that's automatically launched for the application (in the top-left corner of the above screenshot). The larger window is the development window (in the lower-right corner of the above screenshot). Since the development window shares the same rootViewController , if you resize this window, the content within the popover is also resized. Notice that the dock shows an icon for the application. To omit this icon from the dock when running the application, edit the project's Info.plist file. If you rebuild and rerun the application, then you will notice that the application's icon no longer appears in the dock. To hide the extra, initial (smaller) window, uncheck the "Is initial controller" checkbox in the storyboard's window controller. If you rebuild and rerun the application, then you will notice that this window no longer appears. To generate a release build, run the following command: If you encounter the following error... Then add the EXCLUDED_ARCHS build setting to the command and set it to arm64 . This excludes support for ARM-based simulators. Double-click the release build to verify that the application works properly. Now you can distribute this menu bar application to other macOS users! If you are stuck at any step of this tutorial, feel free to visit the final version of this project here . Try building your next menu bar application with React Native for macOS!

Thumbnail Image of Tutorial Converting a React Native for macOS Application into a Menu Bar Application

Creating A Split Component

Photo by  Cassie Matias  on  Unsplash For the longest time, floats were the go-to tool for putting two things next to each other. Unfortunately, since this is not what floats were designed for, this created as many problems as it solved. Luckily, modern CSS makes this much easier to solve. Let's take the following layout: In this layout we need to be able to split the two children into fractional parts of the partents width while maintaining a gutter between them. Let's say we start with the following basic markup. What we need to do is build a Split component that will fractionally split the width of the outer dive between the div  that is wrapping the h2  and span  and the Form  component. There is a couple of ways we could tackle this, but the easiest would be to use CSS grid: In the above code, first we set the display  property to grid  and set the gap property to 1rem . This will create a grid container that puts a gap of 1rem  between each of the children of the Split component. In the final line we are setting the   grid-template-columns  property. The grid-template-columns property allows us to define how many column tracks we have and how wide they should be. We define the width of each column track using any valid CSS size unit, and the quantity of tracks is determined by how many sizes we assign to the property. For example, if we wanted three column tracks of 30px , 50% , and 2rem , It would look like this: Looking back at the Split component above, you will notice that we are using a special size unit that you might not recognize. The fr unit is a unique size unit only available when using CSS grid. The fr unit (or the fraction unit as it is sometimes called) says to the browser, "give me X fraction(s) of the remaining space available." If we set the grid-template-columns to be 1fr 1fr , which will result in two columns with a 50/50 split, like this: It is essential to distinguish that fr is not the same as % . When we use % , we are saying give me a percentage of the total width of my parent component. What that doesn't take into account is the gutter between the elements. So using 50% 50% would result in an overflow, where 1fr 1fr would not. The mockup above doesn't call for a 50/50 split though. The requirement is to split it into thirds, with the first column taking up only 1/3. Also, hard-coding column tracks do not make for a useful primitive. We need something more configurable that we can adjust to the situation. So let's make the following changes: Now, instead of hard-coding values, we have named our fractions according to the ratio we want them to take and now we can update our FormSideBar component like this: Now we have a component that lets us fractionally split anything among two children.  The Split component works great for any time you want to put two elements next to each other, such as for side bars.

Thumbnail Image of Tutorial Creating A Split Component

I got a job offer, thanks in a big part to your teaching. They sent a test as part of the interview process, and this was a huge help to implement my own Node server.

This has been a really good investment!

Advance your career with newline Pro.

Only $30 per month for unlimited access to over 60+ books, guides and courses!

Learn More

Building macOS Applications with React Native for macOS

Did you know Slack 's and Discord 's desktop clients are built with the Electron framework? Using Electron allows developers to bring their web applications to desktop faster without having to rewrite them completely as standalone, native clients that run on multiple operating systems. However, a major downside of building desktop applications with Electron is its high memory consumption and size because it packages the final build with a copy of Chromium, an open-source alternative of the Chrome browser, and Node.js to run an application written with HTML, CSS and JavaScript. At a high level, an Electron application behaves like a Chrome browser and loads and renders an HTML document inside of a window ( BrowserWindow ). To avoid the extra overhead of Chromium and Node.js and make the UI appear consistent with a platform's trademark design by rendering it with native APIs and components, consider using a different framework like React Native for Windows and macOS . Launched in 2019 and forked from Facebook's React Native project, React Native for Windows and macOS is an open source project maintained by Microsoft and allows developers to create Windows and macOS applications with a single React Native codebase. To interact with native APIs, the macOS port uses Objective-C or Swift while the Windows port uses C# or C++/WinRT. React Native for Windows and macOS comes with React components that are transformed into native components of each platform at runtime and can readily be imported from the react-native library. Composing an interface with native components instead of wrapping an entire web application inside of an application shell results in faster and smaller desktop applications. With all the tooling and CLI utilities provided by React Native for Windows and macOS, a developer can easily get started and deliver an application with a solid desktop experience. Below, I'm going to... Like any other piece of technology and library/framework, you need to decide whether React Native for Windows and macOS is appropriate for your particular use case by weighing its upsides against its downsides. Being aware of its strengths and weaknesses ensures our application best meets expectations. Here are several advantages for using React Native for Windows and macOS: Here are several disadvantages for using React Native for Windows and macOS: Remember. By spending a bit of time upfront to pick the best framework for your project, it will save you much more time during development. To get started with React Native for Windows and macOS, initialize a standard React Native project via the react-native init command. Specify the template version to match the latest minor version of React Native for Windows and macOS . Note : projectName cannot contain any spaces or hyphens; it must be alphanumeric and camelcased. Otherwise, the react-native CLI tool prints the following error message: error "<projectName>" is not a valid name for a project. Please use a valid identifier name (alphanumeric). During the initialization of the project, you may be prompted with the following question: CocoaPods (https://cocoapods.org/) is not installed. CocoaPods is necessary for the iOS project to run correctly. Do you want to install it? CocoaPods is a dependency manager for languages (Swift, Objective-C, etc.) that execute inside the Objective-C runtime. Select "Yes, with Homebrew" if you already have Homebrew installed on your machine. Otherwise, select "Yes, with gem (may require sudo)." Note : Make sure Homebrew and packages are up-to-date! Otherwise, you may eventually encounter the following error: dyld: Library not loaded . Inside of the new project, install the macOS-specific packages via the react-native-macos-init command: Note : Install Windows-specific packages via the react-native-windows-init command. This creates a macos directory at the root of the project directory, and it contains the macOS project. Run the macOS application (with hot-reloading) via the react-native run-macos command: Note : Run the Windows application via the react-native run-windows command. This may take some time as it needs to compile all the native code necessary to run the application. In the above screenshot, you may notice an additional terminal window that opens when running the application. This window contains Metro , the React packager. This window must be kept open for the application to work properly during development. If you run into the following error: Then inside of the macos/<projectname>-macOS/ViewController.m file, correct the casing of moduleName , which must follow the same casing as your project's name (camelcased), not lowercased. Anytime you modify the App.js file, watch those changes be automatically reflected in the application! ( App.js ) To build a release (a .app file) for distribution, add the following script to package.json : ( package.json ) Note : projectname is projectName , but lowercased. Here, the build configuration of xcodebuild is set to "Release." Also, the build takes a while to complete. Once completed, the path to the release is printed within the logs. When you double-click on the release, the application opens. Feel free send a copy of the application to other team members to test on their macOS machines. As opposed to Electron applications, React Native for Windows and macOS applications consume less memory and spawn less processes. If you run barebone applications built with these frameworks on the same machine and compared them side-by-side, then you will notice these differences. Here, we will compare three applications: When we run these three applications on the same macOS machine and open Activity Monitor, even though the Electron applications display static content, they each spawn four processes (one main and three helper processes based on Chromium's multi-process architecture ). Altogether, these processes consume more than twice the amount of memory consumed by the single React Native for Windows and macOS application's process. Similarly, if you run the top command, which displays CPU and memory utilization information, inside of a terminal, you will also make the same observation. Space-wise, the application built with React Native for Mac takes up significantly less space on your machine than the applications built with Electron. Download this repository with the source code of these applications to replicate these findings. Try building your next desktop application with React Native for Windows and macOS!

Thumbnail Image of Tutorial Building macOS Applications with React Native for macOS

Adding TypeScript to a React Native for macOS Project

Forked from Facebook's React Native project, React Native for Windows and macOS ships with Flow by default. When compared to TypeScript , Flow is way less popular, and there are fewer third-party library interface definitions written for Flow than TypeScript. If your project requires a static type checker, then pick TypeScript for its widespread support across many third-party libraries/frameworks and thriving ecosystem. Setting up TypeScript for the React Native codebase will improve code quality and readability by static type checking to verify type safety, identifying potential bugs in the code and explicitly annotating code with types. Plus, if you are coding within an IDE that features intelligent code completion (strongly integrated with TypeScript) like VSCode, then anytime you type in the editor, suggestions and info about variables, function signatures, etc. pop up inline to provide helpful hints and keep you productive. Below I'm going to show you how to... To get started, create a new React Native for macOS project by running these commands, as instructed by the official documentation : Inside of the project directory, delete the .flowconfig configuration file, which is installed by default. Since we will be integrating TypeScript into the project, there's no need to also support another static type checker. Install TypeScript and type definitions for React and React Native. To configure TypeScript, add a tsconfig.json file to the project. ( tsconfig.json ) If you have worked previously on a React project that involved TypeScript, then you should be familiar with most of these configuration options. Nevertheless, if are unclear with any of these configuration options, then consult the TypeScript documentation here . Delete the default App.jsx file and replace it with a App.tsx file. ( App.tsx ) Since the new App.tsx file exports the <App /> component via export const , we must change the import statement of this component from import App from './App' to import {App} from './App' . ( index.js ) Run the application to verify that everything is working properly. If haven't already created a React Native for Windows and macOS project, and you are about the begin one, then you can bootstrap it from the TypeScript-based React Native template . Pass the template name react-native-template-typescript to the react-native init command instead of the standard react-native . Then, run the same exact commands for scaffolding a new React Native for Windows and macOS project. Inside of the macos/<projectname>-macOS/ViewController.m file, correct the casing of moduleName , which must follow the same casing as your project's name (camelcased), not lowercased. For example, if your project name is rnMacTs , then this file will specify moduleName as rnmacts , which is incorrectly cased. Therefore, change this line... ( macos/rnmacts-macOS/ViewController.m ) to this... ( macos/rnmacts-macOS/ViewController.m ) Otherwise, you will encounter the following issue when you try to run the application: Here's the tsconfig.json file that's automatically generated from this template. It is loaded with helpful comments that describe each configuration option's purpose. You can uncomment some of the commented-out configuration options if you need additional checks by TypeScript. ( tsconfig.json ) Here's the App.tsx file that's automatically generated from this template. It's just a TypeScript version of the standard React Native template's App.jsx file. ( App.tsx ) Run the application to verify that everything is working properly. When you make a change within App.tsx , those changes will automatically be reflected in the application due to hot-reloading! Try building your next desktop application with React Native for Windows and macOS and TypeScript!

Thumbnail Image of Tutorial Adding TypeScript to a React Native for macOS Project

Connecting Serverless Django to an Amazon RDS Instance (Part 2)

Disclaimer - Please read the first part of this blog post here before proceeding. It walkthrough the initial steps of creating a VPC with two subnets, one private and one public, to restrict access of the RDS database to the deployed Lambda function within the same network. AWS Relational Database Service (RDS) is an AWS cloud computing solution that enables developers to quickly provision, deploy and scale popular relational databases, such as PostgreSQL, on reliable infrastructure. To create an RDS instance, visit the Amazon RDS console and click on the "Create database" button. Select "Standard create" as the database creation method. This gives us control over the configuration options, such as whether backups should be performed. Then, select "PostgreSQL" as the engine type. You can choose a specific version within the proceeding dropdown, but for this tutorial, let's stick with already pre-selected version 12.5-R1 . Under templates, choose the "Free tier" to avoid being billed for RDS-related costs while following this tutorial. For larger, commercial projects, you would create, at minimum, two separate RDS instances: one for a production environment and one for a development environment. Label the instance with a unique, valid identifier. For this tutorial, let's name it serverless-django to indicate its connection to the serverless Django application. Then, set superuser credentials for the instance. Remember to use a strong password! Once you set these credentials, add them to the .env.production file ( PG_DB_USER for the master username and PG_DB_PASSWORD for the master password). Leave the database instance class as db.t2.micro , which corresponds to the free tier. Each class tier comes with different memory and CPU specifications, with db.t2.micro offering the lowest specifications. Leave the storage settings as is, but uncheck storage autoscaling since our database will never exceed its maximum storage capacity. The "Availability & durability" section is automatically disabled because of our earlier selection of the free tier. Multi-AZ deployment should be enabled in the production environment of a large, commercial project to ensure the database is durable and highly available. Under the "Connectivity" section, select the VPC created in first part of this tutorial. For subnet group, select the option "Create new DB Subnet Group" and disallow public access. We do not want to assign a public IP address to the database, otherwise, anyone from the public Internet can access the database and its contents if they correctly guess your superuser credentials or exploit a known vulnerability of the database. The database should only accept connections from our Lambda function within the same VPC. For the VPC security group, create a new VPC security group for this database and name it serverless-django-db-sg . Keep the availability zone to "No preference." Note : You can choose an existing VPC security group, which would be the VPC's default security group named "default," which is listed under the "Security Groups" table in the AWS VPC console. Keep the database authentication method as password authentication. Give the database instance a name of ServerlessDjangoDB . Record this same name within the .env.production file for the environment variable PG_DB . Keep the database parameter group as default.postgres12 . Uncheck automatic backups and performance insights. These features are useful for the production environment of a large, commercial project. Keep the remaining settings the same. Click the "Create database" button to create the database instance. However, an error message appears when you try to create the database instance. Our VPC requires at least two private subnets to cover at least two availability zones to satisfy the database's availability zone coverage requirement. Availability zones provide isolation within a region. When an availability zone experiences anytime network issues of downtime, other availability zones are highly unlikely to experience the same issues. Subnets covering these availability zones will be available while issues are being resolved in the affected availability zones. Therefore, we need to revisit the AWS VPC console and add another private subnet that covers a different zone than the current private subnet. Open the AWS VPC console in a new browser tab/window. Select the VPC's private subnet from the table of subnets. Within its details, take note of the subnet's availability zone ID (in the below screenshot, it is use1-az3 ). When we create another private subnet, its availability zone cannot have the same availability zone ID. Let's create a new private subnet. Select the VPC in the dropdown. Under the "Subnet settings" section, you can assign any name to the subnet, but for this tutorial, it will simply be named "Private subnet." When you choose an availability zone for this subnet, pick one that is different from the one already covered. In the below screenshot, since use1-az3 is already covered by our other private subnet, let's pick US East (N. Virginia) / us-east-1f . Set the private subnet's IPv4 CIDR block to 10.0.16.0/21 . Then, click the "Create subnet" button to create the private subnet. Once the private subnet is successfully created, close out the browser tab/window Toggle back to the previous tab/window with the database creation wizard and click the "Create database" button. The error message disappears, and you should now be able to successfully create the database instance. Currently, the database is publicly accessible from the public Internet. Let's limit this access to only resources within the same VPC. Select the database (identifier serverless-django ) within the table of databases in the Amazon RDS console. Scroll down to the "Security group rules" section. Since the database's inbound traffic is being restricted, click on the first security group with the type "CIDR/IP - Inbound" to modify the inbound traffic rules. Under the "Inbound rules" section, click on the "Edit inbound rules" button. Delete the default inbound rule and add a new inbound rule. Set this rule's type to "PostgreSQL" and source to "Custom." If you created a new VPC security group for the database, then select that security group from the field with the magnifying glass. However, if you chose to use an existing VPC security group, then select that security group from the field with the magnifying glass. Click the "Save rules" button. You can now find this new security group rule inside of the security group rules' table with type "EC2 Security Group - Inbound." Continue on to the last part of this tutorial here , which dives into deploying the serverless Django application onto AWS Lambda with Zappa.

Thumbnail Image of Tutorial Connecting Serverless Django to an Amazon RDS Instance (Part 2)