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

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, 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:

npm install echarts echarts-for-react

Basic Implementation

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

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, 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

npm install echarts vue-echarts

Vue 3 Composition API Example

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

<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 (lines 51–84) showing manual initialization:

<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 (ESM) or dist/echarts.min.js (UMD) as declared in the repository’s 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

npm install echarts ngx-echarts

Module Setup and Component Usage

Register the module with the global ECharts instance in app.module.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:

<div echarts [options]="option" class="chart"></div>
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 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 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 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 (ESM) or 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.

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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →