Declaring dependencies
nuget { dependencies { ... } } declares which NuGet packages your Kotlin/Native library resolves, and, for the ones you actually want to call from Kotlin, which of their namespaces get bound into Kotlin stubs.
Resolve versus bind
Declaring a dependency always resolves it, transitively, through dotnet restore, the same way any <PackageReference> would. Resolving does not generate any Kotlin bindings. A NuGet package commonly pulls in ten or more transitive packages; generating stubs for all of them by default would produce an overwhelming API surface for a library you only wanted one method from.
Binding is opt-in: only a dependency() block that contains a nested bind { } block gets Kotlin stubs, and only the namespaces you include() inside that block get bound (ADR-044). Everything else in the transitive closure is resolved (so it links and restores correctly) but never turns into Kotlin code.
The DSL
The model classes live in nuget-plugin/src/main/kotlin/io/github/xxfast/kotlin/native/nuget/: NugetDependency.kt, NugetDependencyScope.kt, and NugetBindConfig.kt.
Property / function | Where | Meaning |
|---|---|---|
|
| The package version to restore. |
|
| A custom NuGet feed URL for this package. |
|
| Presence opts the package into Kotlin binding generation; absence means resolve-only. |
|
| The Kotlin package the bound namespaces land in. |
|
| Namespace whitelist. Empty means every public namespace in the package is a candidate. |
|
| Namespace blacklist, applied after |
|
| Overrides |
Real examples
Both of these are taken verbatim from test-library/build.gradle.kts.
A static-methods-only package, bound under an explicit packageName:
Every public type in the MimeMapping namespace becomes Kotlin under the mimemapping package, which is how MimeUtility.getMimeMapping(...) in Static classes and methods ends up importable as mimemapping.MimeUtility.
A package bound with a per-namespace alias() instead of a package-wide name:
Here no packageName is set at all; alias() maps the single included namespace Test.Text directly onto the Kotlin package sample.text, which is where the Template wrapper used throughout Objects and handles and Instance members is generated.
Namespace filtering semantics
If
include()is never called, every public namespace in the package is a candidate.If
include()is called one or more times, only those namespaces (and their sub-namespaces) are candidates.exclude()is applied afterinclude()and can only remove candidates, never add them back.alias()overridespackageNamefor one namespace; namespaces without a matchingalias()fall back topackageName, or to the derived default ifpackageNameis also unset.
These filters are forwarded to the NugetMetadataReader subprocess as --include/--exclude CLI arguments, so a namespace you never included never even reaches reverse-ir.json, let alone the generators.
Limitations
Only one
bind { }block perdependency()is supported; binding the same package under two differentpackageNamevalues needs a workaround today.sourceis per-dependency only; there's no extension-level shared feed list yet.There's no local
.nupkgor path-based dependency source yet, only registry resolution.
See ROADMAP.md Phase 8 for the current state of these.