Developer Setup
Project structure, config file paths, and development environment setup for MC-Vector.
Overview
MC-Vector is a Tauri v2 desktop application built with:
| Layer | Technology |
|---|---|
| Frontend | React 19 + Vite + TypeScript |
| Styling | Tailwind CSS |
| Backend | Rust (Tauri commands) |
| IPC | Tauri invoke() â no REST or WebSocket API |
All communication between the React frontend and Rust backend goes through Tauri's built-in IPC mechanism, not HTTP.
Prerequisites
Make sure the following are installed before you begin:
| Tool | Version | Purpose |
|---|---|---|
| Node.js | v18+ | JavaScript runtime |
| pnpm | latest | Package manager |
| Rust | v1.77.2+ | Backend compilation |
| Cargo | (bundled with Rust) | Rust build tool |
Install all prerequisites (Node.js, pnpm, and Rust):
# Install Node.js & pnpm (macOS with Homebrew)
brew install node pnpm
# Or on Linux/macOS without Homebrew, install Node.js from https://nodejs.org/
# Then install pnpm globally:
npm install -g pnpm
# Install Rust via rustup
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
# Activate Rust environment
source $HOME/.cargo/env
Windows users: Install Node.js from the official installer, then run npm install -g pnpm and rustup-init from https://rustup.rs/
Getting Started
# 1. Clone the repository
git clone https://github.com/tukuyomil032/MC-Vector.git
cd MC-Vector
# 2. Install JS dependencies
pnpm install
# 3. Launch development server (hot-reload for both frontend and backend)
pnpm tauri dev
# 4. Build production binary (when ready to ship)
pnpm tauri build
First run: The Rust crate compilation will take a few minutes. Subsequent runs use the incremental build cache and start faster.
Platform-specific bundles are output to:
src-tauri/target/release/bundle/
âââ dmg/ â macOS DMG
âââ macos/ â macOS .app
âââ nsis/ â Windows NSIS installer (.exe)
Project Structure
MC-Vector/
âââ src/ # Frontend (React + Vite)
â âââ App.tsx # Root component & view router
â âââ main.tsx # Vite / React entry point
â âââ index.css # Global styles (Tailwind)
â âââ vite-env.d.ts # Vite type declarations + SVG module
â âââ assets/
â â âââ icons/ # SVG icon files (folder, file, trashâŠ)
â âââ lib/ # Tauri IPC command wrappers
â â âââ server-commands.ts # Server start/stop/restart
â â âââ backup-commands.ts # Backup operations
â â âââ file-commands.ts # File system operations
â â âââ plugin-commands.ts # Plugin/mod management
â â âââ java-commands.ts # Java detection & management
â â âââ ngrok-commands.ts # ngrok tunnel control
â â âââ proxy-commands.ts # Proxy server setup
â â âââ config-commands.ts # Config read/write
â â âââ update-commands.ts # App auto-update
â âââ renderer/
â âââ components/ # Feature UI components
â â âââ DashboardView.tsx # CPU/RAM graphs (Recharts)
â â âââ ConsoleView.tsx # Live console + ANSI output
â â âââ FilesView.tsx # File manager (Monaco editor)
â â âââ BackupsView.tsx # Backup creation & restore
â â âââ PluginBrowser.tsx # Modrinth / Hangar browser
â â âââ UsersView.tsx # Whitelist / ban / op management
â â âââ ProxySetupView.tsx # Velocity / Waterfall setup
â â âââ ProxyHelpView.tsx # Proxy configuration guide
â â âââ AddServerModal.tsx # New server wizard modal
â â âââ NgrokGuideView.tsx # ngrok guide view
â â âââ SettingsWindow.tsx # App settings (theme, etc.)
â â âââ JavaManagerModal.tsx # JRE download & management
â â âââ Toast.tsx # Toast notification component
â â âââ ToastProvider.tsx # Toast context provider
â â âââ properties/
â â âââ PropertiesView.tsx # Quick server.properties editor
â â âââ AdvancedSettingsWindow.tsx # Full 60+ property editor
â â âââ ServerSettings.tsx # Server meta settings
â âââ shared/
â â âââ propertiesData.ts # 60+ server.properties definitions
â â âââ server declaration.ts # MinecraftServer & AppView types
â âââ constants/
â âââ versionOptions.ts # Supported Minecraft version list
â
âââ src-tauri/ # Rust backend (Tauri)
âââ tauri.conf.json # Tauri app configuration
âââ Cargo.toml # Rust dependencies
âââ src/
âââ main.rs # Entry point
âââ commands/ # Tauri command handlers
âââ server.rs # Server process management
âââ backup.rs # Backup / restore
âââ file_utils.rs # File operations
âââ java.rs # Java runtime detection
âââ ngrok.rs # ngrok integration
âââ download.rs # Server .jar download
âââ process_stats.rs # CPU/RAM monitoring
Config & Data File Paths
When MC-Vector creates servers and stores application data, it uses the following OS-specific paths:
| Platform | Base Path |
|---|---|
| macOS | ~/Library/Application Support/MC-Vector/ |
| Windows | C:\Users\<username>\AppData\Roaming\MC-Vector\ |
Server data layout
MC-Vector/
âââ servers/
âââ <server-name>/
âââ server.jar â Downloaded server software
âââ server.properties
âââ eula.txt
âââ world/ â World data
âââ plugins/ or mods/ â Installed plugins/mods
âââ backups/ â ZIP backups created via the app
âââ backup-2026-02-26T12-00-00.zip
App config
MC-Vector/
âââ config.json â Stores server list, ngrok token, theme preference, etc.
Architecture Notes
- Tauri IPC â The frontend calls
invoke("command_name", { args })to interact with Rust. Seesrc/lib/*.tsfor all available commands. - No REST API â There is no HTTP server exposed. All communication is local Tauri IPC.
- No auto-backup â Backups are created manually by the user from the Backups tab.
- Dashboard â Uses Recharts to display CPU/RAM graphs updated every 2 seconds via Tauri events.
- Console â ANSI 16-color, auto-scrolls when within 120px of bottom, 2000-line buffer.
Writing a New Tauri Command
1. Define the command in Rust
Add a new file under src-tauri/src/commands/ or append to an existing one:
// src-tauri/src/commands/example.rs
use tauri::State;
use crate::state::AppState;
#[tauri::command]
pub async fn get_server_count(
state: State<'_, AppState>,
) -> Result<usize, String> {
let servers = state.servers.lock().await;
Ok(servers.len())
}
2. Register in main.rs
// src-tauri/src/main.rs
.invoke_handler(tauri::generate_handler![
// ... existing commands ...
commands::example::get_server_count,
])
3. Declare the permission (Tauri v2)
Tauri v2 requires explicit capability declarations. Edit src-tauri/capabilities/default.json:
{
"identifier": "default",
"description": "Default capabilities",
"permissions": [
"core:default",
"shell:allow-open"
]
}
4. Call from the React frontend
Wrap the invoke call in a typed helper in src/lib/:
// src/lib/server-commands.ts
import { invoke } from "@tauri-apps/api/core";
export async function getServerCount(): Promise<number> {
return invoke<number>("get_server_count");
}
Then use it in any component:
// src/renderer/components/Dashboard.tsx
import { getServerCount } from "@/lib/server-commands";
const count = await getServerCount();
console.log(`Managing ${count} servers`);
Console â Implementation Details
Server stdout/stderr is captured by a tokio task in Rust and emitted as Tauri events:
// src-tauri/src/commands/server.rs
tokio::spawn(async move {
let reader = BufReader::new(stdout);
for line in reader.lines() {
let Ok(line) = line else { break };
app_handle
.emit("server-log", LogPayload {
server_id: id.clone(),
line: line.trim_end().to_string(),
})
.ok();
}
});
The React console component subscribes and enforces the 2,000-line buffer:
// src/renderer/components/ConsoleView.tsx
import { listen } from "@tauri-apps/api/event";
const unlisten = await listen<LogPayload>("server-log", ({ payload }) => {
if (payload.server_id !== currentServerId) {
return;
}
setLines((prev) => {
const next = [...prev, payload.line];
return next.length > 2000 ? next.slice(-2000) : next; // buffer cap
});
});
// cleanup on unmount
return () => unlisten();
Auto-scroll logic (120 px threshold):
const handleScroll = () => {
if (!containerRef.current) {
return;
}
const { scrollTop, scrollHeight, clientHeight } = containerRef.current;
isAtBottomRef.current = scrollHeight - scrollTop - clientHeight < 120;
};
useEffect(() => {
if (isAtBottomRef.current) {
containerRef.current?.scrollTo({ top: containerRef.current.scrollHeight });
}
}, [lines]);
Useful Commands
| Command | Description |
|---|---|
pnpm tauri dev | Start dev server with hot-reload |
pnpm tauri build | Build production binary |
pnpm lint | Run ESLint |
pnpm format | Prettier format |
cargo test | Run Rust unit tests (in src-tauri/) |
cargo clippy | Rust linter |
cargo doc --open | Generate and open Rust API docs |
Contributing
- Fork the repo and create a feature branch:
git checkout -b feat/my-awesome-feature
- Implement your change, then verify:
# Frontend checks
pnpm lint && pnpm format --check
# Rust checks
cd src-tauri && cargo clippy -- -D warnings && cargo test
- Open a pull request against
mainwith a description of what you changed and why.