This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
DataWeave CLI packages the MuleSoft DataWeave runtime as a GraalVM native image so DataWeave scripts run without a JVM. It ships two consumer surfaces from the same runtime:
dw— a native command-line executable (native-cli)dwlib— a native shared library with a C-compatible FFI, consumed by Python and Node.js bindings (native-lib)
The DataWeave language/runtime itself lives in a separate repo (org.mule.weave:* artifacts, version pinned in gradle.properties). This repo is the packaging + CLI layer on top of it.
native-cli— thedwexecutable. Java entrypoint (org.mule.weave.cli.DWCLI) using picocli for arg parsing; Scala for the actual command logic (org.mule.weave.dwnative.*).NativeRuntimewrapsDataWeaveScriptingEngineand is the heart of script execution.native-lib— thedwlibshared library. Java@CEntryPointmethods inorg.mule.weave.lib.NativeLibexposerun_script, streaming, and callback APIs to non-JVM callers. Containspython/andnode/binding packages.native-cli-integration-tests— runs the DataWeave TCK / weave test suites against the compiled native binary (not the JVM). Depends onnative-cli:nativeCompile.
Requires GraalVM (Java 24, graalvm-community) with native-image. Set GRAALVM_HOME and JAVA_HOME to it. ./install-graalvm.sh downloads a distribution into .graalvm/ and exports the vars (note: the script's pinned layout may lag graalvmVersion in gradle.properties — verify the path).
# Build the dw native executable (~several minutes) → native-cli/build/native/nativeCompile/dw
./gradlew native-cli:nativeCompile
# Build the shared library → native-lib/build/native/nativeCompile/dwlib.{dylib,so,dll}
./gradlew native-lib:nativeCompile
# Full build (compiles both native images + runs unit tests)
./gradlew build -PskipNodeTests=true
# Packaged OS-specific zip distribution of dw
./gradlew native-cli:distronative-lib native builds use -J-Xmx6G; ensure enough memory.
# Scala unit tests (JVM, fast) — CLI behavior
./gradlew native-cli:test
# native-lib Java tests + Python + Node bindings (Node/Python spawn subprocesses)
./gradlew native-lib:test
./gradlew native-lib:pythonTest
./gradlew native-lib:nodeTest
# Integration tests — run the DataWeave TCK against the compiled dw binary.
# Downloads test-suite zips for the given weave version, then requires native-cli:nativeCompile.
./gradlew -PweaveTestSuiteVersion=2.10.0 -DweaveSuiteVersion=2.10.0 native-cli-integration-tests:testSkip flags for CI/local: -PskipNodeTests=true, -PskipPythonTests=true, -PskipStripDebug=true (keep debug symbols in dwlib).
Scala tests use scalatest (AnyFreeSpec / Matchers). Run a single test with the standard scalatest test filter:
./gradlew native-cli:test --tests "org.mule.weave.dwnative.cli.DataWeaveCLITest"Weave runtime and test-suite versions are pinned in gradle.properties (weaveVersion, weaveTestSuiteVersion, ioVersion, weaveSuiteVersion). At build time native-cli's genVersions task generates org.mule.weave.v2.version.ComponentVersion (Scala) from these into build/genresource/ — don't edit it by hand. nativeVersion (100.100.100) is the CLI/lib artifact version.
The GraalVM buildArgs in each build.gradle are load-bearing. When adding dependencies that use reflection, threads at startup, or resource loading, you'll likely need to touch these:
--initialize-at-run-time=...(netty, coursier,scala.util.Random, the SPI module loader) — classes that must NOT be initialized during image build.- Data formats and module loaders are registered via SPI (
META-INF/services/org.mule.weave.v2.module.DataFormatand...parser.phase.ModuleLoader).native-libre-materializes these service files duringnativeCompileClasspathJar(see theconfigureEachblock) because the fat-jar merge drops them. A missing/unregistered format shows up as a runtime "unknown mime type" rather than a build error.
dwlib is staged into the binding packages by Gradle, not committed built:
stagePythonNativeLib/stageNodeNativeLibcopydwlib.*intopython/src/dataweave/native/andnode/native/.buildPythonWheel(setup.pybdist_wheel) andbuildNodePackage(npm install → node-gyp rebuild → tsc → npm pack) produce distributables.- Bindings locate the library via
DATAWEAVE_NATIVE_LIB=/abs/path/to/dwlib.*, then fall back to the packaged/dev-build locations.
See native-lib/README.md for the full binding API (sync run, run_streaming, run_transform, callback streaming, error types).
- Spells — shareable, runnable DataWeave scripts fetched from git-based "grimoire" repos (
dw spell,spell create/list/update). A grimoire is named<wizard>-data-weave-grimoire; the built-in DW grimoire has no prefix. - Wizards — trusted sources of grimoires (
dw wizard add). - Dependency manager — a spell's
dependencies.dwldeclares maven deps resolved via coursier (DependencyManager/MavenDependencyManager). - Env vars:
DW_HOME(default~/.dw),DW_DEFAULT_INPUT_MIMETYPE,DW_DEFAULT_OUTPUT_MIMETYPE(both defaultapplication/json).
.github/workflows/main.yml (push/PR to master) and ci.yml (weekly) build both native images and all bindings on Ubuntu + Windows. Integration/regression tests (native-cli-integration-tests against multiple weave suite versions) run only on master, not on PRs, to save CI time.