cd /news/developer-tools/how-does-vureact-compile-vue-3-s-def… · home topics developer-tools article
[ARTICLE · art-10588] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=· neutral

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

VuReact is a compiler toolchain that converts Vue 3 syntax into React code, specifically mapping Vue 3's `defineExpose()` macro to React's `forwardRef()` and `useImperativeHandle()` combination. When a parent component accesses exposed child values through a ref, VuReact translates Vue's `ref` and `expose` pattern into React's `useRef()` and `ref.current` syntax, preserving the structure and interaction model of the original Vue code.

read2 min views26 publishedMay 23, 2026

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 Vue 3's defineExpose()

macro is mapped into React.

Before We Start #

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

  • All Vue and React snippets focus on core logic only, with full component wrappers and unrelated configuration omitted.
  • The discussion assumes you are already familiar with the API shape and core behavior of Vue 3 defineExpose()

.

Compilation Mapping #

Vue defineExpose()

-> React forwardRef()

  • useImperativeHandle()

defineExpose()

is the macro used inside Vue 3 <script setup>

to expose internal state or methods from a child component to its parent.

VuReact compiles that pattern into React's forwardRef()

plus useImperativeHandle()

, allowing the parent component to access the exposed object through a ref.

  • Vue
<script setup lang="ts">
import { ref, defineExpose } from 'vue';

defineProps<{ title: string }>();

const count = ref(0);
const increment = () => count.value++;

defineExpose({
  count,
  increment,
});
</script>
  • Compiled React
import { forwardRef, useCallback, useImperativeHandle, memo } from 'react';
import { useVRef } from '@vureact/runtime-core';

type IComponentProps = { title: string };

const Component = memo(
  forwardRef<any, IComponentProps>((props, expose) => {
    const count = useVRef(0);

    const increment = useCallback(() => {
      count.value++;
    }, [count.value]);

    useImperativeHandle(expose, () => ({
      count,
      increment,
    }));

    return <div>{count.value}</div>;
  }),
);

export default Component;

As the example shows, Vue defineExpose()

is compiled into React's forwardRef()

and useImperativeHandle()

combination.

VuReact preserves the structure of the exposed object, and exposed refs still use .value

, which keeps the interaction model close to Vue.

Parent access: Vue ref

  • expose -> React ref.current

In Vue, parent components access exposed child values through ref

and expose

. In React, VuReact maps that pattern to useRef()

plus ref.current

.

  • Vue parent
<template>
  <Component ref="childRef" />
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue';

const childRef = ref();

onMounted(() => {
  childRef.value?.count.value; // 0
  childRef.value?.increment();
  childRef.value?.count.value; // 1
});
</script>
  • Compiled React parent
const Parent = () => {
  const childRef = useRef();

  useMounted(() => {
    childRef.current?.count.value; // 0
    childRef.current?.increment();
    childRef.current?.count.value; // 1
  });

  return <Component ref={childRef} />;
};

VuReact keeps the parent access path aligned with the original Vue intent, so exposed child refs and methods remain straightforward to use.

── more in #developer-tools 4 stories · sorted by recency
── more on @vureact 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/how-does-vureact-com…] indexed:0 read:2min 2026-05-23 ·