@cvasingh/tradingview-react-chart
v0.1.0
Published
Production-grade TradingView charting library React component with TypeScript, SSR safety, and real-time streaming
Downloads
60
Maintainers
Readme
@cvasingh/tradingview-react-chart
Production-grade TradingView charting library React component with TypeScript, SSR safety, real-time WebSocket streaming, and full lifecycle management.
Features
- TypeScript — Fully typed props, events, and internal APIs
- SSR-safe — Dynamic import wrapper for Next.js / server-rendered apps
- Real-time streaming — Socket.IO WebSocket integration with auto-reconnect
- Error resilience — Retry/backoff on API calls, React Error Boundary,
onErrorcallback - Symbol search — Client-side filtered search over preloaded symbol list
- Drawing persistence — Server/API adapter for saving/loading chart drawings
- Configurable — Session hours, exchanges, studies (string or rich config), themes
- Multi-chart — Multiple independent chart instances on a single page
- Package-ready — ESM + CJS builds via tsup, npm-publishable
Installation
npm install @cvasingh/tradingview-react-chartPeer dependencies: react >= 18, react-dom >= 18
Important: You must have the TradingView
charting_library/files accessible at runtime (e.g. copied into yourpublic/folder). The library is proprietary — do not redistribute it publicly.
Quick Start
Create a .env.local file (see .env.example):
NEXT_PUBLIC_TV_API_BASE_URL=https://your-api.example.com/tradingview
NEXT_PUBLIC_TV_WS_URL=wss://your-ws.example.comimport { TradingViewChart } from "@cvasingh/tradingview-react-chart";
export default function App() {
return (
<div style={{ width: "100vw", height: "100vh" }}>
<TradingViewChart
symbol="TATAMOTORS"
interval="1D"
theme="dark"
autosize
apiBaseUrl={process.env.NEXT_PUBLIC_TV_API_BASE_URL!}
wsUrl={process.env.NEXT_PUBLIC_TV_WS_URL!}
onReady={() => console.log("Chart ready")}
onError={(err) => console.error("Chart error:", err)}
/>
</div>
);
}Next.js (SSR-safe)
Use the dynamic wrapper from your components/ directory, or wrap with next/dynamic yourself:
import dynamic from "next/dynamic";
const Chart = dynamic(
() => import("@cvasingh/tradingview-react-chart").then((m) => m.TradingViewChart),
{ ssr: false },
);Props
| Prop | Type | Default | Description |
| ------------------- | ------------------------ | -------------------- | ----------------------------------------------------------------------------- |
| symbol | string | required | Stock ticker symbol (e.g. "TATAMOTORS") |
| interval | string | "1D" | Chart resolution ("1", "5", "15", "30", "60", "D", "1W", "M") |
| theme | "light" \| "dark" | "light" | Color theme |
| autosize | boolean | true | Fill parent container |
| width | number \| string | — | Fixed width (ignored when autosize is true) |
| height | number \| string | — | Fixed height (ignored when autosize is true) |
| studies | StudyConfig[] | — | Studies to apply (string or { name, inputs?, overrides? }) |
| locale | string | "en" | Locale string |
| timezone | string | "Asia/Kolkata" | IANA timezone |
| debug | boolean | false | Enable debug logging |
| disabledFeatures | string[] | ["header_compare"] | TradingView features to disable |
| enabledFeatures | string[] | — | TradingView features to enable |
| toolbarBg | string | — | Toolbar background colour |
| enablePublishing | boolean | false | Show publish button |
| allowSymbolChange | boolean | false | Allow user to change symbol |
| fullscreen | boolean | false | Fullscreen mode |
| apiBaseUrl | string | required | REST API base URL for symbol/history endpoints |
| wsUrl | string | required | WebSocket URL for real-time streaming |
| onReady | () => void | — | Called when the chart is fully ready |
| onError | (error: Error) => void | — | Called on API/WebSocket/widget errors |
| className | string | — | Extra className on wrapper div |
| style | CSSProperties | — | Inline styles on wrapper div |
| sessionHours | string | "0915-1530" | Market session hours |
| exchanges | ExchangeConfig[] | BSE + NSE | Exchange configurations |
| symbolsListUrl | string | — | URL for symbols list (search). Falls back to apiBaseUrl + "/symbols/list" |
| drawingsApiUrl | string | — | REST API base URL for drawing persistence |
Studies
Studies can be passed as simple strings or rich configuration objects:
<TradingViewChart
studies={[
"MASimple@tv-basicstudies", // simple
{ name: "RSI@tv-basicstudies", inputs: [14] }, // with inputs
{
name: "MACD@tv-basicstudies",
inputs: [12, 26, 9],
overrides: { "histogram.color": "#26a69a" },
},
]}
// ...other props
/>Drawing Persistence
Pass drawingsApiUrl to enable server-side drawing persistence:
<TradingViewChart
drawingsApiUrl="https://api.example.com/drawings"
// ...other props
/>Expected Server Contract
| Method | Endpoint | Body / Params | Response |
| -------- | --------------------------- | ------------------ | ----------------------------- |
| GET | {drawingsApiUrl}?symbol=X | — | { drawings: DrawingData[] } |
| POST | {drawingsApiUrl} | { symbol, data } | 201 |
| DELETE | {drawingsApiUrl}/{id} | — | 204 |
API Endpoints
The component expects these REST endpoints at apiBaseUrl:
| Endpoint | Purpose |
| --------------------------------------------------------- | --------------------------- |
| GET /symbols?symbol=X | Resolve symbol metadata |
| GET /history?symbol=X&interval=R&from=F&to=T&exchange=E | Get historical OHLCV bars |
| GET /symbols/list (or custom symbolsListUrl) | List all symbols for search |
Advanced Usage
Direct library access
import {
createDatafeed,
StreamingManager,
fetchWithRetry,
loadSymbolsList,
} from "@cvasingh/tradingview-react-chart";Error Boundary
The chart is automatically wrapped in TradingViewErrorBoundary when using the dynamic wrapper. You can also use it directly:
import { TradingViewErrorBoundary } from "@cvasingh/tradingview-react-chart";
<TradingViewErrorBoundary
onError={(err) => reportError(err)}
fallback={<div>Something went wrong</div>}
>
<TradingViewChart {...props} />
</TradingViewErrorBoundary>;Development
# Install
npm install
# Dev server (Next.js demo app)
npm run dev
# Run tests
npm run test:run
# Lint
npm run lint
# Build npm package
npm run build:pkg
# Storybook
npm run storybookProject Structure
src/
index.ts ← barrel export (npm package entry)
components/
TradingViewChart.tsx ← core React component
TradingViewChartDynamic.tsx ← SSR-safe dynamic wrapper
TradingViewErrorBoundary.tsx ← React Error Boundary
TradingViewChart.stories.tsx ← Storybook stories
lib/
datafeed.ts ← createDatafeed() factory
streaming.ts ← StreamingManager (socket.io)
loadScript.ts ← idempotent script loader
fetchUtils.ts ← fetch with retry/backoff
timeUtils.ts ← bar time utilities
symbolsStore.ts ← symbol search (client-side filter)
drawingsStore.ts ← drawing persistence adapter
types/
tradingview.ts ← TypeScript types & props
__tests__/ ← Vitest test suite
pages/ ← Next.js demo pages
public/charting_library/ ← TradingView library (not published)Limitations
- TradingView widget does not support changing
symbol/intervalpost-creation — requires full re-init searchSymbolsuses client-side filtering over a preloaded list (no server-side search)- The charting library (v24) is proprietary —
public/charting_library/must not be published publicly - Drawing persistence requires you to implement the server endpoints
- Session hours default to
0915-1530(Indian market) — adjust viasessionHoursprop
License
MIT
