How does VuReact optimize Vue 3's top-level constants and variables for React?

Ryan John

Ryan John

2026-06-02T01:12:00Z

2 min read

VuReact is a compiler toolchain for migrating from Vue to React — and for writing React with Vue 3 syntax.

In this article, we will look at how VuReact optimizes top-level constants and variables when compiling Vue 3 code to React.

Before We Start

To keep the examples easy to read, this article follows two simple conventions:

  1. All Vue and React snippets focus on core logic only, with full component wrappers and unrelated configuration omitted.
  2. The discussion assumes you are already familiar with top-level const declarations and variable optimization in Vue 3.

Compilation Mapping

Top-level Vue const -> static hoisting outside the React component

In Vue, top-level constants inside <script setup> are often used for static configuration, default values, and fixed flags.

VuReact performs static analysis on these declarations. If the initializer is a simple literal such as a string, number, or boolean, it can be hoisted outside the React component so it is not recreated on every render.

  • Vue
<script setup lang="ts">
const defaultValue = 1;
const isEnabled = true;
</script>
Enter fullscreen mode Exit fullscreen mode
  • Compiled React
const defaultValue = 1;
const isEnabled = true;

const Comp = memo(() => {
  return <></>;
});
Enter fullscreen mode Exit fullscreen mode

For simple top-level constants, VuReact lifts the value out of the component body and avoids repeated initialization during re-renders.

Top-level computed variables -> React useMemo() with automatic dependency analysis

When a top-level variable is derived from an expression that depends on reactive state, VuReact can compile it into useMemo() and generate the dependency array automatically.

Purely static expressions are left as normal values instead of being wrapped unnecessarily.

  • Vue
<script setup lang="ts">
const count = ref(0);
const state = reactive({ foo: 'bar', bar: { c: 1 } });

const memoizedObj = {
  title: 'test',
  bar: count.value,
  add: () => {
    state.bar.c++;
  },
};

const staticObj = {
  foo: 1,
  state: { bar: { c: 1 } },
};

const reactiveList = [count.value, 1, 2];
</script>
Enter fullscreen mode Exit fullscreen mode
  • Compiled React
const count = useVRef(0);
const state = useReactive({ foo: 'bar', bar: { c: 1 } });

const memoizedObj = useMemo(
  () => ({
    title: 'test',
    bar: count.value,
    add: () => {
      state.bar.c++;
    },
  }),
  [count.value, state.bar.c],
);

const staticObj = {
  foo: 1,
  state: {
    bar: { c: 1 },
  },
};

const reactiveList = useMemo(() => [count.value, 1, 2], [count.value]);
Enter fullscreen mode Exit fullscreen mode

In this example:

  1. memoizedObj becomes useMemo() because it depends on count.value and state.bar.c.
  2. staticObj stays a normal static object because it does not depend on reactive state.
  3. reactiveList is also compiled into useMemo() with an automatically generated dependency array.

That gives React the memoization it needs without forcing developers to write dependency logic by hand.

Related Links