139 lines
4.5 KiB
Markdown
139 lines
4.5 KiB
Markdown
# Architecture Decision Record: Use Tauri with Embedded Node for Cross-Platform App
|
||
|
||
**Date:** 2025-08-15
|
||
**Status:** Accepted
|
||
**Decision Makers:** \[Team/Project Name]
|
||
**Context:** Desktop + Mobile App Development
|
||
|
||
---
|
||
|
||
## **Context**
|
||
|
||
We are building a cross-platform application targeting **desktop (Windows, macOS, Linux)** and **mobile (Android, iOS)** using **SvelteKit + TailwindCSS** for the UI.
|
||
|
||
Key goals:
|
||
|
||
* Maintain **fast development iteration** with hot reload for both frontend and backend logic.
|
||
* Allow backend logic to be written in **TypeScript** for developer familiarity and speed.
|
||
* Support writing **performance-critical features in Rust** if needed.
|
||
* Deploy the **same codebase** across desktop and mobile with minimal divergence.
|
||
* Avoid security limitations of browser-only apps (e.g., CORS, sandbox restrictions).
|
||
* Provide direct access to **Node APIs** and/or **Rust commands** for native capabilities.
|
||
|
||
---
|
||
|
||
## **Decision**
|
||
|
||
We will use **Tauri v2** with an **embedded Node runtime** alongside the SvelteKit frontend.
|
||
|
||
```mermaid
|
||
graph LR
|
||
%% "Tauri + Node + SvelteKit + Tailwind Architecture"
|
||
|
||
subgraph "Frontend (UI)"
|
||
SvelteKit["SvelteKit<br/>(TS + TailwindCSS)"]
|
||
WebView["WebView<br/>(Tauri Runtime)"]
|
||
SvelteKit --> WebView
|
||
end
|
||
|
||
subgraph "Backend Logic"
|
||
NodeJS["Embedded Node.js Runtime<br/>(TypeScript backend)"]
|
||
Rust["Rust Commands<br/>(Tauri APIs / Native modules)"]
|
||
end
|
||
|
||
subgraph "Platforms"
|
||
Desktop["Desktop<br/>(Windows, macOS, Linux)"]
|
||
Mobile["Mobile<br/>(Android, iOS)"]
|
||
end
|
||
|
||
WebView -->|IPC / API calls| NodeJS
|
||
WebView -->|Tauri Commands| Rust
|
||
NodeJS -->|FFI / API bridge| Rust
|
||
Rust -->|Native APIs| Desktop
|
||
Rust -->|Native APIs| Mobile
|
||
WebView --> Desktop
|
||
WebView --> Mobile
|
||
```
|
||
|
||
**Why Tauri**:
|
||
|
||
* Small runtime compared to Electron for desktop builds (\~5–20 MB without Node).
|
||
* Native integration with OS features (system tray, notifications, file access, etc.).
|
||
* Built-in support for **mobile (Android/iOS)** in Tauri v2.
|
||
* Strong security model and long-term community backing.
|
||
|
||
**Why embed Node**:
|
||
|
||
* Node.js runtime allows full access to existing npm ecosystem and built-in modules (`fs`, `crypto`, `net`, etc.).
|
||
* Enables backend logic to be written entirely in TypeScript during early development.
|
||
* Hot reload with tools like `nodemon` or `ts-node` for fast iteration.
|
||
* Flexibility to migrate specific logic to Rust incrementally without losing productivity.
|
||
|
||
**Workflow**:
|
||
|
||
* **Development**:
|
||
|
||
* Run SvelteKit dev server for UI (`npm run dev`)
|
||
* Run Node backend with hot reload
|
||
* Tauri shell points to `localhost` dev server for instant updates
|
||
* **Production**:
|
||
|
||
* Bundle SvelteKit output with `adapter-static` or `adapter-node`
|
||
* Include Node runtime for backend logic
|
||
* Optionally replace parts of backend with compiled Rust commands for performance-critical paths
|
||
|
||
---
|
||
|
||
## **Alternatives Considered**
|
||
|
||
1. **Capacitor**
|
||
|
||
* ✅ Mature mobile ecosystem and simpler dev workflow for mobile
|
||
* ❌ No built-in Node runtime; would require rewriting backend logic as plugins or browser-safe code
|
||
* ❌ We would lose direct access to Node APIs without extra complexity
|
||
|
||
2. **Electron**
|
||
|
||
* ✅ First-class Node integration
|
||
* ❌ Larger desktop build size (50–150 MB)
|
||
* ❌ Heavier memory footprint compared to Tauri
|
||
|
||
3. **Pure Tauri (Rust backend only)**
|
||
|
||
* ✅ Smallest build sizes, fastest runtime
|
||
* ❌ Slower development for backend logic without TS hot reload
|
||
* ❌ Would require Rust expertise for all backend features from day one
|
||
|
||
---
|
||
|
||
## **Consequences**
|
||
|
||
**Positive:**
|
||
|
||
* Full-stack TypeScript possible in early development → faster MVP delivery.
|
||
* Incremental migration path to Rust for performance-sensitive features.
|
||
* Single codebase for desktop & mobile.
|
||
* Rich native API access via both Node and Tauri’s Rust plugins.
|
||
* Security benefits from Tauri’s isolation model.
|
||
|
||
**Negative:**
|
||
|
||
* Larger mobile builds (\~25–40 MB vs. Capacitor’s \~10–20 MB).
|
||
* More complex tooling setup (Rust + Node + mobile SDKs).
|
||
* Slightly slower startup time on mobile due to Node runtime initialization.
|
||
|
||
---
|
||
|
||
## **References**
|
||
|
||
* [Tauri v2 Documentation](https://v2.tauri.app/)
|
||
* [Node.js Documentation](https://nodejs.org/en/docs)
|
||
* [SvelteKit Documentation](https://kit.svelte.dev/)
|
||
* [TailwindCSS Documentation](https://tailwindcss.com/)
|
||
|
||
---
|
||
|
||
I can also add a **diagram showing the architecture** — frontend, embedded Node backend, and optional Rust modules — so stakeholders can visually understand how the stack fits together across platforms.
|
||
|
||
Do you want me to make that diagram next?
|