GeoLibre Build System Tools: A Complete Guide to npm Workspaces, Vite, and Tauri

GeoLibre uses npm workspaces, Vite, Cargo, and Tauri to build a polyglot GIS platform that outputs web bundles, native desktop binaries, and Python embeddings from a single monorepo.

The opengeos/GeoLibre repository is a multi-language geographic information system (GIS) platform that orchestrates JavaScript, Rust, and Python through a unified build pipeline. This analysis breaks down every build tool, configuration file, and custom script that powers the development workflow.


JavaScript and TypeScript Build Tools

GeoLibre's frontend and worker layers rely on a modern JavaScript toolchain centered on npm workspaces and Vite.

npm Workspaces

The root package.json declares a monorepo structure using npm workspaces:

{
  "workspaces": ["apps/*", "packages/*", "workers/*"]
}

This configuration, found at [package.json](https://github.com/opengeos/GeoLibre/blob/main/package.json#L6-L9), enables single-command dependency management across three distinct code groups. Running npm install hoists shared dependencies and establishes a unified dependency graph for the entire project.

Vite and Rollup

Vite serves as the primary build orchestrator. The core configuration lives in [apps/geolibre-desktop/vite.config.ts](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/vite.config.ts#L1-L8):

import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import { resolve } from 'path'

export default defineConfig({
  plugins: [react()],
  build: {
    rollupOptions: {
      // Manual chunking rules for code-splitting
    }
  }
})

Vite wraps Rollup for production bundling. The configuration defines manualChunks to control code splitting and asset boundaries. This setup handles hot module replacement (HMR) during development and optimized static asset generation for deployment.

esbuild for Minification

GeoLibre plugs esbuild directly into the Vite pipeline through a custom plugin. In [vite.config.ts](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/vite.config.ts#L13-L31), the selectiveJsMinifyPlugin uses esbuild's transform API to minify specific production chunks:

const selectiveJsMinifyPlugin = {
  name: 'selective-js-minify',
  renderChunk(code, chunk) {
    if (shouldMinify(chunk.fileName)) {
      return esbuild.transform(code, { minify: true })
    }
    return null
  }
}

This selective approach avoids minifying already-optimized vendor bundles while compressing application code.

tsx for ESM-native Testing

tsx enables TypeScript execution without compilation. Listed under devDependencies in [package.json](https://github.com/opengeos/GeoLibre/blob/main/package.json#L41-L48), it supports native ESM test runs:

node --import tsx --test src/**/*.test.ts

This eliminates the need for a separate TypeScript compilation step in test workflows.

Playwright for End-to-End Testing

Playwright combined with @axe-core/playwright provides accessibility-aware browser testing. The test:e2e npm script executes against the built web application, validating runtime behavior and WCAG compliance.


Rust Build Tools for Tauri Desktop

GeoLibre produces native desktop applications through the Tauri framework, which binds a Rust backend to the Vite-generated frontend.

Cargo Package Management

Cargo manages the Rust crate defined in [apps/geolibre-desktop/src-tauri/Cargo.toml](https://github.com/opengeos/GeoLibre/blob/main/apps/geolibre-desktop/src-tauri/Cargo.toml#L1-L30):

[package]
name = "geolibre-desktop"
version = "0.1.0"

[features]
native-duckdb = ["duckdb"]
mas = ["tauri/macos-private-api"]

[profile.release]
opt-level = "s"
lto = true

This manifest declares feature flags for optional DuckDB integration and macOS App Store compatibility, plus release optimizations for binary size (opt-level = "s") and link-time optimization.

Tauri v2 CLI

Tauri v2 bridges the Rust shell with the web frontend. The build process invokes the Tauri CLI through a Node.js wrapper script:

npm run tauri:build

This command compiles the Rust binary, bundles the Vite output, and generates platform-specific installers for Windows, macOS, and Linux.


Python Build Tools for Backend Services

GeoLibre includes a FastAPI sidecar service managed through modern Python tooling.

uv for Dependency Locking

uv replaces pip for dependency resolution and locking. The backend/geolibre_server/uv.lock file pins exact versions of all transitive dependencies. CI validates lockfile consistency with:

uv lock --check

This ensures reproducible builds across environments without the performance cost of traditional pip resolution.

pytest for Test Execution

pytest and pytest-cov run backend unit tests with coverage enforcement:

pytest --cov=geolibre_server --cov-fail-under=55

The --cov-fail-under=55 threshold blocks merges that reduce test coverage below 55%.


Custom Build Scripts

GeoLibre extends standard tooling with Node.js scripts in the scripts/ directory.

lite-build.mjs for Cloudflare Deployment

scripts/lite-build.mjs wraps the standard build with Cloudflare-specific constraints:

// Enforces 25 MiB per-file limit for Cloudflare Pages
const MAX_FILE_SIZE = 25 * 1024 * 1024

async function validateBuild(outputDir) {
  const files = await glob(`${outputDir}/**/*.{js,wasm}`)
  for (const file of files) {
    const stats = await stat(file)
    if (stats.size > MAX_FILE_SIZE) {
      throw new Error(`${file} exceeds ${MAX_FILE_SIZE} bytes`)
    }
  }
}

Lines 73-81 implement the size validation logic, failing the build if any asset exceeds Cloudflare's limit. The script also offloads DuckDB-WASM to jsDelivr CDN to reduce bundle size.

tauri-build.mjs for Flagged Builds

scripts/tauri-build.mjs orchestrates Tauri compilation with optional feature flags:


# Standard release

node scripts/tauri-build.mjs

# With native DuckDB (bundles WASM locally)

node scripts/tauri-build.mjs --native-duckdb

# macOS App Store variant

node scripts/tauri-build.mjs --mas

CI and Automation Integration

GeoLibre's build tools chain together in CI through npm script composition.

Unified CI Command

The root package.json defines a comprehensive CI pipeline at lines 28-30:

npm run ci

This executes: lint → build → test:frontend:coverage → test:worker → test:backend:coverage → check:rust

Rust Check Integration

The check:rust script invokes Cargo validation:

cargo check --manifest-path apps/geolibre-desktop/src-tauri/Cargo.toml

This catches compilation errors without producing a full release binary.

Pre-commit Hooks

pre-commit runs the full npm build before accepting commits, ensuring compiled assets in the repository remain synchronized with source changes. The .pre-commit-config.yaml references a local npm-build hook.


Build Outputs

GeoLibre's build system produces three distinct artifacts from one source tree:

Output Toolchain Location
Web bundle Vite + Rollup apps/geolibre-desktop/dist/
Desktop binary Tauri + Cargo apps/geolibre-desktop/src-tauri/target/
Python wheel npm workspaces + setuptools python/ (Jupyter embedding)

Summary

  • npm workspaces unify dependency management across apps, packages, and workers in a single monorepo structure defined in the root package.json.
  • Vite with Rollup and esbuild handles development serving, HMR, and optimized production bundling with custom chunking rules in vite.config.ts.
  • Cargo and Tauri v2 compile the Rust desktop shell with feature flags for platform-specific and optional native dependencies.
  • uv and pytest manage the Python FastAPI backend with locked dependencies and coverage-gated testing.
  • Custom scripts (lite-build.mjs, tauri-build.mjs) enforce deployment constraints and orchestrate complex build variants.
  • The CI pipeline (npm run ci) validates the entire stack through chained npm scripts including Rust compilation checks.

Frequently Asked Questions

What is the primary JavaScript bundler in GeoLibre?

Vite is the primary bundler. It provides the development server, handles hot module replacement, and orchestrates Rollup for production builds. The configuration in apps/geolibre-desktop/vite.config.ts includes custom plugins for selective esbuild minification and manual chunk splitting.

How does GeoLibre manage dependencies across multiple languages?

GeoLibre uses npm workspaces for JavaScript/TypeScript, Cargo for Rust, and uv for Python. Each tool maintains its own lockfile (package-lock.json, Cargo.lock, uv.lock) to ensure reproducible builds. The CI pipeline validates all three ecosystems through a single npm run ci command.

Can GeoLibre build a lightweight web version without desktop features?

Yes. The npm run lite:build command executes scripts/lite-build.mjs, which produces a Cloudflare-compatible bundle. This variant offloads DuckDB-WASM to jsDelivr CDN and enforces a 25 MiB per-file size limit, making it suitable for edge deployment without the Rust desktop shell.

What testing frameworks does GeoLibre use?

GeoLibre employs three testing stacks: Node.js test runner with tsx for ESM-native TypeScript tests, Playwright with axe-core for browser-based end-to-end testing, and pytest with coverage thresholds for the Python backend. Each integrates into the npm run ci pipeline with distinct coverage requirements.

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 →