Skip to content

Cross-platform Compatibility ​

Launchpad is designed to work seamlessly across different operating systems. This guide explains how Launchpad handles platform-specific nuances and how to optimize your usage for cross-platform scenarios.

Platform Detection ​

Launchpad automatically detects the operating system it's running on and adjusts its behavior accordingly:

typescript
// Example of how Launchpad detects platforms internally
import { platform } from 'node:os'

const isWindows = platform() === 'win32'
const isMacOS = platform() === 'darwin'
const isLinux = platform() === 'linux'

Installation Philosophy Across Platforms ​

Launchpad follows the pkgm approach consistently across all platforms:

Unix-like Systems (macOS, Linux) ​

  • Primary: /usr/local for system-wide installations
  • Fallback: ~/.local for user-specific installations
  • Never uses: /opt/homebrew (Homebrew's directory)
  • Maintains: Clean separation from package managers like Homebrew

Windows ​

  • Primary: %LOCALAPPDATA% for user-specific installations
  • Alternative: %PROGRAMFILES% for system-wide (requires elevation)
  • Avoids: Conflicting with Windows package managers

This consistent approach ensures clean coexistence with existing package managers on all platforms.

Path Handling ​

Windows Path Differences ​

On Windows, paths use backslashes (\) rather than forward slashes (/). Launchpad normalizes paths internally:

typescript
// Example of path normalization
import path from 'node:path'

const normalizedPath = path.normalize('/usr/local/bin')
// On Windows, this becomes something like 'C:\usr\local\bin'

Home Directory Resolution ​

Launchpad resolves the ~ symbol to the user's home directory across all platforms:

typescript
// Launchpad's internal approach
const homePath = process.env.HOME || process.env.USERPROFILE || '~'

Shell Integration ​

Each platform uses different shells by default:

  • Windows: PowerShell or CMD
  • macOS: Zsh (newer versions) or Bash (older versions)
  • Linux: Bash, Zsh, or others

Launchpad adapts its PATH modification strategies accordingly.

Shell Message Customization by Platform ​

You can customize shell messages differently on each platform:

bash
# macOS/Linux - Using ~/.zshrc or ~/.bashrc
export LAUNCHPAD_SHELL_ACTIVATION_MESSAGE="🍎 macOS environment ready: {path}"
export LAUNCHPAD_SHELL_DEACTIVATION_MESSAGE="🍎 macOS environment closed"
powershell
# Windows - Using PowerShell profile
$env:LAUNCHPAD_SHELL_ACTIVATION_MESSAGE = "🪟 Windows environment ready: {path}"
$env:LAUNCHPAD_SHELL_DEACTIVATION_MESSAGE = "🪟 Windows environment closed"

File System Permissions ​

Permission handling differs by platform:

  • Unix-like Systems (macOS, Linux): Uses Unix permissions (rwx)
  • Windows: Uses ACLs (Access Control Lists)

When creating shims, Launchpad sets the appropriate permissions:

typescript
// On Unix-like systems
fs.chmodSync(shimPath, 0o755) // Makes file executable

// On Windows
// No explicit chmod needed; Windows handles differently

Sudo Handling ​

Elevated privileges are required for certain operations, and the approach varies by platform:

  • Unix-like Systems: Uses sudo
  • Windows: Requires running as Administrator

Launchpad's auto-sudo feature automatically adapts to the platform.

Platform-specific Example: PATH Management ​

macOS/Linux ​

bash
# Add to PATH on Unix-like systems
echo 'export PATH="~/.local/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc

# Custom shell messages
echo 'export LAUNCHPAD_SHELL_ACTIVATION_MESSAGE="🔧 Dev environment: {path}"' >> ~/.zshrc

Windows (PowerShell) ​

powershell
# Add to PATH on Windows
$currentPath = [Environment]::GetEnvironmentVariable("PATH", "User")
$newPath = "$env:USERPROFILE\.local\bin;" + $currentPath
[Environment]::SetEnvironmentVariable("PATH", $newPath, "User")

# Custom shell messages
[Environment]::SetEnvironmentVariable("LAUNCHPAD_SHELL_ACTIVATION_MESSAGE", "🔧 Dev environment: {path}", "User")

Executable Detection ​

Different platforms use different file extensions for executables:

  • Unix-like Systems: No extension required (permissions matter)
  • Windows: .exe, .bat, .cmd, etc.

Launchpad handles these differences when creating and detecting executables.

Platform-specific Installation Paths ​

Default installation paths vary by platform but follow consistent principles:

macOS ​

  • System-wide: /usr/local (preferred, like pkgm)
  • User-specific: ~/.local (fallback)
  • Never uses: /opt/homebrew (Homebrew's directory)

Linux ​

  • System-wide: /usr/local (preferred, like pkgm)
  • User-specific: ~/.local (fallback)
  • Respects: Existing system package manager directories

Windows ​

  • User-specific: %LOCALAPPDATA%\Programs\Launchpad (preferred)
  • System-wide: %PROGRAMFILES%\Launchpad (requires elevation)

NOTE

Launchpad installs packages to /usr/local (like pkgm), not to Homebrew's /opt/homebrew directory. This ensures clean separation from Homebrew-managed packages and allows peaceful coexistence.

Integration with pkgx ​

pkgx itself is cross-platform, and Launchpad leverages this to provide a consistent experience across operating systems.

Testing Across Platforms ​

When developing with Launchpad, it's good practice to test on multiple platforms:

bash
# Basic testing on Unix-like systems
launchpad install node@22
node --version

# Verify shim creation
ls -la ~/.local/bin/node

# Test environment messages
cd my-project/  # Should show activation message
cd ../          # Should show deactivation message
powershell
# Basic testing on Windows
launchpad install node@22
node --version

# Verify shim creation
dir $env:USERPROFILE\.local\bin\node.exe

# Test environment messages
cd my-project  # Should show activation message
cd ..\         # Should show deactivation message

Cross-platform CI/CD Integration ​

For CI/CD pipelines, you can use Launchpad consistently across platforms:

yaml
# Example GitHub Actions workflow
jobs:
  build:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
    runs-on: ${{ matrix.os }}
    steps:
      - uses: actions/checkout@v4
      - name: Install Launchpad
        run: npm install -g @stacksjs/launchpad
      - name: Install dependencies with Launchpad
        run: launchpad install node@22 python@3.12
      - name: Test environment activation
        run: |
          cd test-project
          # Environment should activate automatically with shell integration

Platform-specific Configuration ​

macOS Configuration ​

typescript
// launchpad.config.ts for macOS
export default {
  installationPath: '/usr/local', // Preferred on macOS
  shellActivationMessage: '🍎 macOS environment ready: {path}',
  shellDeactivationMessage: '🍎 Environment closed',
  // Use Homebrew paths for fallback when needed
  fallbackPaths: ['/opt/homebrew/bin', '/usr/local/bin']
}

Linux Configuration ​

typescript
// launchpad.config.ts for Linux
export default {
  installationPath: '/usr/local', // Preferred on Linux
  shellActivationMessage: '🐧 Linux environment ready: {path}',
  shellDeactivationMessage: '🐧 Environment closed',
  // Respect system package manager paths
  fallbackPaths: ['/usr/bin', '/usr/local/bin']
}

Windows Configuration ​

typescript
// launchpad.config.ts for Windows
export default {
  installationPath: `${process.env.LOCALAPPDATA}\\Programs\\Launchpad`,
  shellActivationMessage: '🪟 Windows environment ready: {path}',
  shellDeactivationMessage: '🪟 Environment closed',
  // Windows-specific paths
  fallbackPaths: ['C:\\Program Files\\Git\\bin']
}

Troubleshooting Cross-platform Issues ​

Path Separator Issues ​

bash
# Use path.join() for cross-platform compatibility
const installPath = path.join(baseDir, 'bin', 'executable')

Environment Variable Differences ​

bash
# Unix-like systems
export LAUNCHPAD_PATH=/usr/local

# Windows
set LAUNCHPAD_PATH=C:\usr\local
# or in PowerShell
$env:LAUNCHPAD_PATH = "C:\usr\local"

Shell Integration Differences ​

bash
# For Bash/Zsh (Unix-like)
echo 'eval "$(launchpad dev:shellcode)"' >> ~/.zshrc

# For PowerShell (Windows)
Add-Content $PROFILE 'Invoke-Expression (& launchpad dev:shellcode)'

Released under the MIT License.