Migration Guide

Cross-Platform Migration Guide

This guide documents the comprehensive cross-platform implementation added to Lokus, including breaking changes, migration steps, and best practices for maintaining cross-platform compatibility.

Overview of Cross-Platform Implementation

What Changed

The cross-platform implementation (introduced in v1.0.3) transformed Lokus from a macOS-focused application into a professional cross-platform desktop application. Key changes include:

  • Complete platform abstraction layer with trait-based implementations
  • Platform-specific build systems and configuration files
  • Multi-platform CI/CD pipeline with automated testing
  • Native installer generation for all supported platforms
  • Unified error handling and feature detection system
  • Frontend platform utilities for UI adaptations

Supported Platforms

PlatformStatusInstaller TypesArchitecture Support
Windows✅ StableMSI, Portablex64, ARM64
macOS✅ StableDMG, Universalx64, Apple Silicon
Linux✅ StableAppImage, DEB, RPMx64, ARM64

Breaking Changes

Configuration File Changes

Before (v1.0.2 and earlier):

// Single tauri.conf.json
{
  "build": {
    "targets": "all"
  },
  "bundle": {
    "targets": ["app"]
  }
}

After (v1.0.3+):

// Platform-specific configurations
// tauri.conf.json (base)
// tauri.windows.conf.json (Windows-specific)
// tauri.macos.conf.json (macOS-specific)

Migration Required:

  • Update build scripts to use platform-specific configurations
  • Modify CI/CD workflows to handle multiple config files
  • Update development commands to use appropriate config

Build Command Changes

Before:

npm run tauri dev
npm run tauri build

After:

# Platform-specific development
npm run dev:windows
npm run dev:macos
npm run dev:linux
 
# Platform-specific builds  
npm run build:windows
npm run build:macos
npm run build:linux

Migration Steps:

  1. Update package.json scripts
  2. Modify development workflows
  3. Update documentation and README files

API Changes

New Platform Utilities

Frontend Changes:

// NEW: Platform detection utilities
import { 
  getCurrentPlatform, 
  isWindows, 
  isMacOS, 
  isLinux,
  platformSwitch 
} from '@/utils/platform';
 
// Example usage
const shortcuts = platformSwitch({
  windows: () => ({ save: 'Ctrl+S' }),
  macos: () => ({ save: '⌘+S' }),
  linux: () => ({ save: 'Ctrl+S' }),
  default: () => ({ save: 'Ctrl+S' })
});

Backend Changes:

// NEW: Platform abstraction layer
use crate::platform::{get_platform_provider, PlatformFeature};
 
let provider = get_platform_provider();
if provider.supports_feature(PlatformFeature::QuickLook) {
    // macOS-specific functionality
}

Deprecated APIs

The following APIs were deprecated and replaced:

// DEPRECATED
window.__TAURI__.shell.open(path);
 
// NEW: Platform-aware file operations
import { revealInFileManager } from '@/utils/platform';
await revealInFileManager(path);

File Structure Changes

New Files Added:

src/
├── utils/platform.js          # NEW: Frontend platform utilities
scripts/
├── build-windows.js           # NEW: Windows build script
├── build-macos.js             # NEW: macOS build script  
├── build-linux.js             # NEW: Linux build script
└── check-platform.js          # NEW: Platform validation
src-tauri/
├── tauri.windows.conf.json    # NEW: Windows configuration
├── tauri.macos.conf.json      # NEW: macOS configuration
└── src/platform/              # NEW: Platform abstraction layer
    ├── mod.rs
    ├── windows.rs
    ├── macos.rs
    ├── linux.rs
    ├── errors.rs
    └── clipboard.rs

Migration Steps

For Existing Installations

User Data Migration

User data and settings are automatically migrated between versions. However, for cross-platform usage:

Windows:

# Settings location
%APPDATA%\Lokus\
 
# Documents default
%USERPROFILE%\Documents\Lokus\

macOS:

# Settings location
~/Library/Application Support/Lokus/
 
# Documents default
~/Documents/Lokus/

Linux:

# Settings location
~/.config/lokus/
 
# Documents default  
~/Documents/Lokus/

