Dependency Resolution
Rack automatically resolves dependencies between registries, ensuring all required modules are correctly installed.
Dependency Declaration
Registries declare dependencies using the registryDependencies field.
{
"name": "vue-router",
"type": "registry:feature",
"registryDependencies": ["frameworks/vue"]
}This indicates that vue-router requires vue to function properly.
Dependency Resolution Process
When you run rk add features/vue-router, Rack executes the following steps.
1. Download Registry JSON
Download registry.json for features/vue-router2. Recursively Resolve Dependencies
Discover vue-router depends on frameworks/vue
→ Download registry.json for frameworks/vue
→ Discover vue depends on runtimes/node
→ Download registry.json for runtimes/node
→ node has no dependencies, resolution completefeatures/vue-router
└── frameworks/vue
└── runtimes/node3. Build Dependency Graph
Use topological sorting algorithm to build installation order.
runtimes/node (no dependencies, first)
↓
frameworks/vue (depends on node)
↓
features/vue-router (depends on vue)4. Detect Circular Dependencies
If circular dependencies are found, Rack throws an error.
CircularDependencyError:
features/A → features/B → features/C → features/AExample
// features/A
{ "registryDependencies": ["features/B"] }
// features/B
{ "registryDependencies": ["features/C"] }
// features/C
{ "registryDependencies": ["features/A"] } // Circular dependency5. Validate Conflicts
Check if registries to be installed conflict with already installed registries.
# Already installed
rk add frameworks/vue
# Attempting to install (will error)
rk add frameworks/reactError message
ConflictError:
frameworks/react conflicts with frameworks/vue6. Version Resolution
When multiple registries depend on the same npm package, Rack resolves version conflicts.
// frameworks/vue
{ "dependencies": { "vue": "^3.4.0" } }
// features/pinia
{ "dependencies": { "vue": "^3.3.0" } }Resolution rules
Same version → Keep that version
vue: "^3.4.0" + vue: "^3.4.0" → "^3.4.0"Compatible versions → Use newer version
vue: "^3.4.0" + vue: "^3.3.0" → "^3.4.0"Incompatible versions → Lower priority number wins
vue: "^3.4.0" (priority: 2) + vue: "^2.7.0" (priority: 4) → "^3.4.0"Why does lower number win?
Registries with lower priority numbers (e.g., framework layer priority: 2) are foundational dependencies, and their version requirements should be prioritized.
Dependencies and Priority
Rack uses dependencies and the priority system together to determine the final installation order.
Core Principle
Dependencies (hard constraints) take precedence over priority numbers (soft constraints).
A depended-upon Registry must be installed first, even if it has a higher priority number.
Sorting Algorithm
Final installation order = Sort by dependency level + Sort by priority number within the same levelRules:
- First calculate the dependency level for each Registry (no dependencies = level 0, depends on level N = level N+1)
- Sort from low to high level (dependencies must be installed first)
- Within the same level, sort by priority number from small to large
Example
Assume the following registries:
{
"items": [
{
"name": "A",
"priority": 1,
"registryDependencies": ["B"] // A depends on B
},
{
"name": "B",
"priority": 4
}
]
}Sorting result: B → A
Analysis:
- B is at level 0 (no dependencies), A is at level 1 (depends on B)
- Although A's priority (1) is less than B's (4), the dependency relationship determines that B must be installed first
- Dependencies (hard constraints) take precedence over priority numbers (soft constraints)
Conflict Declaration
Use the conflicts field to declare incompatible registries; the install pipeline aborts with a descriptive error as soon as one is hit.
{
"name": "vue",
"type": "registry:framework",
"conflicts": ["frameworks/react", "frameworks/svelte"]
}
