How the Tauri v2 Desktop Build Works in the GeoLibre npm Workspaces Monorepo

The GeoLibre repository uses a Tauri v2 desktop build wrapped in an npm workspaces monorepo, where the desktop app at apps/geolibre-desktop bundles a Vite-built web UI with native Rust binaries and an optional Python sidecar.

GeoLibre's Tauri v2 desktop build functions as a specialized package within a unified npm workspaces monorepo. According to the opengeos/GeoLibre source code, this architecture lets the team maintain all JavaScript/TypeScript packages under @geolibre/* namespaces while isolating desktop-specific concerns in a dedicated application folder. The result is a cross-platform native binary that embeds a modern web interface, with build orchestration handled through custom npm scripts and a Node.js build script.

npm Workspaces Structure and Desktop Package Location

The monorepo root defines workspaces that include all library packages and the desktop application. The desktop client lives at apps/geolibre-desktop and functions as a standard npm workspace member with its own package.json, dependencies, and build lifecycle.

This structure allows shared dependencies to be hoisted to the repository root while letting the desktop package declare Tauri-specific tooling locally. Other packages in the workspace can import @geolibre/* libraries as if they were published modules, enabling code reuse between web and desktop targets.

Build Scripts and Development Workflow

All Tauri v2 desktop build operations are exposed through npm scripts defined in apps/geolibre-desktop/package.json. These scripts bridge the Vite bundler, TypeScript compiler, and Tauri CLI:

Script Purpose
npm run dev Starts the Vite development server on port 5173
npm run build Runs tsc -b across workspaces and produces the production web bundle in dist/
npm run tauri:dev Launches a hot-reloading Tauri window pointing at http://localhost:5173
npm run tauri:build Executes the production desktop build pipeline
npm run tauri:build:native-duckdb Builds with native DuckDB instead of WebAssembly
npm run tauri:build:mas Builds a Mac App Store-compliant package

The tauri:dev script is particularly useful for iterative development. It keeps the Vite dev server running and opens a native window that loads from the dev URL, enabling rapid testing of desktop-specific APIs alongside web UI changes.

The Custom Build Script: scripts/tauri-build.mjs

The core orchestration for production builds happens in scripts/tauri-build.mjs. This Node.js module parses arguments, sets environment variables, and spawns the Tauri CLI with the correct flags. According to the GeoLibre source code, the script performs these sequential operations:

Argument Parsing and Flag Detection

The script scans process.argv for two optional flags:

  • --native-duckdb — Enables the native-duckdb Cargo feature
  • --mas — Enables the mas Cargo feature for Mac App Store compliance

These flags are stripped from the argument list before forwarding to the Tauri CLI.

Platform-Specific Defaults

On Linux systems without explicit bundle arguments, the script automatically appends --bundles deb,rpm to produce native package formats suitable for distribution.

Feature Gating and Environment Injection

The build script translates npm script flags into Cargo features and environment variables:

// Simplified logic from scripts/tauri-build.mjs
if (args.includes('--native-duckdb')) {
  cargoFeatures.push('native-duckdb');
}

if (args.includes('--mas')) {
  cargoFeatures.push('mas');
  process.env.GEOLIBRE_STORE_BUILD = '1';
  process.env.GEOLIBRE_MAS_BUILD = '1';
}

The native-duckdb feature swaps the DuckDB query engine from its WebAssembly build to a native binary, significantly improving performance for large geospatial vector and raster operations.

The mas feature triggers stricter packaging rules. It swaps the Tauri configuration to tauri.mas.conf.json, and the environment variables GEOLIBRE_STORE_BUILD and GEOLIBRE_MAS_BUILD signal downstream code to strip prohibited components: the Python sidecar, Jupyter integration, and external download capabilities.

CLI Execution

Finally, the script assembles the command and spawns the Tauri CLI through the workspace:

import { spawnSync } from 'child_process';

const result = spawnSync(
  'npm',
  ['run', 'tauri', '-w', 'geolibre-desktop', '--', 'build', ...finalArgs],
  {
    stdio: 'inherit',
    env: process.env
  }
);

process.exit(result.status ?? 1);

The script exits with the same status code returned by the Tauri CLI, ensuring CI/CD pipelines can detect build failures correctly.

Tauri Configuration Files

Primary Configuration: tauri.conf.json

The main Tauri configuration at apps/geolibre-desktop/src-tauri/tauri.conf.json defines the desktop application's core properties:

  • Product metadata — Name, version, and unique identifier
  • Build hooks — beforeDevCommand and beforeBuildCommand invoke the npm scripts described earlier
  • Development URL — http://localhost:5173 for hot-reload development
  • Security policies — Content Security Policy (CSP), custom asset protocols, and capabilities that govern IPC and local resource access for the MapLibre-based map view
  • Bundle resources — Embeds backend/geolibre_server (the Python FastAPI sidecar) and specifies icon sets

Mac App Store Variant: tauri.mas.conf.json

When building for the Mac App Store, the build script switches to tauri.mas.conf.json. This variant removes or restricts capabilities that violate Apple's sandboxing requirements, such as arbitrary code execution and external process spawning.

Rust Entry Point: main.rs

The file apps/geolibre-desktop/src-tauri/src/main.rs initializes the Tauri application, registers native plugins (dialog, filesystem, geolocation), and mounts the webview. Feature gates in this file respond to the native-duckdb and mas Cargo features to conditionally compile platform-specific behavior.

Complete Build Pipeline Walkthrough

Standard Desktop Build

Running npm run tauri:build executes this sequence:

  1. TypeScript compilation — tsc -b validates types across all workspace packages
  2. Vite bundling — Produces optimized static assets in apps/geolibre-desktop/dist/
  3. Tauri CLI invocation — tauri-build.mjs spawns the Rust compiler with default features
  4. Binary assembly — The Rust backend embeds the dist/ folder as frontendDist, compiles native dependencies, and links the final executable
  5. Installer generation — Platform-specific packages (.app, .exe, .deb, .rpm) are created in src-tauri/target/release/bundle/

Native DuckDB Build

The npm run tauri:build:native-duckdb variant adds the native-duckdb Cargo feature. This:

  • Links against the native DuckDB shared library instead of bundling the WASM module
  • Reduces memory overhead and improves query throughput for geospatial datasets
  • Increases binary size and platform-specific dependency requirements

Mac App Store Build

The npm run tauri:build:mas variant produces a package suitable for Apple notarization:

  • Activates the mas Cargo feature
  • Switches configuration to tauri.mas.conf.json
  • Disables the Python sidecar, Jupyter integration, and automatic updater
  • Sets GEOLIBRE_STORE_BUILD=1 and GEOLIBRE_MAS_BUILD=1 for runtime feature detection

Python Sidecar Integration

The backend/geolibre_server directory contains a FastAPI application that provides vector/raster processing services. During the Tauri build, this Python environment is packaged as a sidecar resource — a separate binary spawned by the Rust backend and communicated with over local IPC. This architecture keeps heavy geospatial computation out of the JavaScript main thread while maintaining a seamless user experience.

The sidecar is excluded from MAS builds per App Store policy, requiring those builds to rely on lighter, sandbox-compatible alternatives.

Practical Build Commands


# Clone and install dependencies

git clone https://github.com/opengeos/GeoLibre.git
cd GeoLibre
npm install

# Development with hot reload

npm run tauri:dev

# Standard production build

npm run tauri:build

# Linux build with native DuckDB for better performance

npm run tauri:build:native-duckdb

# Mac App Store submission build

npm run tauri:build:mas

# Build for specific targets only

npm run tauri:build -- --target aarch64-apple-darwin

Key Files Reference

File Purpose
apps/geolibre-desktop/package.json Workspace entry and npm script definitions
scripts/tauri-build.mjs Build orchestration and feature flag handling
apps/geolibre-desktop/src-tauri/tauri.conf.json Primary Tauri configuration
apps/geolibre-desktop/src-tauri/tauri.mas.conf.json Mac App Store variant configuration
apps/geolibre-desktop/src-tauri/src/main.rs Rust application entry point
backend/geolibre_server/ Python FastAPI sidecar for geoprocessing

Summary

  • Tauri v2 desktop build in GeoLibre operates within a standard npm workspaces monorepo, with the desktop app isolated at apps/geolibre-desktop
  • Custom build script at scripts/tauri-build.mjs handles feature flags (--native-duckdb, --mas) and spawns the Tauri CLI with correct arguments
  • Cargo features toggle between WebAssembly and native DuckDB engines, and between standard and Mac App Store compliance modes
  • Vite integration provides fast development workflows and optimized production bundles embedded in the native binary
  • Python sidecar extends desktop capabilities with FastAPI-based geoprocessing, excluded from MAS builds per platform policy

Frequently Asked Questions

What is the purpose of scripts/tauri-build.mjs in the GeoLibre Tauri v2 desktop build?

The script scripts/tauri-build.mjs serves as the build orchestrator for GeoLibre's Tauri v2 desktop application. It parses command-line flags like --native-duckdb and --mas, injects corresponding Cargo features and environment variables, adds platform-specific defaults (such as --bundles deb,rpm on Linux), and spawns the Tauri CLI through npm workspaces with all assembled arguments.

How does the native DuckDB feature improve performance in GeoLibre desktop builds?

The --native-duckdb flag enables the native-duckdb Cargo feature, which replaces the WebAssembly DuckDB implementation with a native binary linked at compile time. This eliminates WASM runtime overhead and memory constraints, delivering faster query execution for large vector and raster geospatial operations at the cost of increased binary size and platform-specific dependencies.

Why does the Mac App Store build disable the Python sidecar?

Apple's Mac App Store sandboxing policy prohibits applications from spawning external processes or executing arbitrary code. The GeoLibre build system detects the --mas flag, switches to tauri.mas.conf.json, and sets GEOLIBRE_MAS_BUILD=1 to exclude the Python sidecar, Jupyter integration, and automatic updater — components that would violate these policies and prevent App Store approval.

Can I add custom Cargo features to the GeoLibre Tauri build?

Yes. The scripts/tauri-build.mjs file uses standard Node.js argument parsing that you can extend to recognize additional flags. Add your feature detection logic alongside the existing --native-duckdb and --mas handlers, then append your feature to the cargoFeatures array before the Tauri CLI spawn call. Alternatively, create a new npm script that forwards raw arguments directly to npm run tauri -- build.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →