npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

vninvestcharts-widget

v1.2.4

Published

Professional-grade Vietnamese stock charting library with real-time VN market data, 60+ indicators, 20+ drawing tools, and embeddable React widget

Readme

VNInvestCharts Widget

Professional-grade Vietnamese stock charting widget — embed into any website, zero backend coupling. Widget biểu đồ chứng khoán chuyên nghiệp — nhúng vào bất kỳ website nào, hoàn toàn độc lập với backend.

🌐 Live demo / Bản dùng thử: https://vninvest.edusuccess.vn

version license React TypeScript


Why VNInvestCharts Widget? / Tại sao chọn VNInvestCharts Widget?

EN: VNInvestCharts Widget is a pure frontend charting widget with no backend dependency. It embeds into any website — React SPA, vanilla HTML, CMS, or third-party platform — via 3 delivery modes (ESM, IIFE, Iframe). The widget communicates with any backend through a pluggable data adapter, making frontend and backend completely independent.

VN: VNInvestCharts Widget là widget biểu đồ thuần frontend, không phụ thuộc backend. Nhúng được vào mọi website — React SPA, HTML thuần, CMS, hoặc nền tảng bên thứ ba — qua 3 chế độ (ESM, IIFE, Iframe). Widget giao tiếp với backend qua data adapter cắm được, giúp frontend và backend hoàn toàn độc lập.

| Advantage / Ưu điểm | Description / Mô tả | |---|---| | Zero backend coupling / Không phụ thuộc backend | Widget is pure frontend. No server, no database, no API coupling required. / Widget thuần frontend. Không cần server, database, hay ràng buộc API. | | Any website, any stack / Mọi website, mọi stack | Embed via React ESM, vanilla script tag (IIFE), or sandboxed iframe. / Nhúng qua React ESM, script tag (IIFE), hoặc iframe cách ly. | | Pluggable data adapter / Adapter dữ liệu cắm được | Swap data sources via a typed StockDataAdapter interface — your backend, third-party API, or static data. / Đổi nguồn dữ liệu qua interface StockDataAdapter kiểu — backend của bạn, API bên thứ ba, hoặc dữ liệu tĩnh. | | CSS isolation / Cô lập CSS | Shadow DOM built-in (IIFE) or manual injection — no style leaks. / Shadow DOM có sẵn (IIFE) hoặc inject thủ công — không lo xung đột CSS. | | Auth-agnostic / Không ràng buộc xác thực | Token-based authHandler pattern — works with JWT, OAuth, session, or BFF proxy. / Pattern authHandler dạng token — hoạt động với JWT, OAuth, session, hoặc BFF proxy. | | VN market native / Bản địa thị trường VN | Built for Vietnamese stocks, VN timezone, VND currency, vi/en i18n. / Xây dựng cho chứng khoán Việt Nam, múi giờ VN, tiền tệ VND, i18n vi/en. |


Quick Start / Bắt đầu nhanh

Script tag (IIFE) — any website / mọi website

<script src="https://cdn.jsdelivr.net/npm/vninvestcharts-widget/dist/vninvestchart.iife.js"></script>
<script>
  const { unmount, widgetRef } = window.VNInvestCharts.mount({
    container: document.getElementById('chart'),
    props: { symbol: 'VCB', timeframe: '1D', theme: 'dark' },
    useShadowDOM: true,
  });
  // widgetRef.current?.setSymbol('FPT');
</script>

No React, no build step required. Zero backend. / Không cần React, không cần build. Không cần backend.

ESM — React app / ứng dụng React

import { VNInvestCharts } from 'vninvestcharts-widget';
import 'vninvestcharts-widget/dist/index.css';

function App() {
  return <VNInvestCharts symbol="VCB" timeframe="1D" theme="dark" />;
}

Iframe — maximum isolation / cách ly tối đa

<iframe src="https://your-cdn.com/iframe/vninvestchart.iframe.html"
  style="width:100%;height:600px;border:none;"></iframe>
<script type="module">
import { createVNInvestChartsHost } from 'vninvestcharts-widget/iframe';
const sdk = await createVNInvestChartsHost({ iframe: document.querySelector('iframe') });
await sdk.getController().initialize({ symbol: 'VCB', timeframe: '1D' });
</script>

Full sandbox isolation. Communication via typed Host SDK. / Cách ly sandbox hoàn toàn. Giao tiếp qua Host SDK kiểu.


