🚀 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,
    },
  };
};