Development of Desktop Trading Terminal
A desktop trading terminal provides capabilities unavailable in a browser: direct network interaction without CORS restrictions, system notifications, auto-start, access to local files for data export, potentially lower latency via native TCP connections.
Technology Choice
Electron — the most popular framework. React/Vue/Angular frontend + Node.js backend in one application. Downside — large size (~100MB) and high memory consumption (multiple Chromium instances). Plus — code reuse from web.
Tauri (Rust + WebView) — a lighter Electron alternative. Uses system WebView (Edge on Windows, WebKit on macOS), binary size 3–10MB. Rust backend instead of Node.js — significantly less memory, higher performance.
Qt (C++ or Python) — native UI, maximum performance, but complex development and outdated UX.
For most trading terminal projects — Tauri if performance is needed, Electron if development speed is critical.
Tauri Architecture
// src-tauri/src/main.rs
use tauri::{Manager, Window};
use tokio::sync::broadcast;
#[tauri::command]
async fn subscribe_market_data(
symbol: String,
window: Window,
state: tauri::State<'_, AppState>,
) -> Result<(), String> {
let mut rx = state.market_data_bus.subscribe();
tokio::spawn(async move {
while let Ok(event) = rx.recv().await {
if event.symbol == symbol {
window.emit("market-data", &event).unwrap_or_default();
}
}
});
Ok(())
}
#[tauri::command]
async fn place_order(
order: OrderRequest,
state: tauri::State<'_, AppState>,
) -> Result<OrderResponse, String> {
state.exchange_client
.place_order(order)
.await
.map_err(|e| e.to_string())
}
// Frontend: using Tauri API
import { invoke } from '@tauri-apps/api/tauri';
import { listen } from '@tauri-apps/api/event';
// Subscribe to market data via native event
await invoke('subscribe_market_data', { symbol: 'BTC/USDT' });
const unlisten = await listen<MarketData>('market-data', (event) => {
updateOrderBook(event.payload);
});
Native Features for Traders
System tray — terminal runs in tray, receives alerts even when minimized:
import { TrayIcon } from '@tauri-apps/api/tray';
import { sendNotification } from '@tauri-apps/plugin-notification';
// Price alert
if (currentPrice >= alertPrice) {
await sendNotification({
title: 'Price Alert',
body: `BTC/USDT reached ${currentPrice.toFixed(2)}`,
icon: 'icons/icon.png',
});
}
Hotkeys — global keyboard shortcuts:
use tauri_plugin_global_shortcut::{Code, GlobalShortcutExt, Modifiers, Shortcut};
app.global_shortcut().register(
Shortcut::new(Some(Modifiers::CTRL | Modifiers::SHIFT), Code::KeyB),
move |_app, _shortcut, _event| {
// Ctrl+Shift+B - quick market buy
place_market_buy_order();
},
)?;
Auto-start — launch with system for 24/7 monitoring:
import { enable, isEnabled } from '@tauri-apps/plugin-autostart';
async function enableAutostart() {
if (!(await isEnabled())) {
await enable();
}
}
Performance vs Electron
| Metric | Electron | Tauri |
|---|---|---|
| Binary size | 80–150 MB | 3–10 MB |
| Memory on startup | 150–300 MB | 30–80 MB |
| CPU idle | 2–5% | 0.5–1% |
| Startup time | 2–5 sec | 0.5–1 sec |
For a trading terminal running 24/7, the difference in memory and CPU consumption is significant.
Auto-Update
Tauri built-in updater via GitHub Releases or custom server:
// tauri.conf.json
{
"updater": {
"active": true,
"endpoints": ["https://releases.yourapp.com/{{target}}/{{arch}}/{{current_version}}"],
"dialog": true,
"pubkey": "..."
}
}
When a new version is released, the application shows a notification and downloads the update in the background. Signing updates with a private key — a mandatory security requirement.







