React hooks & component for Apache ECharts — TypeScript, auto-resize, themes, lazy init.
- Hook + Component — use
useEchartshook or the declarative<EChart />component - TypeScript first — complete type definitions with IDE autocomplete
- Zero dependencies — no runtime deps beyond peer deps
- Auto-resize — handles container resizing via ResizeObserver
- Themes — built-in light, dark, and macarons themes, plus any custom theme
- Chart linkage — connect multiple charts for synchronized interactions
- Lazy initialization — defer chart init until element enters viewport
- StrictMode safe — instance cache with reference counting handles double mount/unmount
- React 19+ (
react+react-dom) - ECharts 6.x
- Node.js 22+ (required only for tooling/SSR frameworks — the published bundle is browser ESM)
CSR only. ECharts needs a live DOM; SSR is not supported.
ESM-only since 1.3.0. The package publishes a single ESM build (
dist/index.js). Every modern bundler (Vite, Next.js, webpack 5+, Rspack, Parcel, Turbopack) and Node 22+ (require(ESM)) consume it natively. If you still depend on CJS-only tooling, pin to1.2.x.
npm install react-use-echarts echarts
# or
yarn add react-use-echarts echarts
# or
pnpm add react-use-echarts echartsThe simplest way — no ref needed:
import { EChart } from "react-use-echarts";
function MyChart() {
return (
<EChart
option={{
xAxis: { type: "category", data: ["Mon", "Tue", "Wed", "Thu", "Fri"] },
yAxis: { type: "value" },
series: [{ data: [150, 230, 224, 218, 135], type: "line" }],
}}
/>
);
}<EChart /> defaults to width: 100% and height: 100%, so the parent container still needs an explicit height.
Pass ref to access { setOption, getInstance, resize } imperatively.
For full control, use the hook directly:
import { useRef } from "react";
import { useEcharts } from "react-use-echarts";
function MyChart() {
const chartRef = useRef<HTMLDivElement>(null);
const { setOption, getInstance, resize } = useEcharts(chartRef, {
option: { series: [{ type: "line", data: [150, 230, 224, 218, 135] }] },
});
return <div ref={chartRef} style={{ width: "100%", height: "400px" }} />;
}The chart container must have an explicit size, for example style={{ width: "100%", height: "400px" }}.
Built-in themes require one-time registration at app startup:
import { registerBuiltinThemes } from "react-use-echarts/themes/registry";
registerBuiltinThemes();
// Built-in theme
useEcharts(chartRef, { option, theme: "dark" });
// Any string registered via echarts.registerTheme
useEcharts(chartRef, { option, theme: "vintage" });
// Custom theme object (use useMemo to keep reference stable)
const customTheme = useMemo(() => ({ color: ["#fc8452", "#9a60b4", "#ea7ccc"] }), []);
useEcharts(chartRef, { option, theme: customTheme });Supports shorthand (function) and full config (object with query/context):
useEcharts(chartRef, {
option,
onEvents: {
click: (params) => console.log("Clicked:", params),
mouseover: {
handler: (params) => console.log("Hover:", params),
query: "series",
},
},
});const [loading, setLoading] = useState(true);
useEcharts(chartRef, {
option,
showLoading: loading,
loadingOption: { text: "Loading..." },
});Assign the same group ID — tooltips, highlights, and other interactions will sync:
useEcharts(chartRef1, { option: option1, group: "dashboard" });
useEcharts(chartRef2, { option: option2, group: "dashboard" });Defer chart init until the element scrolls into view:
useEcharts(chartRef, { option, lazyInit: true });
// Custom IntersectionObserver options
useEcharts(chartRef, {
option,
lazyInit: { rootMargin: "200px", threshold: 0.5 },
});- Container needs explicit size — the chart won't render in a zero-height div; give the container
height(andwidthif not 100%). - Keep
onEventsreference stable — a newonEventsobject on each render triggers a full rebind. Memoize it withuseMemo(or hoist) when handlers don't change. - Don't share one DOM element across multiple
useEchartshooks — the instance cache reuses a single ECharts instance and emits a dev warning; updates from different hooks will overwrite each other. initOptsand customthemeobjects recreate the instance on reference change — pass memoized or module-level constants unless recreation is intended.- StrictMode is safe — double mount/unmount is handled by the reference-counted instance cache.
Declarative component wrapping useEcharts. Accepts all hook options as props plus:
| Prop | Type | Default | Description |
|---|---|---|---|
style |
React.CSSProperties |
{ width: '100%', height: '100%' } |
Container style (merged with defaults) |
className |
string |
— | Container CSS class |
ref |
Ref<UseEchartsReturn> |
— | Exposes { setOption, getInstance, resize } |
| Option | Type | Default | Description |
|---|---|---|---|
option |
EChartsOption |
(required) | ECharts configuration |
theme |
string | object | null |
null |
Any registered theme name, or custom theme object |
renderer |
'canvas' | 'svg' |
'canvas' |
Renderer type |
lazyInit |
boolean | IntersectionObserverInit |
false |
Lazy initialization via IntersectionObserver |
group |
string |
— | Chart linkage group ID |
setOptionOpts |
SetOptionOpts |
— | Default options for setOption calls |
showLoading |
boolean |
false |
Show loading indicator |
loadingOption |
object |
— | Loading indicator configuration |
onEvents |
EChartsEvents |
— | Event handlers (fn or { handler, query?, context? }) |
autoResize |
boolean |
true |
Auto-resize via ResizeObserver |
initOpts |
EChartsInitOpts |
— | Passed to echarts.init() (devicePixelRatio, locale, width, etc.) |
onError |
(error: unknown) => void |
— | Error handler — effect failures logged via console.error without it; imperative setOption throws without it |
| Method | Type | Description |
|---|---|---|
setOption |
(option: EChartsOption, opts?: SetOptionOpts) => void |
Update chart configuration |
getInstance |
() => ECharts | undefined |
Get ECharts instance |
resize |
() => void |
Manually trigger chart resize |
import { useLazyInit } from "react-use-echarts"; // standalone lazy init hook
import { isBuiltinTheme, registerCustomTheme } from "react-use-echarts"; // theme utils (no JSON)
import { registerBuiltinThemes } from "react-use-echarts/themes/registry"; // ~20KB theme JSON
// All exported types: UseEchartsOptions, UseEchartsReturn, EChartProps,
// EChartsEvents, EChartsEventConfig, EChartsInitOpts, BuiltinTheme, LoadingOption
// EChartsOption and SetOptionOpts come from the "echarts" package directly.We welcome all contributions. Please read the contributing guidelines first.
Detailed changes for each release are documented in the release notes.