Skip to content
Public template

About

Rust + Vue 3 + Tauri v2 desktop starter - CI/CD, testing, and cross-platform releases out of the box

Topics

Resources

Contributing

Security policy

Stars

100 stars

Watchers

3 watching

Forks

Latest commit

 

History

173 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OxideDock

CI License: MIT GitHub stars Release PRs Welcome

Raw speed, refined desktop.

OxideDock is a Rust + Vue 3 desktop starter built on Tauri v2 — native performance, polished DX, ship-ready apps.

OxideDock screenshot

Why OxideDock?

Starting a Tauri app from scratch means wiring up routing, state management, testing, linting, CI/CD, and release pipelines yourself. OxideDock gives you all of that out of the box so you can skip the boilerplate and start building your app from day one.

  • Production-ready defaults — linting, formatting, testing, and CI all preconfigured
  • Cross-platform releases — push a tag and get Linux, macOS, and Windows binaries
  • One command — make dev and you're running

Features

  • Tauri v2 — lightweight, secure desktop runtime
  • Vue 3 — reactive frontend with Composition API
  • Vite — fast dev server and build tool
  • TypeScript — type-safe frontend and configuration
  • Guarded IPC — a test fails the build if Rust commands and the TypeScript layer drift apart
  • Tailwind CSS v4 — utility-first styling with Vite plugin
  • Vue Router — client-side routing
  • Pinia — type-safe state management
  • VueUse — essential Vue composables
  • Vitest — fast unit and component testing
  • Playwright — e2e testing against the web frontend
  • ESLint — flat config with Vue 3 rules
  • Biome — fast formatting and linting
  • Clippy + Rustfmt — Rust linting and formatting
  • cargo-audit — Rust dependency security auditing
  • Lefthook — fast, parallel pre-commit hooks
  • GitHub Actions — CI (lint + test + build) and release pipelines
  • Makefile — unified task runner for all operations

Prerequisites

Quick Start

# Clone the template
git clone https://github.com/fridzema/oxide-dock.git
cd oxide-dock

# Verify prerequisites (Rust, Bun)
make check

# Install dependencies
make setup

# (Optional) Rename the project to your own app
make bootstrap

# Start development
make dev

Project Structure

oxidedock/
├── .github/workflows/     # CI and release pipelines
├── .vscode/               # Editor settings and extensions
├── src/                   # Vue 3 frontend
│   ├── components/        # Reusable components
│   ├── composables/       # Shared composables
│   ├── layouts/           # Layout components
│   ├── pages/             # Route views
│   ├── router/            # Vue Router configuration
│   ├── stores/            # Pinia stores
│   ├── App.vue            # Root component
│   ├── main.ts            # App entry point
│   └── style.css          # Tailwind CSS imports
├── src-tauri/             # Rust backend
│   ├── src/               # Rust source code
│   ├── capabilities/      # Permission capabilities
│   ├── Cargo.toml         # Rust dependencies
│   └── tauri.conf.json    # Tauri configuration
├── tests/
│   ├── unit/              # Vitest unit tests
│   └── e2e/               # Playwright e2e tests
├── Makefile               # Task runner
├── lefthook.yml           # Git hooks
└── README.md

Available Commands

Development

Command Description
make dev Start Tauri dev with hot reload
make dev-frontend Start Vite dev server only
make build Build production binary
make build-debug Build with debug console

Linting & Formatting

Command Description
make lint Run all linters (ESLint + Biome + Clippy)
make lint-fix Auto-fix linting issues
make format Format all files
make format-check Check formatting

Testing

Command Description
make test Run all tests
make test-unit Run Vitest unit tests
make test-e2e Run Playwright e2e tests
make test-watch Run Vitest in watch mode

Rust

Command Description
make rust-lint Run Clippy
make rust-format Run Rustfmt
make rust-audit Check for vulnerabilities
make rust-test Run Rust tests

CI, Setup & Bootstrap

Command Description
make check Verify prerequisites are installed
make setup Install all dependencies
make bootstrap Rename project to your own app
make ci Run full CI pipeline locally
make coverage Run all coverage (Rust + Vue)
make clean Remove build artifacts

Tech Stack

