TryAITryAITry TryAI

Shared chat

Electron أم Egui لتطبيق التداول

I created two version of my paid future trading terminal dekstop app , version with electron + rust (rust logic not yet) and version with egui , the ui look 100% the same between two versions The only thing still didnt added are charts , for electron i can add it with tradingview lightweight library and for egui i can use egui-charts library بناءا على ما قلت لك اي نسخة تنصحني بالاتمرار فيها؟ خصوصا ان تطبيقي سيكون مدفوع شهريا بواقعية مادا تنصح؟
Claude Fable 5

نصيحتي بواقعية: استمر في نسخة Electron + Rust

والسبب الحاسم ليس الـ UI (طالما متطابق) بل الشارتات تحديداً، لأنها قلب أي منصة تداول مدفوعة:

1. الشارت هو المنتج الفعلي في تطبيق تداول

  • TradingView Lightweight Charts: مكتبة ناضجة، مجانية، يستخدمها آلاف المنصات، فيها Candlesticks، Crosshair، Volume، Timeframes، أداء ممتاز حتى مع آلاف الشموع، والمتداولون معتادون على شكلها وسلوكها.
  • egui_plot / مكتبات egui: بدائية جداً لهذا الغرض. ستضطر تبني بنفسك: الشموع، الـ zoom/pan الاحترافي، الـ crosshair مع OHLC tooltip، المؤشرات الفنية، أدوات الرسم (خطوط الترند، فيبوناتشي...). هذا شهور من العمل لتصل لجودة أقل من TradingView.

2. تطبيق مدفوع شهرياً = تحتاج بنية تجارية

مع Electron ستجد حلولاً جاهزة لكل شيء:

  • Auto-update (electron-updater) — ضروري جداً لتطبيق اشتراكات
  • تكامل سهل مع بوابات الدفع (Stripe checkout في webview)
  • Licensing / session management عبر مكتبات JS ناضجة
  • سرعة تطوير أعلى بكثير عند إضافة ميزات جديدة (والمشتركون سيطالبون بميزات باستمرار)

3. عيوب Electron ليست قاتلة هنا

نعم، استهلاك ذاكرة أعلى وحجم أكبر (~150MB+)، لكن المتداولون يشغّلون أصلاً MT5 وNinjaTrader وChrome بعشرات التابات. لن يلغي أحد اشتراكه بسبب 300MB رام، لكنه سيلغيه بسبب شارت ضعيف.

اقتراح إضافي يستحق النظر: Tauri

بما أنك أصلاً تخطط لمنطق Rust:

  • Tauri = Rust backend + نفس واجهة الويب + نفس TradingView charts
  • حجم أصغر بكثير (~10MB) وذاكرة أقل من Electron
  • تنقل الـ frontend الحالي كما هو تقريباً

الخلاصة

المعيارElectron/Tauriegui
جودة الشارتات⭐⭐⭐⭐⭐⭐⭐
سرعة الوصول للسوقسريعبطيء جداً
Auto-update & دفعجاهزيدوي
استهلاك المواردأعلىأفضل

قراري لو كنت مكانك: Electron (أو Tauri إن أردت Rust بعمق) + TradingView Lightweight Charts، وأطلق المنتج بسرعة. egui خيار ممتاز تقنياً لكنه سيؤخر إطلاقك أشهراً بجودة شارت أقل — وهذا خسارة مباشرة لمنتج اشتراك شهري.

Claude Fable 51.6k tok63.6 tok/sTTFT 6.5s31.8s
Rust حسنا ما هي افضل طريقة لاستعمال
Claude Fable 5
Rust حسنا ما هي افضل طريقة لاستعمال مع. الكترون لا هناك طرق كثيرة وما هي الخطوات الجيدة وايضا اعطني الاجابة بالانجليزية
Claude Fable 5

Best Ways to Use Rust with Electron

There are 4 main approaches — here they are ranked for your use case (a trading terminal):

Option 1: napi-rs (Native Node.js Module) — ⭐ Recommended for most cases

Rust compiles to a .node native module that you require() directly in Electron's main process. Zero IPC overhead, direct function calls.

  • Pros: Fastest integration, type-safe bindings auto-generated for TypeScript, async support with tokio, mature (used by swc, Prisma, Next.js)
  • Cons: Must rebuild per platform/architecture, crashes in Rust can crash Electron

Option 2: Sidecar Process — ⭐ Recommended for trading logic specifically

Ship a standalone Rust binary alongside your app. Electron spawns it and communicates via stdin/stdout (JSON), WebSocket, or gRPC.

  • Pros: Complete isolation (Rust crash ≠ app crash), Rust runs its own tokio runtime freely (perfect for market data feeds, order engines), easy to debug/test the binary independently
  • Cons: IPC serialization overhead, process lifecycle management

