🚀 8.9 Released! → ⚡️ New Node-API Engine Preview, 📲 ns widget ios, 💅 Tailwind v4 and more...
Read Announcement

All NativeScript apps can be bundled using Vite. To manage the required configuration, we maintain the @nativescript/vite package.

Setup

Install the plugin.

bash
npm install @nativescript/vite

Configure

The plugin comes with several framework integrations.

Vue

ts
import { defineConfig, mergeConfig, UserConfig } from 'vite';
import { vueConfig } from '@nativescript/vite';

export default defineConfig(({ mode }): UserConfig => {
	return mergeConfig(vueConfig({ mode }), {});
});

Angular

ts
import { defineConfig, mergeConfig, UserConfig } from 'vite';
import { angularConfig } from '@nativescript/vite';

export default defineConfig(({ mode }): UserConfig => {
	return mergeConfig(angularConfig({ mode }), {});
});

Solid

ts
import { defineConfig, mergeConfig, UserConfig } from 'vite';
import { solidConfig } from '@nativescript/vite';

export default defineConfig(({ mode }): UserConfig => {
	return mergeConfig(solidConfig({ mode }), {});
});

Svelte

ts
import { defineConfig, mergeConfig, UserConfig } from 'vite';
import { solidConfig } from '@nativescript/vite';

export default defineConfig(({ mode }): UserConfig => {
	return mergeConfig(solidConfig({ mode }), {});
});

React

ts
import { defineConfig, mergeConfig, UserConfig } from 'vite';
import { reactConfig } from '@nativescript/vite';

export default defineConfig(({ mode }): UserConfig => {
	return mergeConfig(reactConfig({ mode }), {});
});

TypeScript (XML view)

ts
import { defineConfig, mergeConfig, UserConfig } from 'vite';
import { typescriptConfig } from '@nativescript/vite';

export default defineConfig(({ mode }): UserConfig => {
	return mergeConfig(typescriptConfig({ mode }), {});
});

The above config configures most things required to bundle a NativeScript application.

This page contains examples of common things you might want to change in the Examples of configurations section - for anything else not mentioned here, refer to the Vite documentation.

CLI Flags

When running a NativeScript app the following flags have an effect on the final vite config

--no-hmr

Disable HMR (enabled by default)

--env.verbose

Prints verbose logs and the internal config before building

Additional flags

Additional env flags that are usually passed by the CLI automatically

  • --env.appPath - path to the app source (same as appPath in the nativescript.config.ts)
  • --env.appResourcesPath - path to App_Resources (same as appResourcesPath in the nativescript.config.ts)
  • --env.nativescriptLibPath - path to the currently running CLI's library.
  • --env.android - true when running on android
  • --env.ios - true when running on ios
  • --env.platform=<platform> - for specifying the platform to use. Can be android or ios, or a custom platform in the future.
  • --env.hmr - true when building with HMR enabled

Global "magic" variables

We define a few useful globally available variables that you can use to alter logic in your applications.

  • __DEV__ - true when webpack is building in development mode
    ts
    if (__DEV__) {
      // we are running a dev build
    }
  • __ANDROID__, true when the platform is Android
    ts
    if (global.isAndroid) {
      // we are running on android
    }
  • __IOS__, true when the platform is iOS
    ts
    if (__IOS__) {
      // we are running on iOS
    }
The following variables are also defined, but are primarily intended to be used by NativeScript Core internally, or plugins that wish to use these.
  • __NS_ENV_VERBOSE__ - true when --env.verbose is set
  • __CSS_PARSER__ - the CSS parser used by NativeScript Core. The value is set based on the cssParser value in the nativescript.config.ts and defaults to css-tree
  • __UI_USE_XML_PARSER__ - a flag used by NativeScript Core to disable the XML parser when it's not used
  • __UI_USE_EXTERNAL_RENDERER__ - a flag used by NativeScript Core to disable registering global modules when an external renderer is used.

Configuration examples

Here are some common examples of things you may want to do in your vite.config.ts.

Adding a copy rule

ts
import { defineConfig, mergeConfig, UserConfig } from 'vite';
import { typescriptConfig } from '@nativescript/vite';
import path from 'path';
import { viteStaticCopy } from 'vite-plugin-static-copy';

export default defineConfig(({ mode }): UserConfig => {
	const base = typescriptConfig({ mode });
	const projectRoot = path.resolve(__dirname);
	const testImagePath = path.resolve(projectRoot, 'src/ui/image/700x50.png');
	return mergeConfig(base, {
		plugins: [
      viteStaticCopy({
				targets: [{ src: testImagePath, dest: 'ui/image' }],
			})
    ],
	});
});

Plugin API

NativeScript plugins can provide a nativescript.vite.mjs file in their root folder (next to package.json), and @nativescript/vite will include these configs when resolving the final config.

For example, a plugin could return custom processing:

js
import { createRequire } from "module";
const require = createRequire(import.meta.url);

let postcssConfig = "./postcss.config.js";

try {
  const twV4 = require("@tailwindcss/postcss");
  const nsTailwind = require("@nativescript/tailwind");
  postcssConfig = { plugins: [twV4, nsTailwind] };
} catch (e2) {
  console.warn(
    "Inline PostCSS unavailable, falling back to ./postcss.config.js"
  );
}

export default () => {
  return {
    css: {
      postcss: postcssConfig,
    },
  };
};