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 thenative-duckdbCargo feature--mas— Enables themasCargo 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 —
beforeDevCommandandbeforeBuildCommandinvoke the npm scripts described earlier - Development URL —
http://localhost:5173for 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:
- TypeScript compilation —
tsc -bvalidates types across all workspace packages - Vite bundling — Produces optimized static assets in
apps/geolibre-desktop/dist/ - Tauri CLI invocation —
tauri-build.mjsspawns the Rust compiler with default features - Binary assembly — The Rust backend embeds the
dist/folder asfrontendDist, compiles native dependencies, and links the final executable - Installer generation — Platform-specific packages (
.app,.exe,.deb,.rpm) are created insrc-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
masCargo feature - Switches configuration to
tauri.mas.conf.json - Disables the Python sidecar, Jupyter integration, and automatic updater
- Sets
GEOLIBRE_STORE_BUILD=1andGEOLIBRE_MAS_BUILD=1for 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.mjshandles 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →