Vue 3 to Lyt.js Migration Guide: API Compatibility, Template Refactoring, and SSR End-to-End

Lyt.js is a zero-dependency frontend framework implemented in TypeScript. It preserves familiar Vue 3 development patterns while reducing bundle size and introducing Signal, Vapor Mode, and SSR capabilities. This guide focuses on migration steps, compatibility boundaries, and production adoption strategies. Keywords: Vue 3 migration, Lyt.js, SSR.

The technical specification snapshot highlights the migration baseline

Parameter Details
Core language TypeScript
Framework positioning Vue 3-compatible frontend framework
Protocol/ecosystem interfaces Component-based UI, Router, Store, SSR
Core dependencies Zero third-party runtime dependencies
Compressed size Core 8 packages, about 35KB gzip
Comparison baseline Vue 3 core, about 44KB gzip
Compatibility layer @lytjs/compat
Routing solution @lytjs/router
State management @lytjs/store

Juejin

Juejin

Lyt.js delivers migration value by maximizing reuse of Vue 3 knowledge

The core advantage of Lyt.js v5.0.1 is not that it is completely different, but that it is highly similar while being lighter. For Vue 3 teams, migration cost usually concentrates on template directives, a small set of configuration items, and ecosystem package replacement rather than a rewrite of business logic.

It also provides two layers of capability. One layer offers Vue 3 API compatibility, and the other introduces enhanced features such as Signal, Vapor Mode, and built-in SSR. The former lowers the switching barrier, while the latter creates clear performance benefits.

The core APIs can largely be ported directly

Application creation, component definition, lifecycle hooks, computed properties, and most reactive patterns remain consistent. For existing Composition API projects, business-layer code usually does not require structural refactoring.

import { createApp, defineComponent, reactive, computed, onMounted } from '@lytjs/core'

const App = defineComponent({
  setup() {
    const state = reactive({ count: 0 }) // Vue-style reactive object remains compatible
    const doubled = computed(() => state.count * 2) // Computed property syntax stays the same

    onMounted(() => {
      console.log('mounted') // Lifecycle invocation remains unchanged
    })

    return { state, doubled }
  }
})

createApp(App).mount('#app') // Application mounting stays the same

This example shows that at the entry point, component definition, and reactive core layers, Lyt.js introduces very little migration friction compared with Vue 3.

Template syntax refactoring is the primary explicit change

Lyt.js simplifies the v- prefix into a form that is closer to native HTML. This is the easiest part of a migration to identify in bulk and replace automatically. Typical rules include v-if -> if, v-for -> each, v-model -> model, and @click -> on:click.

This change does not affect how you organize state, and it does not change methods, computed properties, or event-handling logic. In other words, the change happens primarily at the template layer, not at the business-logic layer.

Vue template migration can be completed through rule-based replacement

<!-- Vue 3 -->
<div v-if="loading">
  <input v-model="keyword" />
  <li v-for="item in list" :key="item.id" @click="open(item)">
    {{ item.name }}
  </li>
</div>

<!-- Lyt.js -->
<div if="loading">
  <input model="keyword" />
  <li each="item in list" :key="item.id" on:click="open(item)">
    {{ item.name }}
  </li>
</div>

This comparison shows that the template change is a syntax replacement, not a rewrite of rendering concepts.

Component options and the compatibility layer determine migration pace together

If the project still uses the Options API, the most important difference is that data() becomes state(). Beyond that, the structure of computed, methods, watch, props, and emits can remain mostly unchanged.

For large existing codebases, @lytjs/compat is a better first-stage solution. It allows teams to migrate the runtime and build pipeline first, then gradually address template and directory structure issues.

Using compat lets you get the app running first and optimize later

import {
  ref, reactive, computed, watch, onMounted,
  createApp, defineComponent
} from '@lytjs/compat'

export default defineComponent({
  setup() {
    const count = ref(0) // Compatible ref syntax
    const state = reactive({ ready: false })
    const doubled = computed(() => count.value * 2)

    watch(count, () => {
      state.ready = true // Compatible watch behavior
    })

    onMounted(() => {
      console.log(doubled.value)
    })

    return { count, state, doubled }
  }
})

The value of this example is clear: you can preserve the Vue 3 mental model first, then switch to lighter native Lyt.js patterns only when needed.

Router and state management migration remain highly similar

In router migration, interfaces such as createRouter, navigation guards, and programmatic navigation are close to Vue Router. The main detail to note is that history-mode configuration changes from a history instance to a mode option.

