DEV Community

Cover image for How does VuReact compile Vue 3's readonly() to React?
Ryan John
Ryan John

Posted on • Originally published at vureact.top

How does VuReact compile Vue 3's readonly() to React?

VuReact is a tool that compiles Vue 3 code into standard, maintainable React code. In this article, we will look at another common Vue API: readonly().

If you write readonly() in Vue, what does VuReact generate on the React side?

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 the API shape and core behavior of Vue 3 readonly.

Compilation Mapping

Vue readonly() -> React useReadonly()

readonly() is Vue 3's API for creating a deeply readonly reactive copy. It returns a reactive object that cannot be mutated directly.

VuReact compiles that pattern into useReadonly(), so React can preserve the same protection model.

  • Vue
<script setup>
import { reactive, readonly } from 'vue';

const original = reactive({
  count: 0,
  nested: { text: 'Hello' },
});

const readonlyCopy = readonly(original);
</script>
Enter fullscreen mode Exit fullscreen mode
  • Compiled React
import { useReactive, useReadonly } from '@vureact/runtime-core';

const original = useReactive({
  count: 0,
  nested: { text: 'Hello' },
});

const readonlyCopy = useReadonly(original);
Enter fullscreen mode Exit fullscreen mode

VuReact's useReadonly is the runtime adapter for readonly(). You can think of it as the React-side equivalent of Vue readonly state, preserving deep readonly behavior. Any attempted mutation on the readonly copy is blocked, and in development mode it can also surface warnings.

Vue shallowReadonly() -> React useShallowReadonly()

shallowReadonly() is the shallow version of readonly protection in Vue 3. It prevents writes to top-level properties while leaving nested objects writable.

VuReact maps that behavior to useShallowReadonly().

  • Vue
<script setup>
import { reactive, shallowReadonly } from 'vue';

const state = reactive({
  user: { name: 'React', role: 'Admin' },
});

const shallowRead = shallowReadonly(state);
</script>
Enter fullscreen mode Exit fullscreen mode
  • Compiled React
import { useReactive, useShallowReadonly } from '@vureact/runtime-core';

const state = useReactive({
  user: { name: 'React', role: 'Admin' },
});

const shallowRead = useShallowReadonly(state);
Enter fullscreen mode Exit fullscreen mode

VuReact's useShallowReadonly is the runtime adapter for shallowReadonly(). In practice, that means top-level properties cannot be reassigned, while nested objects still keep their original references and remain writable inside.

Top comments (0)