install
source · Clone the upstream repo
git clone https://github.com/different-ai/openwork
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/different-ai/openwork "$T" && mkdir -p ~/.claude/skills && cp -r "$T/.opencode/skills/tauri-solidjs" ~/.claude/skills/different-ai-openwork-tauri-solidjs && rm -rf "$T"
manifest:
.opencode/skills/tauri-solidjs/SKILL.mdsource content
Quick Usage (Already Configured)
Create new Tauri + SolidJS project
pnpm create tauri-app openwork --template solid-ts
Development
pnpm tauri dev
Build for production
pnpm tauri build
Build for mobile
# iOS pnpm tauri ios dev pnpm tauri ios build # Android pnpm tauri android dev pnpm tauri android build
Project Structure
openwork/ packages/ desktop/ src-tauri/ src/ main.rs # Rust entry point lib.rs # Tauri commands and state Cargo.toml # Rust dependencies tauri.conf.json # Tauri configuration capabilities/ # Permission capabilities src/ App.tsx # SolidJS root component index.tsx # Entry point components/ # UI components stores/ # Solid stores for state lib/ # Utilities and OpenCode bridge index.html # HTML template package.json # Frontend dependencies vite.config.ts # Vite configuration
Key Dependencies
Frontend (package.json)
{ "dependencies": { "solid-js": "^1.8.0", "@tauri-apps/api": "^2.0.0", "@tauri-apps/plugin-shell": "^2.0.0", "@tauri-apps/plugin-fs": "^2.0.0", "@tauri-apps/plugin-sql": "^2.0.0" }, "devDependencies": { "@tauri-apps/cli": "^2.0.0", "vite": "^5.0.0", "vite-plugin-solid": "^2.8.0", "tailwindcss": "^3.4.0" } }
Backend (Cargo.toml)
[dependencies] tauri = { version = "2", features = ["shell-open"] } tauri-plugin-shell = "2" tauri-plugin-fs = "2" tauri-plugin-sql = { version = "2", features = ["sqlite"] } serde = { version = "1", features = ["derive"] } serde_json = "1"
Tauri Commands (Rust -> JS)
// packages/desktop/src-tauri/src/lib.rs use tauri::Manager; #[tauri::command] async fn spawn_opencode(prompt: String) -> Result<String, String> { use std::process::Command; let output = Command::new("opencode") .args(["-p", &prompt, "-f", "json", "-q"]) .output() .map_err(|e| e.to_string())?; String::from_utf8(output.stdout) .map_err(|e| e.to_string()) } #[tauri::command] fn get_opencode_db_path() -> String { // Return path to .opencode/opencode.db dirs::home_dir() .map(|p| p.join(".opencode/opencode.db").to_string_lossy().to_string()) .unwrap_or_default() }
Invoking Commands from SolidJS
import { invoke } from "@tauri-apps/api/core"; async function runTask(prompt: string) { const result = await invoke<string>("spawn_opencode", { prompt }); return JSON.parse(result); }
Common Gotchas
- Tauri 2.x uses
instead of@tauri-apps/api/core
.@tauri-apps/api/tauri - Mobile builds require Xcode (iOS) or Android Studio (Android).
- File access requires
and capability configuration.tauri-plugin-fs - SQLite access requires
.tauri-plugin-sql
First-Time Setup (If Not Configured)
Install Tauri CLI
pnpm add -D @tauri-apps/cli
Initialize Tauri in existing project
pnpm tauri init
Add mobile targets
pnpm tauri ios init pnpm tauri android init