Skip to main content

Package Dependencies And Imports

Morph packages do not live alone.

They compose through explicit imports and package-level dependencies.


Why Imports Matter

Imports define what a package expects from the rest of the Morph graph.

That includes things such as:

  • providers
  • runtime families
  • execution engines
  • build pipelines
  • package-owned capabilities exported by other packages

Without explicit imports, ownership becomes hidden and feature wiring drifts back into core shortcuts.


Package-Level Imports

morph.toml can declare imports such as provider dependencies:

[import.host_provider]
kind = "provider"
id = "provider.core.host_llvm"

This means the package depends on a provider that another package exports.


Real Examples

Current packages already do this:

PackageExample Import
Coreimports host, GPU, and shader providers
Tensorimports host and GPU providers
Threadingimports host provider metadata

The package graph then resolves those imports through enabled packages.


What Not To Do

Do not encode dependencies as hidden assumptions in source files.

Examples of bad ownership:

  • assuming a provider exists without declaring it
  • hardcoding a package dependency in core code
  • treating a runtime family as globally available without a declared relationship

Dependencies should be visible in package space.


Imports vs Feature References

Think of imports as package-level requirements.

Think of feature manifests as feature-level ownership declarations.

You usually need both:

  • morph.toml declares package relationships
  • feature.toml declares feature behavior that uses those relationships

Dependency Design Rule

If a package needs another package's capability:

  1. declare that dependency explicitly
  2. keep the consuming logic in the package
  3. widen framework descriptors only if the relationship cannot be expressed yet

Do not route around package dependencies through Core.


Next Steps