Core Architecture / Kiến trúc cốt lõi

Frontend-Backend Separation / Tách biệt Frontend-Backend

┌─────────────────────────────────────────────────┐
│   Your Website (any stack / mọi nền tảng)       │
│                                                  │
│  ┌───────────────────────────────────────────┐   │
│  │  VNInvestCharts Widget (pure frontend)     │   │
│  │                                            │   │
│  │  ┌──────┐  ┌──────────┐  ┌─────────────┐  │   │
│  │  │ ESM  │  │   IIFE   │  │   Iframe    │  │   │
│  │  │ React│  │Vanilla JS│  │  Sandboxed  │  │   │
│  │  └──┬───┘  └────┬─────┘  └──────┬──────┘  │   │
│  │     └───────────┼───────────────┘          │   │
│  │                 │ (unified adapter layer)    │   │
│  │          ┌──────┴──────┐                    │   │
│  │          │ DataAdapter │ ← pluggable       │   │
│  │          └──────┬──────┘                    │   │
│  └─────────────────┼──────────────────────────┘   │
│                    │                              │
│  ┌─────────────────┼──────────────────────────┐   │
│  │  Your Backend (any language / bất kỳ)      │   │
│  │  ┌──────────────┴──────────────┐           │   │
│  │  │  REST / GraphQL / WebSocket │           │   │
│  │  │  Python / Java / Go / PHP ⋯│           │   │
│  │  └─────────────────────────────┘           │   │
│  └────────────────────────────────────────────┘   │
└─────────────────────────────────────────────────┘

EN: The widget never talks directly to a backend. All data flows through a StockDataAdapter interface — your backend can be written in any language, use any protocol (REST, WS, gRPC), and change independently of the frontend. The widget doesn't care.

VN: Widget không bao giờ giao tiếp trực tiếp với backend. Toàn bộ dữ liệu chảy qua interface StockDataAdapter — backend của bạn viết bằng ngôn ngữ nào cũng được, dùng giao thức nào cũng được (REST, WS, gRPC), và có thể thay đổi độc lập với frontend. Widget không quan tâm.

// Your adapter — connect any backend / kết nối backend bất kỳ
import type { StockDataAdapter } from 'vninvestcharts-widget';

const myAdapter: StockDataAdapter = {
  fetchBarsBefore: async (symbol, tf, beforeDate, limit) => {
    const res = await fetch(`/api/bars?symbol=${symbol}&tf=${tf}&before=${beforeDate.getTime()}&limit=${limit}`);
    return res.json();
  },
  fetchBarsInRange: async (symbol, tf, from, to) => {
    const res = await fetch(`/api/bars?symbol=${symbol}&tf=${tf}&from=${from.getTime()}&to=${to.getTime()}`);
    return res.json();
  },
};

<VNInvestCharts symbol="VCB" adapter={myAdapter} />

SSOT Data Model / Mô hình dữ liệu SSOT

EN: Every indicator is computed once by the engine kernel and consumed by many layers — no redundant computation, no stale state. The widget maintains a canonical store that guarantees data consistency across panes, drawings, and replay.

VN: Mọi chỉ báo được engine kernel tính một lần và nhiều tầng cùng tiêu thụ — không tính toán dư thừa, không state lỗi thời. Widget duy trì canonical store đảm bảo dữ liệu nhất quán giữa các pane, drawing, và replay.

Multi-layer Isolation / Cô lập đa tầng

src/
├── lib/           ← Pure library — no external deps / *thuần thư viện*
│   ├── core/      ← Chart engine, calculators, registry, replay
│   ├── drawing/   ← Drawing tools + interaction FSM
│   ├── indicators/← Indicator compute registry
│   └── types/     ← Shared TypeScript definitions
├── widget/        ← Embeddable React widget — embeddable / *có thể nhúng*
└── demo/          ← Demo shell — never imported by lib/widget / *demo, không ảnh hưởng*

Hard rules / Nguyên tắc cứng:

  • src/lib/ never imports from src/demo/ — library is completely independent of the demo surface. / Thư viện hoàn toàn độc lập với demo.
  • The widget layer can be embedded without the demo layer — zero extra weight. / Lớp widget nhúng được mà không kéo theo demo.
  • Presentation never affects data — UI is a pure projection of the canonical store. / UI là hình chiếu thuần của dữ liệu.

Delivery Matrix / Ma trận phân phối

