Back to Blog Home
← all posts

NativeScript 8.0 Released

March 31, 2021 — by Technical Steering Committee (TSC)

NativeScript 8.0 signals it's future solid footing for growth and natural modern JavaScript evolutions with increased community engagement by addressing some of the oldest requested features, adding structural integrity with official eslint package, adding support for creative view development via new RootLayout, affirming broad use case applicability via new Capacitor integration, support for latest webpack5 and a revamped website and documentation refresh.

  • Official Apple M1 support
  • webpack5 support
  • First class a11y support
  • CSS box-shadow support (requested since 2015!)
  • CSS text-shadow support
  • New hidden binding property for more performance dialing cases
  • New official eslint rules for NativeScript projects
  • New RootLayout container - offering more dynamic creative view development
  • New website and revamped docs to better represent the current and future of NativeScript
  • The first official NativeScript Best Practices Guide
  • ...and more streamlining of core to further prepare for continual evolutionary enhancements

There's a number of items we'd like to touch on in more detail so let's get into it.

Quickly jump to these sections

We released NativeScript 7 in the Fall of 2020 which was probably one of the biggest structural updates to the framework since it's very inception and it set the foundation for broad improvements to come, some of which are evident here in 8.0. We are committed to delivering major releases 2 times a year - once in the Spring (now) and another in the Fall. This often falls inline with platform tooling updates throughout the industry which we align with every year. At each pass we continue to improve the update/migration story where needed.

This time around TSC Member, Stanimira Vlaeva, dug in deep to deliver @nativescript/eslint-plugin. The first official eslint rules for NativeScript projects. These can be used to help projects mitigate framework breaking changes as well as offers a way to auto update project imports to align themselves with the latest updates. This package will continue to be enhanced to strengthen NativeScript structural integrity over time. Let's take a look at how you can update to NativeScript 8 today.

Updating to NativeScript 8

As some may have become accustomed by now, you can run:

npm i -g nativescript

ns migrate

This will install the latest NativeScript 8 CLI and then run the migration.

Here's the dependencies you can expect to be using:

