Skip to content

refactor(shim): implement lite provider interface #74

@CalvinAllen

Description

@CalvinAllen

Refactor the shim to use a lightweight provider interface that excludes heavy dependencies.

Problem

The shim imports full runtime providers which pull in dependencies not needed at runtime:

  • net/http (~2MB) - used only by ListAvailable()
  • download package - used only by Install()
  • progressbar/v3 (~500KB) - used by download
  • Detection code for nvm/pyenv/fnm - used only by DetectInstalled()

Shim's Actual Needs

The shim only uses these provider methods:

type ShimProvider interface {
    Name() string
    DisplayName() string
    Shims() []string
    ExecutablePath(version string) (string, error)
    IsInstalled(version string) (bool, error)
    ShouldReshimAfter(shimName string, args []string) bool
}

It does not need:

  • Install() / Uninstall()
  • ListAvailable() / ListInstalled()
  • DetectInstalled()
  • GlobalPackages() / InstallGlobalPackages()

Proposed Solutions

Option A: Build Tags

Use //go:build !shim to exclude heavy methods from shim builds:

//go:build !shim

func (p *Provider) ListAvailable() ([]runtime.AvailableVersion, error) {
    // HTTP code here
}

Pros: Minimal code changes, single provider file
Cons: Build complexity, easy to forget tags

Option B: Interface Split

Create separate ShimProvider and FullProvider interfaces:

src/internal/runtime/
├── provider.go      # Full interface
└── shim_provider.go # Lite interface for shim

src/runtimes/node/
├── provider.go      # Core methods (both interfaces)
├── install.go       # Install/download (full only)
└── detect.go        # Detection code (full only)

Pros: Clean separation, explicit dependencies
Cons: More files, some duplication

Option C: Lazy Loading

Only import heavy packages when methods are called (using plugin or reflection).

Pros: No build changes
Cons: Complex, runtime overhead, not idiomatic Go

Expected Impact

  • Shim binary size: ~7.2MB → ~3-4MB (after symbol stripping)
  • Removes net/http initialization overhead
  • Faster cold starts

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions