# How to Integrate Apache ECharts with React, Vue, and Angular: A Complete Framework Guide

> Integrate Apache ECharts with React Vue and Angular using thin wrapper libraries for seamless component lifecycle binding. Follow this complete framework guide and delegate rendering to the core echarts package.

- Repository: [The Apache Software Foundation/echarts](https://github.com/apache/echarts)
- Tags: tutorial
- Published: 2026-03-04

---

**Use thin wrapper libraries—echarts-for-react for React, vue-echarts for Vue, and ngx-echarts for Angular—to bind ECharts instances to your component lifecycle while delegating all rendering to the core `echarts` package.**

Integrating Apache ECharts with popular JavaScript frameworks like React, Vue, and Angular requires bridging the library’s imperative API (`echarts.init`, `setOption`, `dispose`) with each framework’s declarative component model. The official `apache/echarts` repository provides framework-agnostic core functionality in [`src/echarts.js`](https://github.com/apache/echarts/blob/main/src/echarts.js), while community-maintained wrappers handle instance creation, updates, and cleanup automatically.

## React Integration with echarts-for-react

The **echarts-for-react** wrapper exposes a `<ReactECharts />` component that instantiates the chart in a `useEffect` hook and destroys it on unmount, mapping React props directly to ECharts configuration options.

### Installation

Install both the core library and the React wrapper:

```bash
npm install echarts echarts-for-react

```

### Basic Implementation

Import the core ECharts namespace and the wrapper component, then pass your `option` object:

```tsx
import React from 'react';
import ReactECharts from 'echarts-for-react';
import * as echarts from 'echarts';

const option = {
  tooltip: { trigger: 'axis' },
  xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] },
  yAxis: { type: 'value' },
  series: [{ name: 'Direct', type: 'bar', data: [10, 52, 200, 334, 390, 330, 220] }]
};

export const BarChart: React.FC = () => (
  <ReactECharts
    option={option}
    style={{ height: 400, width: '100%' }}
    echarts={echarts}
    notMerge={true}
    lazyUpdate={true}
  />
);

```

### Key Configuration Options

- **`notMerge={true}`** – Forces a full re-render when the `option` prop changes, ensuring immutable data patterns trigger visual updates.
- **`lazyUpdate={true}`** – Batches multiple consecutive `setOption` calls for better performance.
- **Instance access** – Forward a ref to call imperative methods like `getInstance()` or `dispatchAction` directly on the underlying ECharts object.

According to the wrapper source at [`src/core/ReactECharts.tsx`](https://github.com/apache/echarts/blob/main/src/core/ReactECharts.tsx), the component automatically handles `echarts.init` during mount and `dispose` during unmount to prevent memory leaks.

## Vue Integration with vue-echarts

The **vue-echarts** wrapper (officially recommended by the ECharts team) provides a `<v-chart>` component compatible with both Vue 2’s `data`/`observable` and Vue 3’s `ref`/`reactive` systems.

### Installation

```bash
npm install echarts vue-echarts

```

### Vue 3 Composition API Example

Bind reactive options using `ref` and pass them to the component:

```vue
<template>
  <v-chart class="chart" :option="option" />
</template>

<script setup>
import { ref } from 'vue';
import VChart from 'vue-echarts';
import * as echarts from 'echarts';

const option = ref({
  tooltip: { trigger: 'axis' },
  xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] },
  yAxis: { type: 'value' },
  series: [{ name: 'Direct', type: 'bar', data: [10, 52, 200, 334, 390, 330, 220] }]
});
</script>

<style scoped>
.chart { height: 400px; width: 100%; }
</style>

```

### Vue 2 Options API Reference

The `apache/echarts` repository includes a working demo in [`test/echarts-in-vue.html`](https://github.com/apache/echarts/blob/main/test/echarts-in-vue.html) (lines 51–84) showing manual initialization:

```html
<script>
new Vue({
  el: '#app',
  data() {
    return {
      option: { /* chart configuration */ }
    };
  },
  mounted() {
    const chart = echarts.init(this.$refs.chart);
    chart.setOption(this.option);
  },
  template: `<div ref="chart" style="height:400px;"></div>`
});
</script>

```

Whether using the wrapper or manual initialization, always import from the core entry point [`src/echarts.js`](https://github.com/apache/echarts/blob/main/src/echarts.js) (ESM) or [`dist/echarts.min.js`](https://github.com/apache/echarts/blob/main/dist/echarts.min.js) (UMD) as declared in the repository’s [`package.json`](https://github.com/apache/echarts/blob/main/package.json).

## Angular Integration with ngx-echarts

**ngx-echarts** supplies a structural directive that binds to the `options` property and manages the chart lifecycle through Angular’s dependency injection system.

### Installation

```bash
npm install echarts ngx-echarts

```

### Module Setup and Component Usage

Register the module with the global ECharts instance in [`app.module.ts`](https://github.com/apache/echarts/blob/main/app.module.ts):

```ts
import { NgxEchartsModule } from 'ngx-echarts';
import * as echarts from 'echarts';

@NgModule({
  imports: [
    BrowserModule,
    NgxEchartsModule.forRoot({ echarts })
  ],
})
export class AppModule {}

```

In your component template, apply the `echarts` directive:

```html
<div echarts [options]="option" class="chart"></div>

```

```ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-chart',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  option = {
    tooltip: { trigger: 'axis' },
    xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] },
    yAxis: { type: 'value' },
    series: [{ name: 'Direct', type: 'bar', data: [10, 52, 200, 334, 390, 330, 220] }]
  };
}

```

The directive source at [`src/lib/echarts.directive.ts`](https://github.com/apache/echarts/blob/main/src/lib/echarts.directive.ts) handles automatic disposal when the component destroys, but you can access the instance via `@ViewChild('chart')` to call `dispatchAction` or `resize` imperatively.

## Common Integration Challenges and Solutions

### Chart Not Resizing on Container Changes

ECharts does not observe DOM mutations automatically. Call `chart.resize()` inside your framework’s resize detection:

- **React**: Use a `ResizeObserver` inside `useEffect`.
- **Vue**: Watch the container size or use `window.onresize`.
- **Angular**: Subscribe to `window.resize` or use the `ngx-echarts` `[merge]` input to trigger updates.

### Memory Leaks from Multiple Instances

Instantiating a new chart without disposing the previous one creates detached DOM nodes. All three wrappers automatically invoke `chart.dispose()` on unmount, but if you manually call `echarts.init()`, you must pair it with `chart.dispose()` before re-initializing.

### ESM vs. UMD Conflicts

Importing `echarts` from a CDN (UMD) while also bundling the npm ESM version causes duplicate code and type conflicts. Use **only one** source: either the CDN script tag pointing to [`dist/echarts.min.js`](https://github.com/apache/echarts/blob/main/dist/echarts.min.js) or `import * as echarts from 'echarts'` in your bundler.

## Summary

- **React**: Use `echarts-for-react` to render charts via `<ReactECharts>` with automatic lifecycle management and imperative ref access.
- **Vue**: Use `vue-echarts` for reactive binding with Composition API (`ref`) or consult [`test/echarts-in-vue.html`](https://github.com/apache/echarts/blob/main/test/echarts-in-vue.html) in the ECharts repo for manual Vue 2 patterns.
- **Angular**: Use `ngx-echarts` with `NgxEchartsModule.forRoot()` to register the global instance and bind options via the `echarts` directive.
- Always call `resize()` when containers change and ensure `dispose()` runs before unmount to prevent memory leaks.
- Import from a single source—either [`src/echarts.js`](https://github.com/apache/echarts/blob/main/src/echarts.js) (ESM) or [`dist/echarts.min.js`](https://github.com/apache/echarts/blob/main/dist/echarts.min.js) (UMD)—to avoid duplicate bundling.

## Frequently Asked Questions

### How do I update chart options reactively in React?

Pass a new `option` object to the `option` prop. Set `notMerge={true}` to replace the entire configuration or omit it to merge updates incrementally. The wrapper detects prop changes and calls `setOption` automatically.

### Can I use ECharts with Vue 3's `<script setup>` syntax?

Yes. Import `VChart` from `vue-echarts` and bind a `ref` to the `:option` attribute. The wrapper is fully compatible with Vue 3 reactivity and the Composition API, as demonstrated in the official ECharts test file [`test/echarts-in-vue.html`](https://github.com/apache/echarts/blob/main/test/echarts-in-vue.html).

### How do I access the raw ECharts instance in Angular?

Use `@ViewChild(NgxEchartsDirective)` or assign a template reference variable (`#chart`) and access `this.chart.chartInstance`. This exposes methods like `dispatchAction`, `getDataURL`, and `resize` for imperative control.

### Why does my chart appear blank or fail to resize?

Ensure the container has a defined height (either explicit CSS or flex layout). If the container size changes dynamically, manually trigger `chart.resize()` or use the framework’s resize detection hooks. Verify you are not loading both the UMD and ESM versions of ECharts simultaneously.