Manual Migration Steps

  1. Export Settings (if migrating between platforms):

    // In Lokus v1.0.2
    File > Export > Settings
  2. Copy Documents:

    • Copy your workspace directory to the new platform
    • Maintain the same relative structure
  3. Import Settings (on new platform):

    // In Lokus v1.0.3+
    File > Import > Settings

For Developers

Update Development Environment

  1. Install Platform-Specific Dependencies:

    Windows:

    winget install Microsoft.VisualStudio.2022.BuildTools
    winget install Microsoft.EdgeWebView2

    macOS:

    xcode-select --install

    Linux:

    sudo apt install libgtk-3-dev libwebkit2gtk-4.1-dev
  2. Update Build Scripts:

    {
      "scripts": {
        "dev": "npm run dev:${npm_config_platform:-$(node -p 'process.platform')}",
        "build": "npm run build:${npm_config_platform:-$(node -p 'process.platform')}"
      }
    }
  3. Update CI/CD Workflows:

    # .github/workflows/test.yml
    strategy:
      matrix:
        os: [ubuntu-latest, windows-latest, macos-latest]

Code Migration

Platform-Specific Code:

// BEFORE: Platform detection in components
const isMac = navigator.platform.includes('Mac');
 
// AFTER: Use platform utilities
import { isMacOS } from '@/utils/platform';
const isMac = isMacOS();

Conditional Rendering:

// BEFORE: Manual platform checks
{navigator.platform.includes('Mac') && <MacOnlyComponent />}
 
// AFTER: Platform-aware rendering
import { platformSwitch } from '@/utils/platform';
 
const PlatformSpecificComponent = platformSwitch({
  macos: () => <MacComponent />,
  windows: () => <WindowsComponent />,
  linux: () => <LinuxComponent />,
  default: () => <DefaultComponent />
});

File Operations:

// BEFORE: Direct Tauri calls
import { open } from '@tauri-apps/api/shell';
await open(filePath);
 
// AFTER: Platform-aware operations
import { revealInFileManager } from '@/utils/platform';
await revealInFileManager(filePath);

For Plugin Developers

Plugin Compatibility

Existing plugins require minimal changes but should be updated for better cross-platform support:

Plugin Manifest Updates:

{
  "name": "my-plugin",
  "version": "1.0.0",
  "platforms": ["windows", "macos", "linux"],
  "requirements": {
    "lokus": ">=1.0.3"
  }
}

Platform-Specific Plugin Code:

// Plugin with platform adaptations
import { getCurrentPlatform, PLATFORMS } from '@lokus/platform-utils';
 
class MyPlugin {
  init() {
    const platform = getCurrentPlatform();
    
    if (platform === PLATFORMS.WINDOWS) {
      this.initWindowsFeatures();
    } else if (platform === PLATFORMS.MACOS) {
      this.initMacOSFeatures();
    } else if (platform === PLATFORMS.LINUX) {
      this.initLinuxFeatures();
    }
  }
}

Best Practices for Cross-Platform Development

Code Organization

1. Platform Detection

// Always use the official platform utilities
import { getCurrentPlatform, isWindows, isMacOS, isLinux } from '@/utils/platform';
 
// Avoid direct navigator checks
// DON'T: navigator.platform.includes('Win')
// DO: isWindows()

2. Feature Detection

// Check for platform-specific features
import { isPlatformFeatureAvailable } from '@/utils/platform';
 
if (isPlatformFeatureAvailable('touchBar')) {
  // Initialize Touch Bar features
}

3. Conditional Logic

// Use platformSwitch for cleaner conditional logic
import { platformSwitch } from '@/utils/platform';
 
const config = platformSwitch({
  windows: () => ({ modifier: 'Ctrl' }),
  macos: () => ({ modifier: 'Cmd' }),
  linux: () => ({ modifier: 'Ctrl' }),
  default: () => ({ modifier: 'Ctrl' })
});

UI/UX Considerations

1. Platform-Appropriate Controls

import { getPlatformUIPreferences } from '@/utils/platform';
 
const UIComponent = () => {
  const { windowControlsPosition } = getPlatformUIPreferences();
  
  return (
    <div className={`window-controls-${windowControlsPosition}`}>
      {/* Platform-appropriate window controls */}
    </div>
  );
};