"dependencies": {
  "@nativescript/core": "8.0.0"
"devDependencies": {
  "@nativescript/android": "8.0.0",
  "@nativescript/ios": "8.0.0",
  "@nativescript/types": "8.0.0",
  "@nativescript/webpack": "~5.0.0-beta.0"

We are already using NativeScript 8 with @nativescript/webpack@~5.0.0-beta.0 with great success. It's actually quite a bit faster too, here's some numbers:


# cold run after ns clean (includes npm install, pod install etc.)
prepare ios  42.08s user 10.86s system 125% cpu 42.063 total

prepare ios  13.01s user 1.00s system 126% cpu 11.052 total
prepare ios  13.03s user 0.97s system 131% cpu 10.663 total
prepare ios  13.36s user 0.99s system 131% cpu 10.903 total


# cold run after ns clean (includes npm install, pod install etc.)
prepare ios  21.78s user 6.78s system 98% cpu 28.985 total

prepare ios  6.58s user 0.63s system 134% cpu 5.361 total
prepare ios  6.73s user 0.67s system 133% cpu 5.523 total
prepare ios  6.62s user 0.65s system 134% cpu 5.397 total

The webpack rewrite has been cooking since November last year, and has given us the opportunity to test-drive the official RFC Process.

We will keep it officially in beta for just a little bit, but we do recommend using it as we certainly are.

An overview of all the new things

The following new features can be observed in a wonderful sample app that NativeScript community contributor, William Juan, put together here:

Webpack: vastly simplified config

A typical NativeScript webpack.config.js looks like this now:

const webpack = require("@nativescript/webpack");

module.exports = (env) => {

  return webpack.resolveConfig();

See it being used in in the demo!

The above config manages all the supported frameworks and their specific webpack requirements (plugins, loaders etc.) while sharing a common base config that streamlines features across all flavors.

While the default config is fairly minimal, you have full control to customize any aspects of the final config that's resolved through @nativescript/webpack.

Another great feature is that plugins can now automatically register new loaders, rules - in fact, plugins can do anything with the project config — no more manual copying of loaders & webpack plugins!

This new config will avoid the constant back-and-forth of "Are you using the latest webpack.config.js?". The underlying base configs can easly be updated through npm without requiring any changes in your project.

CSS: box-shadow

Box Shadows have been a highly requested feature in NativeScript, in fact it was first requested in 2015!

You can now use css box-shadow - the value support is CSS-Spec compliant - you can use any of the short-hand variants.

box-shadow: 0 0 5px rgba(0, 0, 0, 0.8);

Used throughout the movies demo app

CSS: text-shadow

Another community contributor, Tiago Alves, added official text-shadow support in this pull request.

text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.8);

You can also find this being used in movies demo app here

Layout: the new RootLayout

A brand new layout container which extends from GridLayout offers new apis for powerful and fun dynamic view creation and layering.

<RootLayout> is a layout container designed to be used as the primary root layout container for your app with a built in api to easily control dynamic view layers. It extends a GridLayout so has all the features of a grid but enhanced with additional apis.

It's api can be observed here:

export class RootLayout extends GridLayout {
  open(view: View, options?: RootLayoutOptions): Promise<void>;
  close(view: View, exitTo?: TransitionAnimation): Promise<void>;
  bringToFront(view: View, animated?: boolean): Promise<void>;
  closeAll(): Promise<void>;
  getShadeCover(): View;

export function getRootLayout(): RootLayout;

export interface RootLayoutOptions {
  shadeCover?: ShadeCoverOptions;
  animation?: {
    enterFrom?: TransitionAnimation;
    exitTo?: TransitionAnimation;

export interface ShadeCoverOptions {
  opacity?: number;
  color?: string;
  tapToClose?: boolean;
  animation?: {
    enterFrom?: TransitionAnimation; // only applied if first one to be opened
    exitTo?: TransitionAnimation; // only applied if last one to be closed
  ignoreShadeRestore?: boolean;

export interface TransitionAnimation {
  translateX?: number;
  translateY?: number;
  scaleX?: number;
  scaleY?: number;
  rotate?: number; // in degrees
  opacity?: number;
  duration?: number; // in milliseconds
  curve?: any; // CoreTypes.AnimationCurve (string, cubicBezier, etc.)

You can use getRootLayout() to get a reference to the root layout in your app from anywhere.

Sample layout:

<RootLayout height="100%" width="100%">
  <GridLayout height="100%">
    <label verticalAlignment="center" textAlignment="center" text="MAIN CONTENT AREA"></label>

Sample api usage:

// Open a dynamic popup
const view = this.getPopup("#EA5936", 110, -30);
  .open(view, {
    shadeCover: {
      color: "#000",
      opacity: 0.7,
      tapToClose: true,
    animation: {
      enterFrom: {
        opacity: 0,
        translateY: 500,
        duration: 500,
      exitTo: {
        opacity: 0,
        duration: 300,
  .catch((ex) => console.error(ex));

// Close the dynamic popup
  .close(view, {
    opacity: 0,
    translate: { x: 0, y: -500 },
  .catch((ex) => console.error(ex));

function getPopup(color: string, size: number, offset: number): View {
  const layout = new StackLayout();
  layout.height = size;
  layout.width = size;
  layout.marginTop = offset;
  layout.marginLeft = offset;
  layout.backgroundColor = color;
  layout.borderRadius = 10;
  return layout;

You can find a thorough example in this sample repo also provided by community contributor, William Juan.

You can play with the toolbox app here for more examples

Accessibility: first class a11y

For a long time, the amazing folks over at Nota, Denmark's national library for people with reading disabilities, have provided a fantastic a11y plugin with nativescript-accessibility-ext.

When we started working on 8.0 we began working with Morten Sjøgren to integrate the plugin directly into core as a first class integration and thanks to Morten's incredible work a11y is now built directly into core.

There will be an additional blog post dedicated to a11y during the 8.0 - 8.1 cycle this Spring to dig into this in more detail.

You can explore some of the first class a11y support in the core repo's toolbox app here.

You can also have a look at the new docs.

Tooling: @nativescript/debug-ios

This package will add some deep interactive debugging tools to your iOS app (only in develop/debug mode so don't worry about it affecting your release/production app).

You can enable it anytime with the following:

npm install @nativescript/debug-ios --save-dev


import { NativeScriptDebugIOS } from "@nativescript/debug-ios";;

Plugins: @nativescript/apple-pay

npm install @nativescript/apple-pay

This provides the following:

<ApplePayBtn tap="onApplePayTap" buttonType="InStore" />

You can find the full documentation of what this provides in the new plugin docs.

Plugins: @nativescript/google-pay

npm install @nativescript/google-pay

This provides the following:

<GooglePayBtn cardNetworks="VISA, AMEX, DISCOVER" authMethods="PAN_ONLY, CRYPTOGRAM_3DS" tap="onGooglePayTap" width="100%" height="40" buttonType="PAY_BLACK" />

You can find the full documentation of what this provides in the new plugin docs.

Important note about BottomNavigation and Tabs

BottomNavigation and Tabs ui components in core brought along Cocoapods whether your project used them or not. With 8.0, they now are provided by the community where they can receive more focused attention not bound or held up by NativeScript core updates.


<BottomNavigation> is now available via @nativescript-community/ui-material-bottom-navigation

The api is the same however the component names can swap to what is found in the Readme.


<Tabs> is now available via @nativescript-community/ui-material-tabs

This is a drop in replacement.

First official NativeScript Best Practices Guide

Over the years several distinct best practices have emerged when working with NativeScript and we took a moment to outline a few of the most fundamental ones you shoud be aware of to get the best end result out of your projects.

NativeScript Best Practices Guide

This section will most certainly grow with even more tips/tricks over time.

Community update zoom calls

The next scheduled community update via Zoom will occur on April 7th, 2021 and will continue on a monthly basis until a month prior to the next major version release (9.0 sometime in late fall to early winter).

Join our Discord Community

Over the years, the NativeScript Community has been very active on Slack, however this time around we have decided that Discord is a much better suited platform to reach the community.

📣 Come join and say Hello in our Discord Community!

Live streams of NativeScript 8 project updates

Two live streams will take place in the month of April to update old NativeScript projects to 8.0 so keep an eye on Twitter and NativeScripting for the date announcement.

What's Next?

For 8.1:

  • Introducing @nativescript/tailwind
  • Enhancing a few more use cases with a11y (perform escape gestures, etc.)
  • Additional fixes for @nativescript/ios
  • Additional fixes throughout core

An updated roadmap for 2021 and beyond will be posted during the month of April 2021.

Big Thank You!

We want to thank the incredible community for their input and support. The contributions provided during this cycle were astounding and you make working on NativeScript an absolute joy. In addition, the tremendous love you have shown on Open Collective, each and every contribution has helped make 8.0 a reality as well as paved the way for more exciting things to come.