Este artículo solo está disponible en inglés. Estamos trabajando en traducciones al español.

Ingeniería 6 min de lectura

Vue Native: Build Real Native iOS & Android Apps with Vue 3 Composition API

Vue Native is a framework for building truly native mobile apps using Vue 3. Learn how its custom renderer bridges Vue components to UIKit and Android Views.

T

thelacanians

The Mobile Framework You Actually Want

Every few years the JavaScript ecosystem produces a new “write once, run anywhere” mobile framework. Most of them mean “write once, debug everywhere in a WebView.” Vue Native is not that.

Vue Native is a framework for building genuinely native iOS and Android applications using Vue 3. Not a Cordova wrapper. Not an Electron shell shrunk to pocket size. A custom Vue renderer that maps your components directly to UIKit views on iOS and Android Views on Android. The button your user taps is a real UIButton, not a <div> pretending to be one.

If you already know Vue, you already know most of Vue Native. That is the point.

How It Works

The architecture is worth understanding because it explains why this is not just another hybrid framework:

Vue SFC → Vue Custom Renderer → TypeScript Bridge (JSON batch)

                          iOS: Swift → UIKit + Yoga Layout
                          Android: Kotlin → Android Views + FlexboxLayout

Your Vue single-file components go through a custom renderer — not the DOM renderer you use on the web, but one that emits native view operations. These operations cross the bridge in batched JSON messages to platform-specific runtimes written in Swift and Kotlin. The native side creates and updates real platform views.

The layout engine is Yoga on iOS and FlexboxLayout on Android, so you get consistent cross-platform behavior from flexbox-style properties. No CSS parser, no browser engine, no WebView. Just native views positioned by a layout engine that understands the same flexbox model you already think in.

Vue 3 All the Way Down

Vue Native is built on Vue 3, not a subset of it. Full Composition API. <script setup>. ref, computed, watch, watchEffect — all of it. If you have been writing Vue 3 on the web, the mental model transfers completely.

Here is a counter that renders entirely with native UI components:

<script setup lang="ts">
import { ref } from '@vue-native/runtime'
import { createStyleSheet } from '@vue-native/runtime'

const count = ref(0)

const styles = createStyleSheet({
  container: {
    flex: 1,
    padding: 24,
    justifyContent: 'center',
    alignItems: 'center',
  },
  title: {
    fontSize: 28,
    fontWeight: 'bold',
    marginBottom: 16,
  },
  button: {
    backgroundColor: '#0F3460',
    paddingHorizontal: 32,
    paddingVertical: 14,
    borderRadius: 12,
  },
})
</script>

<template>
  <VView :style="styles.container">
    <VText :style="styles.title">Count: {{ count }}</VText>
    <VButton :style="styles.button" @press="count++">
      <VText style="color: #fff; fontSize: 22">Increment</VText>
    </VButton>
  </VView>
</template>

VView, VText, VButton — these are not HTML elements with native styling applied. They are direct mappings to platform views. On iOS, VButton becomes a UIButton. On Android, a MaterialButton. The reactivity system is identical to web Vue. The rendering target is completely different.

Native Modules as Composables

This is where Vue Native gets interesting. Platform APIs — camera, haptics, geolocation, biometrics, notifications, network status — are exposed as Vue composables. No bridging boilerplate. No platform-specific plugins to install and configure.

<script setup lang="ts">
import { ref } from 'vue'
import { useNetwork, useHaptics } from '@vue-native/runtime'

const { isConnected } = useNetwork()
const { vibrate } = useHaptics()

const posts = ref([
  { id: 1, author: 'Ada', content: 'First post', liked: false },
  { id: 2, author: 'Grace', content: 'Compiling thoughts', liked: false },
])
const refreshing = ref(false)

function toggleLike(post: typeof posts.value[0]) {
  if (!post.liked) vibrate('light')
  post.liked = !post.liked
}

async function onRefresh() {
  refreshing.value = true
  // fetch new posts...
  refreshing.value = false
}
</script>

<template>
  <VView v-if="!isConnected" style="backgroundColor: #FF3B30; padding: 8">
    <VText style="color: #FFF">No internet connection</VText>
  </VView>

  <VScrollView :refreshing="refreshing" @refresh="onRefresh">
    <VView v-for="post in posts" :key="post.id" style="padding: 16">
      <VText style="fontWeight: bold">{{ post.author }}</VText>
      <VText>{{ post.content }}</VText>
      <VButton :onPress="() => toggleLike(post)">
        <VText>{{ post.liked ? '❤️' : '🤍' }} Like</VText>
      </VButton>
    </VView>
  </VScrollView>
</template>

useNetwork() returns reactive connection state. useHaptics() gives you a vibrate function that triggers actual haptic feedback on the device. VScrollView supports pull-to-refresh natively. The entire interaction model is platform-native, exposed through an API that any Vue developer can read without documentation.

The full set of built-in composables includes useCamera(), useGeolocation(), useBiometry(), useNotifications(), and more. Each wraps the corresponding platform API in a reactive interface that feels like it belongs in the Vue ecosystem because it does.

20 Built-In Components

Vue Native ships with a component library that covers the fundamentals of mobile UI:

  • Layout: VView, VScrollView, VList
  • Text and Input: VText, VInput, VButton
  • Media: VImage
  • Controls: VSwitch, VSlider
  • Overlays: VModal

These are not styled web components. Each one maps to platform-specific views and respects platform conventions. A VSwitch looks and behaves like a native toggle on both iOS and Android. A VModal presents as a native modal sheet, not a positioned <div> with a backdrop.

Hot Reload on Device

Vue Native supports hot reload on physical devices. Change a component, save the file, see the update on your phone. Not a full app restart — actual hot module replacement applied to the native view tree. The feedback loop is fast enough that you can iterate on layout and interaction design without the context-switching penalty of rebuild-and-reinstall cycles.

Why This Matters

The mobile development landscape has been split between two camps for a long time: go fully native with Swift/Kotlin and maintain two codebases, or use a cross-platform framework and accept the compromises. React Native proved that a JavaScript-driven approach can produce genuinely native results, but it comes with its own ecosystem, its own idioms, and its own learning curve.

Vue Native applies the same architectural insight — a custom renderer bridging to native views — but builds on Vue 3 instead. For teams already invested in Vue, this is significant. Your web developers can contribute to mobile features without learning a new framework. Your component patterns, state management conventions, and TypeScript interfaces transfer directly.

We are paying attention to Vue Native because it aligns with something we care about deeply: production-grade code that does not sacrifice developer experience. The framework does not hide the native platform behind abstractions that leak under pressure. It exposes native capabilities through an API that Vue developers already understand.

The gap between “it works in a demo” and “it works in production” is where most cross-platform frameworks fail. Vue Native’s approach — real native rendering, typed APIs, platform composables that map directly to system frameworks — suggests it is built for the latter. We will be watching closely as the ecosystem matures, and we will be building with it.