State & Data
State management (Pinia)
npm install pinia @vue/devtools-api
npx vastx-native init android # re-wires the bootstrap now that pinia is present
import { defineStore } from 'pinia'
import { ref } from 'vue'
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
function increment() { count.value++ }
return { count, increment }
})
vastx-native init/create detects a pinia dependency and wires createApp(RootFrame).use(createPinia()) into the generated bootstrap automatically. This works because Pinia's core is pure Vue reactivity with no DOM dependency at all, and every DOM/devtools-only code path it has is gated behind a typeof window !== 'undefined' check that's simply always false in NativeScript's runtime.
Not every Nuxt module works this way — most inject their functionality through Nuxt's own Vite/Nitro build hooks, which the native build never runs at all. Pinia works because its actual logic has neither dependency; check the same before adding another module.
Third-party backends (Supabase)
@supabase/supabase-js and its sub-packages (auth/postgrest/storage/functions) are plain JS/TS — no native Android/iOS code at all, so there's no linking step:
npm install @supabase/supabase-js
Database queries, auth, storage, and edge functions work as-is: every one of them falls back to a bare fetch(...) call if not overridden, and NativeScript's own @nativescript/core/globals already installs a real global.fetch/Headers/Request/Response. The auth client's session storage falls back to in-memory unless you give it a real one:
import { createClient } from '@supabase/supabase-js'
import { getString, setString, remove } from '@nativescript/core/application-settings'
const nativeStorage = {
getItem: (key: string) => getString(key, ''),
setItem: (key: string, value: string) => setString(key, value),
removeItem: (key: string) => remove(key)
}
export const supabase = createClient(
'https://YOUR-PROJECT.supabase.co',
'YOUR-ANON-KEY',
{ auth: { storage: nativeStorage } }
)
Realtime (supabase.channel(...)) needs one more piece — @supabase/realtime-js requires a global WebSocket constructor, which NativeScript doesn't have. It accepts a custom options.transport, so this is solvable with an adapter wrapping useWebSocket()'s native mechanism — not shipped yet.
MCP client (useMcpClient())
Apps built with vastx-native can connect to MCP servers and call their tools:
<script setup lang="ts">
import { useMcpClient } from 'vastx-native/runtime/composables/useMcpClient.js'
const mcp = useMcpClient()
await mcp.connect('https://your-mcp-server.example.com/mcp')
const tools = await mcp.listTools()
const result = await mcp.callTool('search', { query: 'vastx native' })
</script>
This implements MCP's "Streamable HTTP" transport in its non-streaming mode — the only mode a NativeScript app can actually speak (the runtime has fetch/XMLHttpRequest but no WebSocket and no EventSource). A server that insists on streaming responses gets a clear error, not a silent hang.
Real-time networking (useWebSocket())
<script setup lang="ts">
import { useWebSocket } from 'vastx-native/runtime/composables/useWebSocket'
const ws = useWebSocket('wss://your-server.example.com/socket', {
onOpen: () => console.log('connected'),
onMessage: (data) => console.log('got:', data),
onClose: (code, reason) => console.log('closed', code, reason)
})
ws.send('hello')
</script>
Import this one without a .js suffix, unlike every other composable (a real, confirmed resolution-order interaction between this package's exports field and webpack's platform-extension list).
NativeScript has no global WebSocket, and no maintained NativeScript WebSocket plugin exists on npm. This talks to each platform's real native WebSocket capability directly: Android via OkHttp, iOS via NSURLSessionWebSocketTask (a first-party OS API since iOS 13).
Verification status, honestly: the Android implementation is fully verified on real hardware — real webpack build, real Gradle assemble, real adb install, a real Node.js WebSocket server bridged over USB, live message round-trips confirmed on-device. The iOS implementation is a real, best-effort implementation against Apple's documented API, reviewed the same way, but not yet compiled or run on a device.