| Mode / Chế độ | Bundle | CSS Isolation | React required | Use case / Ứng dụng | |---|---|---|---|---| | ESM (React) | dist/index.js | Manual Shadow DOM | Yes | React SPA | | IIFE (script tag) | dist/vninvestchart.iife.js | Shadow DOM by default | No | Any website, CMS, static page | | Iframe | dist/iframe/vninvestchart.iframe.html | Sandbox (absolute) | No | Third-party sites, strict CSP |


Embedding Guide / Hướng Dẫn Nhúng

Full bilingual guide → docs/WIDGET_EMBED_GUIDE.md Hướng dẫn song ngữ đầy đủ → docs/WIDGET_EMBED_GUIDE.md

| Method / Phương thức | Lines of code | Backend needed | Best for / Phù hợp nhất | |---|---|---|---| | ESM React | 5–10 | No | React SPA | | IIFE script tag | 5–10 | No | WordPress, Shopify, static HTML | | Iframe + SDK | 10–15 | No | Third-party embedding, banking, enterprise |


Features / Tính năng

| Feature | Status | |---------|--------| | Candlestick / OHLC / Heikin-Ashi / Renko / Kagi / Point & Figure | ✅ | | 68 drawing tools (Trend Line, Fibonacci, Channel, Gann, Elliott Wave, Harmonic, ABCD, Pitchfork, Measurement) | ✅ | | 59 technical indicators (EMA, MACD, RSI, Bollinger, VWAP, Volume Profile, CVD, Ichimoku, SuperTrend, Market Profile) | ✅ | | Dark / Light theme | ✅ | | Bar replay & paper trading | ✅ | | Multi-symbol comparison | ✅ | | Dynamic pane layout with splitter resize | ✅ | | Workspace save/restore (localStorage) | ✅ | | VI / EN i18n | ✅ | | Bar backfill engine (lazy-load historical data) | ✅ | | Drawing export/import | ✅ | | VNInvest exclusive indicators (Whale Flow, CVD, Dark Flow, SMFI) | 🔄 In progress | | Visual DAG indicator builder | 📋 Planned | | Indicator sets & templates | 📋 Planned |


Widget API

interface VNInvestChartsProps {
  symbol: string;
  timeframe: Timeframe;
  theme?: 'light' | 'dark';
  locale?: 'vi' | 'en';
  drawingUiEnabled?: boolean;
  showHeader?: boolean;
  showToolbar?: boolean;
  showFooter?: boolean;
  containerStyle?: React.CSSProperties;
  onSymbolChange?: (symbol: string) => void;
  onTimeframeChange?: (tf: Timeframe) => void;
}

Imperative control (IIFE):

const { mount, unmount, widgetRef } = window.VNInvestCharts.mount({
  container: document.getElementById('chart'),
  props: { symbol: 'VCB', timeframe: '1D' },
  useShadowDOM: true,
});

widgetRef.current?.setSymbol('VCB');
widgetRef.current?.setTimeframe('1H');
widgetRef.current?.toggleTheme();
const drawings = widgetRef.current?.exportDrawings();

Full props reference → docs/WIDGET_EMBED_GUIDE.md


Subpath Exports / Đường dẫn phụ

// Data adapters
import { VNInvestDataAdapter, MultiSourceDataAdapter } from "vninvestcharts-widget/adapters";
// Drawing controllers
import { createLocalStorageAdapter, type DrawingWorkspaceController } from "vninvestcharts-widget/drawing";
// Types
import type { StockDataAdapter, Timeframe, OHLCVBar } from "vninvestcharts-widget/types";

Standalone Components / Components độc lập

import {
  DrawingDock, DrawingInspector, DrawingListPanel,
  ReplayControlBar, PaperTradePanel, SettingsModal, VNSymbolSearch,
  WhalePanel, WidgetErrorBoundary, WidgetEmptyState, PremiumFeatureGate,
} from "vninvestcharts-widget";

Development / Phát triển

npm install
npm run watch          # dev server → http://localhost:8080
npm run type-check     # TypeScript strict check
npm test               # 2600+ tests (Vitest)
npm run build          # production build → dist/

Packages / Gói

| Package | Description | |---------|-------------| | vninvestcharts-widget | Main library — ESM + CJS + IIFE + iframe | | vn-kline-engine-core | Canvas/WebGL rendering engine | | vn-kline-engine-react | React bindings for engine |


License

Mozilla Public License 2.0 — © 2026 Phạm Việt Dũng