Technology Version Purpose
Tauri v2 Desktop runtime
Vue v3 Frontend framework
Vite v8 Build tool
TypeScript v6 Type safety
Tailwind CSS v4 Styling
Vue Router v5 Routing
Pinia v4 State management
VueUse latest Composable utilities
Vitest latest Unit testing
Playwright latest E2e testing
ESLint v10 Vue linting
Biome v2 Formatting and linting
Lefthook latest Git hooks

Type-Safe IPC

Commands cross the Rust/TypeScript boundary through src/shared/ipc.ts: every command gets a typed wrapper, and Rust's structured AppError gets a matching TypeScript type.

Three places have to agree for a command to work: it must be defined with #[tauri::command] in src-tauri/src/handlers.rs, registered in tauri::generate_handler! in src-tauri/src/lib.rs, and declared in CommandResults in src/shared/ipc.ts. Miss one and the failure shows up at runtime, usually as a confusing "command not found".

tests/unit/ipc-surface.test.ts reads all three and fails the build if they disagree, so that class of bug cannot reach a release.

This checks the command surface — that every command exists in all three places under the same name. It does not verify argument or payload field types; those still rely on the hand-written types in src/shared/ipc.ts matching the Rust structs.

Recipes

Optional features are opt-in, not preinstalled. Each one is a recipe — an idempotent script that wires the feature into your checkout: dependency, plugin registration, capability, config.

make add-window-state   # remember window size and position across restarts
make add-tray           # system tray icon with a menu
make add-updater        # in-app auto-updates (needs signing keys)

Each recipe prints what it changed and points at its own README under recipes/. Recipes modify your working tree and are meant to be run once and committed — review the diff like any other change. git checkout -- is the undo.

Verified in CI

recipes.yml applies every recipe to a clean checkout on every push and pull request, then runs ESLint, Biome, the TypeScript type check, the Vitest suite, cargo clippy -- -D warnings and cargo test against the result. It applies the recipe a second time and fails if that produces any diff, so a recipe that stops being idempotent cannot land.

Pull requests deliberately skip the app build to keep the feedback loop short. recipes-nightly.yml covers it: once a day it runs the full make ci — including bun tauri build — for every recipe on Linux.

CI/CD

CI Pipeline (ci.yml)

Runs on every push to main and on pull requests:

  1. Lint — ESLint, Biome check, TypeScript type check
  2. Rust Lint — Clippy + Rustfmt (Linux only)
  3. Test — Vitest unit tests, Playwright e2e (chromium), Rust tests on all platforms with coverage on Linux
  4. Audit — cargo audit runs daily and on Cargo dependency changes (separate workflow)
  5. Build — Linux smoke build (main branch only); full cross-platform build happens at release time

Release Pipeline

Releases are fully automated via release-please:

  1. Push conventional commits to main (fix:, feat:, feat!:)
  2. Release-please opens a PR bumping versions and updating CHANGELOG.md
  3. Merging the PR tags the release, triggering cross-platform builds
  4. A draft GitHub Release is created with platform binaries:
    • Linux: .deb, .AppImage
    • macOS: .dmg (Intel + Apple Silicon)
    • Windows: .msi, .exe

Check release status with make release-status.

Customization

Change App Name and Icon

  1. Update name in package.json
  2. Update productName in src-tauri/tauri.conf.json
  3. Replace icons in src-tauri/icons/ (use bun tauri icon /path/to/icon.png)

Add a UI Component Library

# Shadcn Vue
bunx shadcn-vue@latest init

# Or PrimeVue
bun add primevue

Add Internationalization

bun add vue-i18n

Create locale files in src/locales/ and register the plugin in src/main.ts.

Code Signing

Follow the Tauri code signing guide to set up signing for macOS and Windows distribution.

Built with OxideDock

Apps shipped on top of OxideDock:

  • SoapDuck — a native macOS SOAP client for developers: load WSDLs, build and send SOAP requests, and inspect responses, with WS-Security and certificate signing.

Built something with OxideDock? Open a PR to add it here.

Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/your-feature)
  3. Make your changes
  4. Run make ci to verify everything passes
  5. Commit with a descriptive message
  6. Push and open a pull request

Contributors

License

MIT

About

Rust + Vue 3 + Tauri v2 desktop starter - CI/CD, testing, and cross-platform releases out of the box

Topics

Resources

Contributing

Security policy

Stars

100 stars

Watchers

3 watching

Forks

Releases

Packages

Used by

Contributors

Languages