2. Keyboard Shortcuts

import { createShortcut } from '@/utils/platform';
 
const shortcuts = {
  save: createShortcut('S', { primary: true }),     // Ctrl+S or ⌘+S
  copy: createShortcut('C', { primary: true }),     // Ctrl+C or ⌘+C
  paste: createShortcut('V', { primary: true })     // Ctrl+V or ⌘+V
};

3. File Paths

import { normalizePath, joinPath } from '@/utils/platform';
 
// Always normalize paths for display
const displayPath = normalizePath(rawPath);
 
// Use joinPath for path construction
const fullPath = joinPath(basePath, 'subfolder', 'file.txt');

Testing Strategies

1. Cross-Platform Testing

// Use platform mocking in tests
import { setPlatformForTesting } from '@/utils/platform';
 
describe('Cross-platform feature', () => {
  test('works on Windows', () => {
    setPlatformForTesting('windows');
    // Test Windows-specific behavior
  });
  
  test('works on macOS', () => {
    setPlatformForTesting('macos');
    // Test macOS-specific behavior
  });
});

2. Feature Detection Testing

import { mockPlatformFeature } from '@/test-utils/platform';
 
test('handles missing platform features', () => {
  mockPlatformFeature('touchBar', false);
  
  // Test graceful degradation
  const component = render(<MyComponent />);
  expect(component.queryByTestId('touch-bar')).toBeNull();
});

Performance Considerations

Platform-Specific Optimizations

1. Bundle Optimization

// vite.config.js - Platform-specific builds
export default {
  build: {
    rollupOptions: {
      external: (id) => {
        // Exclude platform-specific modules for other platforms
        if (process.env.TARGET_PLATFORM === 'windows' && id.includes('macos')) {
          return true;
        }
        return false;
      }
    }
  }
};

2. Lazy Loading

// Load platform-specific code only when needed
const loadPlatformModule = async () => {
  const platform = getCurrentPlatform();
  
  switch (platform) {
    case 'windows':
      return import('./platform/windows');
    case 'macos':
      return import('./platform/macos');
    case 'linux':
      return import('./platform/linux');
    default:
      return import('./platform/default');
  }
};

Memory Management

1. Platform Resource Cleanup

// Ensure platform-specific resources are cleaned up
class PlatformManager {
  constructor() {
    this.platform = getCurrentPlatform();
    this.resources = new Set();
  }
  
  async cleanup() {
    for (const resource of this.resources) {
      await resource.cleanup();
    }
    this.resources.clear();
  }
}

Troubleshooting Migration Issues

Common Migration Problems

1. Build Failures

# Problem: "Configuration not found"
Error: Could not find tauri.windows.conf.json
 
# Solution: Update build commands
npm run build:windows  # Instead of npm run tauri build

2. Platform Detection Issues

// Problem: Incorrect platform detection
// Solution: Clear platform cache
import { clearPlatformCache } from '@/utils/platform';
clearPlatformCache();

3. File Path Issues

// Problem: Windows path separators on other platforms
// Solution: Always normalize paths
import { normalizePath } from '@/utils/platform';
const safePath = normalizePath(userProvidedPath);

Version Compatibility

Check Lokus Version:

import { checkLokusVersion } from '@lokus/core';
 
const isCompatible = checkLokusVersion('>=1.0.3');
if (!isCompatible) {
  throw new Error('This feature requires Lokus v1.0.3 or later');
}

Feature Availability:

import { isPlatformFeatureAvailable } from '@/utils/platform';
 
const features = [
  'fileManagerReveal',
  'terminalLaunch', 
  'nativeNotifications'
];
 
const availableFeatures = features.filter(isPlatformFeatureAvailable);
console.log('Available features:', availableFeatures);

Getting Help

Migration Support

Community Resources:

Documentation:

Professional Support:

  • Enterprise migration assistance available
  • Custom platform integration consulting
  • Training and workshops for development teams

This migration guide is updated regularly as new cross-platform features are added. For the latest information, check the changelog and GitHub releases (opens in a new tab).