v2
CLI Documentation
Architecture
Recipe Book Resolver

Recipe Book Resolver

The Recipe Book Resolver determines where modules should be placed (target package or target apps) based on recipe books and user overrides.

Overview

The Recipe Book Resolver resolves targetPackage and targetApps for modules using this priority order:

  1. User override (genome.moduleOverrides) - HIGHEST
  2. Genome module definition (genome.modules[].targetPackage)
  3. Recipe book (recipeModule.targetPackage) - PRIMARY SOURCE
  4. Recipe book package structure (packageStructure.directory)
  5. Generic fallback

Resolution Priority

Priority 1: User Override

// User can override in genome
genome.moduleOverrides = {
  'capabilities/auth': {
    targetPackage: 'custom-auth'
  }
}

Use Case: User wants to place a module in a different package than recipe book suggests.

Priority 2: Genome Module Definition

// Module already has targetPackage defined
module.targetPackage = 'auth'

Use Case: Module was already resolved and has target package.

Priority 3: Recipe Book (Primary Source)

{
  "packages": {
    "auth": {
      "providers": {
        "default": {
          "modules": [
            {
              "id": "capabilities/auth",
              "targetPackage": "auth"
            }
          ]
        }
      }
    }
  }
}

Use Case: Standard case - recipe book defines where module goes.

Priority 4: Package Structure

{
  "packages": {
    "auth": {
      "packageStructure": {
        "directory": "packages/auth"
      }
    }
  }
}

Use Case: Fallback if recipe module doesn't have targetPackage.

Priority 5: Generic Fallback

If none of the above, use module ID to infer package name:

// capabilities/auth → auth
const inferredPackage = module.id.split('/').pop();

Framework Module Detection

Framework modules are detected using metadata:

const isFramework = 
  moduleMetadata?.type === 'framework' ||
  moduleMetadata?.category === 'framework' ||
  moduleMetadata?.category === 'foundation';

Framework modules:

  • Have targetApps (not targetPackage)
  • Execute during bootstrap
  • Filtered from regular execution

Target Resolution

Package Modules

{
  targetPackage: 'auth',      // Package name
  targetApps: undefined,      // Not app-specific
  source: 'recipe_book'
}

Result: Module generates in packages/auth/

App Modules (Frameworks)

{
  targetPackage: null,        // Not a package
  targetApps: ['web'],        // App-specific
  source: 'recipe_book'
}

Result: Module generates in apps/web/

Example

Recipe Book

{
  "packages": {
    "auth": {
      "providers": {
        "default": {
          "modules": [
            {
              "id": "capabilities/auth",
              "targetPackage": "auth"
            }
          ]
        }
      }
    },
    "nextjs": {
      "providers": {
        "default": {
          "modules": [
            {
              "id": "capabilities/nextjs",
              "targetPackage": null,
              "targetApps": ["web"]
            }
          ]
        }
      }
    }
  }
}

Resolution

// Module: capabilities/auth
resolveTargetPackage(module) → {
  targetPackage: 'auth',
  source: 'recipe_book'
}
 
// Module: capabilities/nextjs
resolveTargetPackage(module) → {
  targetPackage: null,
  targetApps: ['web'],
  source: 'recipe_book'
}

Framework Compatibility

Recipe books can specify framework requirements:

{
  "modules": [
    {
      "id": "capabilities/nextjs-middleware",
      "requiredFramework": "nextjs",
      "requiredAppTypes": ["web"]
    }
  ]
}

Result: Module only resolves if app uses nextjs framework and is web type.

Related