· product · vesk native

One model. Two worlds.

React Native wraps a JS runtime. Flutter reinvents widgets. Vesk Native reuses your .vsk IR and emits Kotlin — native activities, Compose UI, Material 3, no WebView, no bridge tax.

target graph

.vsk IR
web
DOM · CSS · ESM
kotlin
Compose · Material 3

Same component, same track() state, same Tailwind tokens — different emitter. The compiler is the port.

No WebView

Tauri/Capacitor wrap a browser. Vesk emits platform primitives — accessibility, text selection, and gestures are native, not emulated.

No bridge tax

React Native serializes across a bridge. Vesk compiles directly — fine-grained updates are O(1) on both targets.

Design fidelity

Tailwind + lucide-vesk on web become Compose theming + Material 3 on Android — no shadow DOM mismatches.

vs other cross-platform stacks
Stack Language UI Cost model Share with web
Vesk Native .vsk / TS → Kotlin Compose Material 3 Compile-time; no runtime bridge ~90% model share
React Native JS/TS Native views via bridge Bridge + Yoga ~60-70% (styling diverges)
Flutter Dart Custom renderer (Skia) Own runtime + GC Low — separate codebase
Tauri / Capacitor JS/TS WebView Full browser per window 100% web, 0% native feel
Expo JS/TS RN + managed bridge Bridge + extra abstraction Same as RN

Vesk's pitch is narrow and honest: if your product is content + forms + lists + offline — docs, dashboards, field apps — sharing the IR beats maintaining two apps. For games or highly custom canvases, keep Flutter.

Fieldbook — offline-first field notes

Compiled to Kotlin, cold start 240 ms, works offline with the same useFetch cache + offline.vsk boundaries as web.

Read case study →

Signal Docs — one library, two targets

Same component library renders docs on the web and help screens on Android — 2 targets, 1 model, no design drift.

Read case study →