| title | Configuring your Project | ||||
|---|---|---|---|---|---|
| contributors |
|
The nativescript.config.ts is a central place to configure your project. It allows you to configure your project structure, application id, runtime related flags and more.
::: info Note about the .ts extension
You can author the config file as plain .js file as well. We recommend sticking with the .ts extension even if your project doesn't use TypeScript, because most editors will provide autocompletion in the .ts file.
:::
By default a config looks somewhat like the following
import { NativeScriptConfig } from '@nativescript/core'
export default {
id: 'org.nativescript.app',
appPath: 'app',
appResourcesPath: 'App_Resources',
android: {
v8Flags: '--expose_gc',
markingMode: 'none',
},
} as NativeScriptConfigid: string = 'com.mycompany.myapp'Controls the Application ID of your app, this setting can be overridden per platform via ios.id, android.id and linux.id.
main: string = './src/custom-main.ts'Sets the entry point to your app. This value is usually set in package.json in the main field.
appPath: string = 'custom-src'Specifies where your app source is located, usually src or app.
appResourcesPath: string = '../shared/app_resources'Specifies where your app resources are located, usually App_Resources.
webpackConfigPath: string = 'custom-webpack.config.js'Specifies the webpack config location. The default is webpack.config.js in the root.
projectName: string = 'projectName'Specifies the name of the project. The default is the basename of the project directory.
profiling: 'counters' | 'timeline' | 'lifecycle' = "timeline"Enable profiler logs. In most cases when profiling, you would use timeline.
cssParser: 'rework' | 'nativescript' | 'css-tree' = "css-tree"Set the default CSS parser that NativeScript will use, by default it uses css-tree.
ignoredNativeDependencies: string[] = ['@nativescript/imagepicker']A list of npm package names to ignore when attaching native dependencies to the build.
cli: Object = {}See CLI Configuration Reference
android: Object = {}See Android Configuration Reference
ios: Object = {}See iOS Configuration Reference
linux: Object = {}See Linux Configuration Reference
hooks: Array = []See Hooks Configuration Reference
NativeScript supports dynamic import() from remote URLs. This is useful during development but carries security implications in production since NativeScript code has direct access to native platform APIs (file system, keychain, network, camera, etc.).
| Mode | Remote Modules |
|---|---|
| Debug | β Always allowed |
| Production | β Blocked by default |
If you need remote ES modules in production, explicitly opt-in:
import { NativeScriptConfig } from '@nativescript/core'
export default {
id: 'org.nativescript.myapp',
appPath: 'src',
security: {
allowRemoteModules: true,
},
} as NativeScriptConfigRestrict to specific trusted origins:
export default {
// ...
security: {
allowRemoteModules: true,
remoteModuleAllowlist: [
'https://cdn.yourcompany.com/modules/',
'https://esm.sh/@yourorg/',
],
},
} as NativeScriptConfigThe allowlist uses prefix matching β a URL is allowed if it starts with any entry.
- Keep production secure by default - Don't enable unless necessary
- Use narrow allowlists - Specific paths, not broad domains
- Pin versions in URLs - Use immutable, versioned URLs
- Never use user-controlled URLs - Injection vulnerability risk
For comprehensive security guidance, see the Security Guide.
::: tip Note
yarn2 is experimental and available in nativescript@8.5.0 or newer.
:::
cli.packageManager: 'npm' | 'yarn' | 'pnpm' | 'yarn2' = 'yarn';Sets the package manager to use for this project.
Defaults to the package manager set with the CLI (ns package-manager set yarn), or npm if not set.
pathsToClean?: string[];Overrides the files or paths to clean when running the ns clean command.
additionalPathsToClean?: string[];Additional files or paths to clean when running the ns clean command, the paths are appended to the default list of paths.
android.id: string = 'com.mycompany.myapp.android';Controls the Application ID of your Android app, this setting overrides the value set in id.
See also ios.id.
android.discardUncaughtJsExceptions: boolean = true;Discard any uncaught JS exceptions. This can be useful in production environments where you don't want your app to crash in case an unexpected JS exception is thrown.
android.v8Flags: string = "--expose_gc --trace=true";Flags passed to the v8 runtime. --expose_gc is required for the runtime to function properly.
For a list of available v8 flags see this Gist.
android.codeCache: boolean = true;Enables the v8 code-cache.
android.gcThrottleTime: number = 20; // in msTrigger a gc periodically (in ms). Defaults to 0 (disabled).
android.markingMode: 'none' | 'full';Sets the default gc marking mode, defaults to none.
::: warning Deprecated value
full has been deprecated and it's not recommended.
:::
android.handleTimeZoneChanges: boolean = true;Notify the app when the timezone changes, defaults to false.
android.maxLogcatObjectSize: number = 9999;Sets the max length of a single output string. Defaults to 1024.
android.forceLog: boolean = true;Enable logging in Release mode. Defaults to false.
android.memoryCheckInterval: number; // in msSets the frequency of the freeMemoryRatio check.
android.freeMemoryRatio: number;Percentage of memory (0.0 to 1.0) before it forces a GC. Defaults to 0 (disabled).
When set, it also requires memoryCheckInterval to be set.
android.enableLineBreakpoints: boolean;Used for advanced debugging.
android.enableMultithreadedJavascript: boolean;Enable the multithreaded JavaScript engine. Defaults to false.
ios.id: string = 'com.mycompany.myapp.ios';Controls the Bundle Identifier of your iOS app, this setting overrides the value set in id.
See also android.id.
ios.discardUncaughtJsExceptions: boolean = true;Discard any uncaught JS exceptions. This can be useful in production environments where you don't want your app to crash in case an unexpected JS exception is thrown.
::: tip
SPM packages are available in nativescript@8.5.0 or newer.
:::
ios.SPMPackages: Array<{
name: string;
libs: Array<string>;
repositoryURL: string;
version: string;
/**
* (8.9+) If you have more targets (like widgets for example),
* you can list their names here to include the Swift Package with them.
*/
targets?: string[];
}>Allows defining Swift Package Manager dependencies that should be installed into the project. Any dependencies listed here, similar to Cocoapods dependencies will be built with the project. This means you can generate typings for them via ns typings ios for TypeScript usage.
// ...
ios: {
SPMPackages: [
{
name: 'swift-numerics',
libs: ['Numerics'],
repositoryURL: 'https://github.com/apple/swift-numerics.git',
version: '1.0.0',
},
]
}::: tip
NativeSource config option is available in nativescript@8.9.0 or newer.
:::
ios.NativeSource: Array<{
name: string;
path: string;
}>Include any native source code from anywhere in the project (or workspace). Glob patterns are fully supported.
- Include any
.swiftfiles anywhere within the projectsrcdirectory:
// ...
ios: {
NativeSource: [
{
name: 'ProjectPlatformSrc',
path: './src/**/*.swift'
}
],
}This will create a file reference folder named ProjectPlatformSrc within the generated Xcode project containing any .swift files found anywhere within the project src directory.
- Include any
.swiftfiles anywhere within the projectsrcdirectory, including any (Swift, Obj-C impl/headers, as well as any module.modulemap files) within a workspacepackagesorlibsdir:
// ...
ios: {
NativeSource: [
{
name: 'ProjectPlatformSrc',
path: './src/**/*.swift'
},
{
name: 'Auth',
path: '../../packages/**/*.{swift,m,h,modulemap}'
},
{
name: 'Purchasing',
path: '../../libs/**/*.{swift,m,h,modulemap}'
}
],
}::: warning Experimental The Linux platform is experimental. See Developing for Linux. :::
linux.id: string = 'org.mycompany.MyApp';Controls the app id on Linux, this setting overrides the value set in id. It names the app's desktop entry (<id>.desktop), icon and install folder, and must be a reverse DNS name (letters, digits, _ and -, separated by dots).
linux.window: {
width?: number
height?: number
minWidth?: number
minHeight?: number
resizable?: boolean
title?: string
} = {}The initial size of the app's windows, in logical pixels, and their minimum size. Defaults to 1024 by 768, resizable, with the app name as the title.
export default {
// ...
linux: {
window: {
width: 1280,
height: 800,
minWidth: 480,
minHeight: 360,
},
},
} as NativeScriptConfiglinux.appearance: 'system' | 'light' | 'dark' = 'system';Keeps the app's native controls light or dark, whatever the desktop uses. Defaults to 'system', which follows the desktop.
linux.v8Flags: string = '--expose_gc';V8 flags set before the runtime starts. During development, the NS_V8_FLAGS environment variable adds to them.
linux.bundle: boolean = true;When enabled, release builds pack the app's files into one read-only app.nsbundle next to the executable. App code reads it with the usual file APIs, and writing to app files fails. Debug builds always use a plain folder. Defaults to true.
linux.bundleUnpack: string[] = ['fonts/**'];Globs, relative to the app folder, of files that are kept as real files in app.nsbundle.unpacked, for code that opens them by path. Native addons (.node and .so files) are always unpacked. Defaults to ['fonts/**'].
linux.sourceProtect: boolean = true;When enabled, release builds encrypt the app.nsbundle with a key generated for each build and embedded in the executable, so the app's sources aren't shipped readable. Defaults to false.
This can be overridden per build with --source-protect or --no-source-protect. The encryption key can be provided with --source-protect-key-hex <key> or the NS_LINUX_BUNDLE_KEY environment variable. If source protection is requested and can't be applied, the build fails.
linux.fuses: {
bundleIntegrity?: boolean
onlyLoadAppFromBundle?: boolean
inspector?: boolean
envOverrides?: boolean
} = {}Settings written into the executable of release builds:
bundleIntegrity- refuse anapp.nsbundlethat doesn't match the build. Defaults totruewhen the app is bundled.onlyLoadAppFromBundle- only run the app fromapp.nsbundle, never from a plain app folder. Defaults totruewhen the app is bundled.inspector- allow attaching a debugger with--inspect. Defaults tofalse.envOverrides- honor the runtime's command line flags and environment variables (such asNS_V8_FLAGS). Defaults tofalse.
hooks: [
{
type: 'before-<hookName>' | 'after-<hookName>',
script: './path/to/script.js',
},
]Allows defining project-persistent hooks.
Available hooks (prefix with before- or after-):
buildAndroidPlugin- Builds aar file for Android plugin, runs duringprepareNativeAppbuildAndroid- Builds Android appbuildIOS- Builds iOS appcheckEnvironment- Validate project env, runs duringns doctor,ns clean, and most build commandscheckForChanges- Changes occurred duringwatchinstall- Application installed to device/emulatorprepare- Compiles webpack and prepares native app in platforms folderprepareNativeApp- Preparing the actual native app, runs duringprepare/watchhookresolveCommand- Resolves command and arguments, runs before all CLI commandswatch- Set up watchers for live sync, runs duringpreparehookwatchPatterns- Set up watch patterns, runs duringwatchhook
NativeScript provides security configuration options to control sensitive runtime behaviors, particularly around remote code execution via ES module imports.
::: tip For comprehensive security guidance and best practices, see the Security Guide. :::
security.allowRemoteModules: boolean = false;Enable remote ES module loading in production builds.
| Mode | Remote Modules |
|---|---|
| Debug (local development) | β Always allowed |
| Production (Release builds) | β Blocked by default |
When false (the default), any attempt to import("https://...") in production will throw an error. This is a security measure because NativeScript code has direct access to native platform APIs (file system, keychain, network, camera, etc.).
export default {
// ...
security: {
allowRemoteModules: true,
},
} as NativeScriptConfig::: warning Security Implications Remote modules bypass App Store/Play Store code review and can access any native API your app has access to. Only enable this if you have a specific, justified need and understand the implications. :::
security.remoteModuleAllowlist: string[] = [];Restrict remote modules to specific URL prefixes. Only used when allowRemoteModules is true.
The allowlist uses prefix matching β a URL is allowed if it starts with any entry in the list.
export default {
// ...
security: {
allowRemoteModules: true,
remoteModuleAllowlist: [
'https://cdn.yourcompany.com/modules/',
'https://esm.sh/@yourorg/',
],
},
} as NativeScriptConfig| Allowlist Entry | Allowed URLs | Blocked URLs |
|---|---|---|
https://cdn.example.com/ |
https://cdn.example.com/mod.js |
https://other.com/mod.js |
https://esm.sh/@myorg/ |
https://esm.sh/@myorg/pkg |
https://esm.sh/@other/pkg |
https://unpkg.com/ |
https://unpkg.com/lodash |
http://unpkg.com/lodash (http blocked) |
If the allowlist is empty or not provided (and allowRemoteModules is true), all HTTPS URLs are allowed β this is not recommended for production.
When remote module loading is blocked, you'll see clear error messages:
// Remote modules disabled
Remote ES modules are not allowed in production. URL: https://example.com/mod.js.
Enable via security.allowRemoteModules in nativescript.config.ts
// URL not in allowlist
Remote URL not in security.remoteModuleAllowlist: https://untrusted.com/mod.js
- Keep production secure by default β Don't enable
allowRemoteModulesunless necessary - Use narrow allowlists β Specific paths, not broad domains
- Pin versions in URLs β Use immutable, versioned URLs over mutable endpoints
- Never use user-controlled URLs β Avoid injection vulnerabilities
For more details on security implications and additional best practices, see the Security Guide.