Moving from Pinia to @lytjs/store is also straightforward. Conceptually, it still includes state, getters, and actions. The main difference is the initialization API name, along with additional capabilities such as subscription, reset, and destroy.

Ecosystem replacement looks more like package migration than paradigm migration

import { createApp } from '@lytjs/core'
import { createRouter } from '@lytjs/router'
import { createStore } from '@lytjs/store'

const router = createRouter({
  mode: 'history', // Lyt.js uses mode to define the routing mode
  routes: [{ path: '/', component: Home }]
})

const counterStore = createStore({
  name: 'counter',
  state: () => ({ count: 0 }),
  actions: {
    increment() {
      this.count++ // Update state directly inside the action
    }
  }
})

createApp(App).use(router).mount('#app')

This example shows the typical ecosystem transition path: the entry structure remains familiar, while only package names and a small amount of configuration format change.

SSR, Signal, and Vapor Mode are the real gains after migration

If your only goal is to make the project run, the value of Lyt.js may not look dramatic at first. But once the project enters a performance optimization phase, Signal and Vapor Mode become the differentiators. Signal provides fine-grained updates and works well for scenarios with frequent localized refreshes.

At the SSR layer, Lyt.js provides renderToString, streaming rendering, and generator-based output. That makes it more suitable for projects that need first-paint performance, SEO, or hybrid rendering. LytX further fills the gap with meta-framework capabilities similar to Nuxt.

Introduce high-performance features only after the baseline migration is complete

import { signal, computed, batch } from '@lytjs/reactivity'

const count = signal(0)
const doubled = computed(() => count() * 2) // Read the signal value through function invocation

batch(() => {
  count.set(1) // Reduce repeated rendering during batched updates
  count.set(2)
  count.set(3)
})

console.log(doubled()) // Output the latest computed result

This example shows that Signal is best introduced after the migration stabilizes, targeting hot components for focused performance refactoring.

A phased migration strategy reduces engineering risk

In the first phase, replace dependencies and build tooling, and introduce @lytjs/compat first to ensure the project can compile and run. In the second phase, convert .vue files to .lyt in bulk and complete template directive replacement. In the third phase, handle Store, Router, and SSR details.

Only after that should you move to enhanced optimization, including Signal mode, Vapor Mode, DevTools, and UI component system integration. This approach prevents syntax, runtime, and performance strategy changes from piling up in a single migration.

The minimum viable migration command set keeps the rollout predictable

npm uninstall vue vue-router pinia @vitejs/plugin-vue
npm install @lytjs/core @lytjs/router @lytjs/store @lytjs/compiler

# Preview bulk migration results before writing changes to disk
npx @lytjs/compat vue-to-lyt ./src --recursive --dry-run

# Run the actual conversion after confirming the output
npx @lytjs/compat vue-to-lyt ./src --recursive

These commands represent the safest path: replace the infrastructure first, then automate source migration.

The conclusion is that Lyt.js fits Vue teams that want low migration cost and long-term performance headroom

From a practical perspective, Lyt.js offers four major advantages: highly compatible APIs, simplified template syntax, a zero-dependency runtime, and long-term performance gains from Signal, SSR, and Vapor Mode.

For mid-sized and large Vue 3 projects, the best strategy is not a one-shot rewrite. Instead, use @lytjs/compat and CLI tools for a progressive migration. Complete compatibility first, then optimize. That is how you achieve a truly low-friction migration.

FAQ provides structured answers for common migration concerns

Q1: Which parts of a Vue 3 project are most likely to remain unchanged when migrating to Lyt.js?

A: Most Composition API business logic, lifecycle hooks, computed properties, and reactive object patterns can usually be reused directly. The main modifications are concentrated in template directives, import paths, and a small set of ecosystem configuration items.

Q2: Should large projects switch directly to native Lyt.js, or start with compat?

A: Use @lytjs/compat first. It is better suited to multi-module and multi-team collaboration scenarios. It lets you stabilize runtime behavior first, then gradually replace templates, routing, and state management while reducing regression risk.

Q3: What are the core additional benefits of Lyt.js compared with Vue 3?

A: The main value is not API compatibility alone. The real benefits are a smaller footprint, Signal-based fine-grained reactivity, stable Vapor Mode, full SSR support, and template syntax that is closer to native HTML.

The core summary reconstructs the migration path from Vue 3 to Lyt.js end to end

This guide systematically reconstructs the migration path from Vue 3 to Lyt.js, covering API compatibility, template directive differences, router and state management replacement, SSR and build configuration adjustments, and a progressive migration strategy with bulk conversion workflows.