Option 3: WebAssembly (wasm-bindgen)

Rust compiled to WASM, runs in the renderer.

  • Pros: Cross-platform single build, sandboxed
  • Cons: No raw TCP sockets/threads limitations, slower than native, bad fit for network-heavy trading logic — skip this

Option 4: Raw FFI (ffi-napi)

Manual C ABI bindings. Fragile, unmaintained libraries — avoid.


My Recommendation for Your App

Hybrid: use a Rust sidecar for the trading engine (market data, order execution, strategy logic) + optionally napi-rs for small hot-path utilities. The sidecar keeps your money-handling logic isolated and independently testable — critical for a paid product.


Steps: Sidecar Architecture (Primary)

1. Create the Rust binary

bash
cargo new trading-enginecd trading-enginecargo add tokio --features fullcargo add serde serde_json --features serde/derivecargo add tokio-tungstenite   # if using WebSocket transport

2. Expose a WebSocket server in Rust

// src/main.rsuse tokio::net::TcpListener; #[derive(serde::Serialize)]struct Tick { symbol: String, price: f64, ts: i64 } #[tokio::main]async fn main() {    // Bind to localhost only — never 0.0.0.0    let listener = TcpListener::bind("127.0.0.1:8765").await.unwrap();    while let Ok((stream, _)) = listener.accept().await {        tokio::spawn(handle_connection(stream));    }} async fn handle_connection(stream: tokio::net::TcpStream) {    let ws = tokio_tungstenite::accept_async(stream).await.unwrap();    // stream market data / handle order commands here}

3. Spawn it from Electron's main process

typescript
// main.tsimport { spawn, ChildProcess } from "child_process";import path from "path";import { app } from "electron"; let engine: ChildProcess; function startEngine() {  const bin = app.isPackaged    ? path.join(process.resourcesPath, "bin", "trading-engine")    : path.join(__dirname, "../trading-engine/target/release/trading-engine");   engine = spawn(bin, [], { stdio: ["pipe", "pipe", "pipe"] });   engine.on("exit", (code) => {    console.error(`engine died (${code}), restarting...`);    setTimeout(startEngine, 1000); // auto-restart  });} app.whenReady().then(startEngine);app.on("before-quit", () => engine?.kill());

4. Connect from the renderer

typescript
// rendererconst ws = new WebSocket("ws://127.0.0.1:8765");ws.onmessage = (e) => {  const tick = JSON.parse(e.data);  candlestickSeries.update(tick); // feed TradingView Lightweight Charts directly};

5. Package the binary with electron-builder

yaml
# electron-builder.ymlextraResources:  - from: "trading-engine/target/release/trading-engine${/*}"    to: "bin/"

Steps: napi-rs (Optional, for hot paths)

bash
npm install -g @napi-rs/clinapi new rust-utils
// lib.rsuse napi_derive::napi; #[napi]pub fn calculate_ema(prices: Vec<f64>, period: u32) -> Vec<f64> {    let k = 2.0 / (period as f64 + 1.0);    let mut out = Vec::with_capacity(prices.len());    let mut ema = prices[0];    for p in &prices {        ema = p * k + ema * (1.0 - k);        out.push(ema);    }    out}
typescript
// In Electron main — typed bindings are auto-generatedimport { calculateEma } from "./rust-utils";const ema = calculateEma(closes, 21);

Practical Tips

  1. Bind sidecar to 127.0.0.1 only and add a random auth token passed via env var on spawn — otherwise any local app could connect to your engine.
  2. Use binary framing (MessagePack/protobuf) instead of JSON if you're streaming high-frequency ticks — JSON parsing becomes the bottleneck.
  3. Keep the protocol versioned ({"v": 1, "type": "tick", ...}) so auto-updated Electron frontends stay compatible with older engine binaries.
  4. CI matrix: build the Rust binary for win-x64, mac-arm64, mac-x64, linux-x64 in GitHub Actions and inject it into the electron-builder step.
  5. Start with stdin/stdout JSON lines if WebSocket feels heavy — it's simpler and works fine for command/response patterns; use WebSocket only for streaming data to the renderer.

Bottom line: sidecar for the engine, napi-rs later if you need microsecond-level calls. This keeps your paid product stable — the app UI never dies because of an engine bug.

Claude Fable 52.4k tok97.2 tok/sTTFT 6.9s31.4s

This is a shared TryAI chat. Sign in to start your own conversation.

Sign in to TryAI