Skip to content

18 · Modules

Libraries from other languages

Declare versions once, install with Zolo and keep native imports.

On this page

One deps block declares libraries from multiple providers at file scope:

use plugin rust::{rust as rs}
use plugin native::{cpp}
use plugin jvm::{kotlin as kt}

deps {
    rs::serde_json = "1.0.145"
    cpp::fmt = { version = "11.0.2", default_features = true }
    kt::"com.google.guava:guava" = "33.4.0-jre"
}

Qualified package keys start with their imported language name or alias and ::. Quote keys containing punctuation. Short strings are exact pins; detailed options keep the provider's existing rules. The earlier extern provider deps form is also supported, and both forms can coexist.

Use serde_json, fmt and Guava from one declaration, including provider aliases. Prepare the packages with zolo install, then run the example.

47-unified-dependencies.zolo
Playground
// Prepare once: zolo install examples/features/14-modules/47-unified-dependencies.zolo
// Requires Rust, C++/vcpkg and the JVM/Kotlin provider toolchains for preparation.
// parity-timeout-ms:300000
use plugin rust::{rust as rs}
use plugin native::{cpp}
use plugin jvm::{kotlin as kt}

deps {
    rs::serde_json = "1.0.145"
    cpp::fmt = { version = "11.0.2", default_features = true }
    kt::"com.google.guava:guava" = "33.4.0-jre"
}

extern rs fn answer() -> int {
    let value: serde_json::Value = serde_json::from_str(r#"{"answer":42}"#).unwrap();
    value["answer"].as_i64().unwrap()
}

extern cpp fn formatted(value: int) -> str {
    #include <fmt/format.h>
    return fmt::format("exact {}", value);
}

extern kt fn join(values: [str]) -> str {
    import com.google.common.base.Joiner
    return Joiner.on(", ").join(values.asIterable())
}

print(answer())
print(formatted(9007199254740993))
print(join(["Kotlin", "Maven", "Zolo"]))

// expected:
// 42
// exact 9007199254740993
// Kotlin, Maven, Zolo

For several libraries from one provider, put unqualified keys inside a group:

deps {
    rs {
        serde_json = "1.0.145"
    }
    cpp::fmt = { version = "11.0.2", default_features = true }
    kt {
        "com.google.guava:guava" = "33.4.0-jre"
    }
}

Groups use the imported provider or alias. They can repeat and coexist with qualified entries and the earlier extern provider deps blocks. The same versions, options, installation policy and lock apply. Groups have one level; each package inside inherits its group's provider.

Mix provider groups with a qualified C++ package and reuse the same dependencies.

48-grouped-dependencies.zolo
Playground
// Prepare once: zolo install examples/features/14-modules/48-grouped-dependencies.zolo
// Requires Rust, C++/vcpkg and the JVM/Kotlin provider toolchains for preparation.
// parity-timeout-ms:300000
use plugin rust::{rust as rs}
use plugin native::{cpp}
use plugin jvm::{kotlin as kt}

deps {
    rs {
        serde_json = "1.0.145"
    }
    cpp::fmt = { version = "11.0.2", default_features = true }
    kt {
        "com.google.guava:guava" = "33.4.0-jre"
    }
}

extern rs fn answer() -> int {
    let value: serde_json::Value = serde_json::from_str(r#"{"answer":42}"#).unwrap();
    value["answer"].as_i64().unwrap()
}

extern cpp fn formatted(value: int) -> str {
    #include <fmt/format.h>
    return fmt::format("exact {}", value);
}

extern kt fn join(values: [str]) -> str {
    import com.google.common.base.Joiner
    return Joiner.on(", ").join(values.asIterable())
}

print(answer())
print(formatted(9007199254740993))
print(join(["Kotlin", "Maven", "Zolo"]))

// expected:
// 42
// exact 9007199254740993
// Kotlin, Maven, Zolo

Functions keep their own language's imports. Aliases work normally: JavaScript and TypeScript share the Node environment; C# uses .NET.

Use exact NumPy, date-fns and MathNet versions without installing packages inside functions. The first standalone zolo run prepares packages before compilation and writes 36-extern-dependencies.zolo.lock next to the script.

36-extern-dependencies.zolo
Playground
// In the examples project: zolo install examples/features/14-modules/36-extern-dependencies.zolo
// Copied outside a project, the first run prepares packages and writes this script's lock.
// Subsequent runs reuse verified environments. Requires the provider runtimes.
// parity-timeout-ms:120000
use plugin python::{python}
use plugin node::{typescript as ts}
use plugin dotnet::{csharp}

extern python deps {
    numpy = "2.3.3"
}

extern ts deps {
    "date-fns" = "4.1.0"
}

extern csharp deps {
    "MathNet.Numerics" = "5.0.0"
}

extern python fn mean(values: [float]) -> float {
    import numpy as np
    return float(np.mean(values))
}

extern ts fn date_label(value: string) -> string {
    import { format, parseISO } from "date-fns";
    return format(parseISO(value), "yyyy-MM-dd");
}

extern csharp fn factorial(n: int) -> float {
    using MathNet.Numerics;
    return SpecialFunctions.Factorial(checked((int)n));
}

print(mean([10.0, 20.0, 30.0]))
print(date_label("2026-09-30"))
print(factorial(5))

// expected:
// 20
// 2026-09-30
// 120

For a project, declare libraries in zolo.toml:

[packages]
schema = 2

[foreign]
install = "manual"

[foreign.python.dependencies]
numpy = "2.3.3"

[foreign.node.dependencies]
"date-fns" = "4.1.0"

[foreign.dotnet.dependencies]
"MathNet.Numerics" = "5.0.0"

Run zolo install, then zolo run. Functions using the same provider receive one isolated environment. A project's zolo.lock includes Zolo packages and foreign dependency graphs. Identical source/manifest declarations merge; conflicting requirements report both locations.

Short strings always mean exact versions. npm pins require a complete version such as 4.1.0; use requirement for partial 4 or 4.1 ranges. Use the detailed form for native ranges or Python extras, in the source block or manifest:

extern python deps {
    numpy = { requirement = ">=2.2,<3" }
    httpx = { version = "0.28.1", extras = ["http2"] }
}

requirement follows that ecosystem's rules. The lock records resolved versions and subsequent runs reuse them.

zolo install analysis.zolo
zolo add python:[email protected]
zolo add node:[email protected]
zolo add dotnet:[email protected]
zolo run analysis.zolo --offline --frozen

Standalone scripts default to auto; projects default to manual. Set [foreign] install = "auto" or pass --install=auto to prepare missing packages when running. --offline permits only local caches; --frozen requires a matching lock and prevents changes. Arguments after -- belong to your program.

The editor reads prepared environments and offers an explicit install action. Opening a file neither downloads packages nor executes its imports. This first version supports Python wheels, npm packages with install scripts disabled and NuGet assets for the selected framework/platform, and Maven JARs for Java. Provider plugins and language runtimes are acquired separately. See Java with extern for Maven coordinates, Java version selection and the global [foreign.jvm.dependencies] table.

Global index

Find your way through Zolo

Try an idea

Start here

9 results

9 results

enpt-br