Back to Nativescript

README

packages/vite/README.md

9.1.1-core5.6 KB
Original Source
<p align="center"> <a href="https://nativescript.org"> </a> </p> <h1 align="center">@nativescript/vite</h1> <p align="center"> <b>Vite integration for NativeScript apps.</b> </p> <p align="center"> <a href="https://www.npmjs.com/package/@nativescript/vite"></a> <a href="https://github.com/NativeScript/NativeScript/blob/main/LICENSE"></a> </p> <p align="center"> <a href="https://docs.nativescript.org/configuration/vite">Documentation</a> · <a href="https://docs.nativescript.org/setup/">Environment Setup</a> · <a href="https://github.com/NativeScript/NativeScript/blob/main/tools/notes/CONTRIBUTING.md">Contribute</a> · <a href="https://nativescript.org/discord">Community</a> </p>

Prerequisites

  • NativeScript 9 or higher

Install

sh
npm i @nativescript/vite -D

Quick start (init)

To bootstrap an existing NativeScript app for Vite, run from your app root:

bash
npx nativescript-vite init

This will:

  • Generate a vite.config.mts using the detected project flavor (Angular, Vue, React, Solid, TypeScript, or JavaScript) and the corresponding helper subpath from @nativescript/vite.
  • Add the dependency @valor/nativescript-websockets.
  • Append .ns-vite-build to .gitignore if it is not already present.

After running init, you have two ways to work with Vite:

  1. HMR workflow (default — the CLI starts the dev server for you)
bash
ns debug ios
ns debug android
  1. Standard dev workflow (non-HMR)
bash
ns debug ios --no-hmr
ns debug android --no-hmr

Android: automatic adb reverse

For Android HMR the CLI automatically runs adb reverse tcp:<port> tcp:<port> for the session's dev-server port (using the SDK-resolved adb, scoped to the deploy target, after the device is ready) so the device reaches the dev server through the ADB tunnel at 127.0.0.1:<port>. Relevant opt-outs:

  • NS_HMR_NO_ADB_REVERSE=1 — skip the tunnel and use 10.0.2.2.
  • NS_HMR_PREFER_LAN_HOST=1 — physical device over Wi-Fi; emit the host's LAN IP.
  • NS_HMR_HOST=<host[:port]> — point the device at an explicit origin (CI / tunnels).

Custom HMR sessions

The CLI picks the dev-server settings for each session on its own:

  • Port — the first free port at or above NS_HMR_PORT (default 5173), the same way vite moves off a busy port. Whatever it picks is baked into the device URLs, bound by the dev server and (on Android) tunnelled with adb reverse, so all three always agree.
  • Staging directory.ns-vite-build/<platform>, so iOS and Android builds never overwrite each other's output.

Both can still be pinned explicitly:

Environment variablePurposeDefault
NS_HMR_PORTPreferred Vite dev-server port; the CLI moves to the next free port when it is taken5173
NS_HMR_STRICT_PORTFail instead of moving when NS_HMR_PORT is taken (Vite's strictPort) — for tunnels / CI that forward a fixed portunset
NS_VITE_DIST_DIRProject-relative staging directory used for Vite output before the NativeScript CLI copies it into the platform app.ns-vite-build/<platform>

The environment settings only need to be visible to the ns process — the CLI propagates them (and the values it picks) to the dev server it spawns.

Running two platforms at once

Start both; nothing to configure:

bash
# Terminal 1
ns debug ios       # dev server on 5173

# Terminal 2
ns debug android   # 5173 is busy → dev server on 5174

Each session gets its own port and staging directory. Older CLIs that don't pick ports need them set by hand per terminal:

bash
# Terminal 1: iOS
NS_HMR_PORT=5173 NS_VITE_DIST_DIR=.ns-vite-build/ios ns debug ios

# Terminal 2: Android
NS_HMR_PORT=5174 NS_VITE_DIST_DIR=.ns-vite-build/android ns debug android

The inline environment syntax above is for POSIX shells; use the equivalent assignment on Windows.

Advanced: running vite serve yourself

The dev server is just vite serve -- --env.<platform> --env.hmr. You can run it standalone for diagnostics, but do not run it alongside ns run/ns debug for the same platform — both would try to bind the same port. CLI-managed is the supported default.

Usage

  1. Create vite.config.mts (the .mts extension keeps the config ESM without setting "type": "module" in the app's package.json, avoiding Vite's configLoader: 'native' warning):
ts
import { defineConfig, mergeConfig, UserConfig } from 'vite';
import { typescriptConfig } from '@nativescript/vite/typescript';

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

Framework-specific configs should be imported from their matching subpaths to avoid loading unrelated framework tooling:

ts
import { angularConfig } from '@nativescript/vite/angular';
import { reactConfig } from '@nativescript/vite/react';
import { solidConfig } from '@nativescript/vite/solid';
import { vueConfig } from '@nativescript/vite/vue';
  1. Update nativescript.config.ts:
ts
import { NativeScriptConfig } from '@nativescript/core';

export default {
	// add these:
	bundler: 'vite',
	bundlerConfigPath: 'vite.config.mts',
} as NativeScriptConfig;
  1. Enjoy Vite.

Explore More

Check out the NativeScript Vite documentation for more configuration options and features.