Complete Guide to ComfyUI on Mac - Installation, Configuration, and Troubleshooting

Author: Tom Cranstoun
Are you looking to harness the power of AI image generation on your Mac?

ComfyUI might be exactly what you need. Unlike other Stable Diffusion interfaces, ComfyUI offers a node-based approach that gives you unprecedented control over the image generation process. In this comprehensive guide, I'll walk you through setting up ComfyUI on Apple Silicon Macs (M1, M2, M3), from installation to advanced configuration and troubleshooting.

What is ComfyUI?

ComfyUI is an open-source, node-based interface for Stable Diffusion that allows you to create complex AI image generation workflows visually. Think of it as a visual programming environment specifically designed for AI image generation. Instead of typing commands, you connect nodes (components) together to build your desired pipeline.

Key advantages of ComfyUI include:

One-Shot Installation Script

If you prefer a hassle-free installation, you can use this one-shot installer script that handles everything automatically. This script will install Miniconda, set up a Python environment, clone ComfyUI, and download models.

#!/bin/bash
# ComfyUI One-Shot Installer for Mac with Apple Silicon
# This script installs Miniconda, sets up a Python environment,
# downloads ComfyUI, and installs all necessary dependencies and models.
# Set up colors for output
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m' # No Color
# Functions to print colored messages
info() {
  echo -e "${BLUE}[INFO]${NC} $1"
}
success() {
  echo -e "${GREEN}[SUCCESS]${NC} $1"
}
warning() {
  echo -e "${YELLOW}[WARNING]${NC} $1"
}
error() {
  echo -e "${RED}[ERROR]${NC} $1"
}

# Function to check if command exists
command_exists() {
  command -v "$1" >/dev/null 2>&1
}
# Check if running on macOS
if [[ "$(uname)" != "Darwin" ]]; then
  error "This script is intended for macOS only."
  exit 1
fi
# Check if running on Apple Silicon
if [[ "$(uname -m)" != "arm64" ]]; then
  warning "This script is optimized for Apple Silicon Macs (M1/M2/M3). You appear to be using an Intel Mac."
  read -p "Continue anyway? (y/n): " -n 1 -r
  echo
  if [[ ! $REPLY =~ ^[Yy]$ ]]; then
    exit 1
  fi
fi
# Display warning about disk space and download size
echo "=========================================================="
echo "           ComfyUI One-Shot Installer for Mac"
echo "=========================================================="
echo
warning "This script will:"
echo "  1. Install Miniconda if not already installed"
echo "  2. Create a Python environment for ComfyUI"
echo "  3. Clone the ComfyUI repository to ~/Documents/GitHub/ComfyUI"
echo "  4. Install required dependencies"
echo "  5. Download SD models, VAE models, and ControlNet models"
echo
warning "You'll need approximately:"
echo "  - 3GB for Miniconda and the Python environment"
echo "  - 2GB for ComfyUI and dependencies"
echo "  - 10GB+ for models (SD 1.5, SDXL, VAEs, ControlNet models, etc.)"
echo "  - Total: At least 15GB of free disk space"
echo
warning "The download may take a significant amount of time depending on your internet connection."
echo
read -p "Do you want to continue? (y/n): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
  info "Installation cancelled."
  exit 0
fi
# Set up paths - Using the standard GitHub directory
GITHUB_DIR="$HOME/Documents/GitHub"
COMFYUI_DIR="$GITHUB_DIR/ComfyUI"
MINICONDA_DIR="$HOME/miniconda3"
MINICONDA_INSTALLER="/tmp/miniconda.sh"
ENV_NAME="comfyui"
# Create GitHub directory if it doesn't exist
info "Setting up directories..."
mkdir -p "$GITHUB_DIR"
success "GitHub directory ready at $GITHUB_DIR"
# Check for Conda installation
if ! command_exists conda; then
  info "Conda not found. Installing Miniconda..."
 # Download Miniconda installer
  info "Downloading Miniconda installer..."
  curl -L -o "$MINICONDA_INSTALLER" "https://repo.anaconda.com/miniconda/Miniconda3-latest-MacOSX-arm64.sh"
  # Run the installer
  bash "$MINICONDA_INSTALLER" -b -p "$MINICONDA_DIR"
  # Initialize conda
  "$MINICONDA_DIR/bin/conda" init "$(basename "$SHELL")"
  # Make conda available in this script
  source "$MINICONDA_DIR/etc/profile.d/conda.sh"
  success "Miniconda installed."
else
  info "Conda already installed, continuing with existing installation."
  # Make conda available in this script
  if [[ -f "$MINICONDA_DIR/etc/profile.d/conda.sh" ]]; then
    source "$MINICONDA_DIR/etc/profile.d/conda.sh"
  elif [[ -f "$HOME/anaconda3/etc/profile.d/conda.sh" ]]; then
    source "$HOME/anaconda3/etc/profile.d/conda.sh"
  else
    # Try to find conda.sh in other common locations
    CONDA_PATH=$(which conda)
    CONDA_BASE=$(dirname $(dirname "$CONDA_PATH"))
    if [[ -f "$CONDA_BASE/etc/profile.d/conda.sh" ]]; then
      source "$CONDA_BASE/etc/profile.d/conda.sh"
    else
      error "Could not find conda.sh. Please run 'conda init bash' (or your shell) and restart this script."
      exit 1
    fi
  fi
fi

# Check for existing environment and create if needed
info "Checking for existing ComfyUI environment..."
if conda env list | grep -q "^$ENV_NAME "; then
  warning "Environment '$ENV_NAME' already exists."
  read -p "Do you want to recreate it? All packages in this environment will be lost. (y/n): " -n 1 -r
  echo
  if [[ $REPLY =~ ^[Yy]$ ]]; then
    conda env remove -n "$ENV_NAME" -y
    conda create -n "$ENV_NAME" python=3.11 -y
    success "Environment recreated."
  else
    info "Using existing environment."
  fi
else
  info "Creating new environment with Python 3.11..."
  conda create -n "$ENV_NAME" python=3.11 -y
  success "Environment created."
fi
# Activate the environment
info "Activating ComfyUI environment..."
conda activate "$ENV_NAME"
# Check if activation worked
if [[ "$CONDA_DEFAULT_ENV" != "$ENV_NAME" ]]; then
  error "Failed to activate Conda environment. Please run this script again."
  exit 1
fi
# Clone ComfyUI repository
info "Checking for existing ComfyUI installation..."
if [ -d "$COMFYUI_DIR" ]; then
  warning "ComfyUI directory already exists at $COMFYUI_DIR."
  read -p "Do you want to update it? (y/n): " -n 1 -r
  echo
  if [[ $REPLY =~ ^[Yy]$ ]]; then
    cd "$COMFYUI_DIR"
    git pull
    success "ComfyUI updated."
  else
    info "Keeping existing ComfyUI installation."
  fi
else
  info "Cloning ComfyUI repository to $COMFYUI_DIR..."
  git clone https://github.com/comfyanonymous/ComfyUI.git "$COMFYUI_DIR"
  success "ComfyUI cloned."
fi

# Navigate to ComfyUI directory
cd "$COMFYUI_DIR"
# Install PyTorch
info "Installing PyTorch for Apple Silicon..."
pip install --pre torch torchvision torchaudio --index-url https://download.pytorch.org/whl/nightly/cpu
# Install dependencies
info "Installing ComfyUI dependencies..."
pip install -r requirements.txt
pip install safetensors einops
# Create configuration file
info "Setting up configuration file..."
cat > extra_model_paths.yaml << EOL
# ComfyUI extra model paths configuration
# This file helps ComfyUI find and map your models
# Main ComfyUI installation
comfyui:
  base_path: $COMFYUI_DIR/
  is_default: true
  checkpoints: models/checkpoints/
  clip: models/clip/
  clip_vision: models/clip_vision/
  configs: models/configs/
  controlnet: models/controlnet/
  diffusion_models: models/diffusion_models/
  embeddings: models/embeddings/
  loras: models/loras/
  upscale_models: models/upscale_models/
  vae: models/vae/
  vae_approx: models/vae_approx/
# Model aliases to automatically map model filenames
# When ComfyUI looks for a file on the left, it will use the file on the right instead
checkpoint_aliases:
  # SD 1.5 aliases
  v1-5-pruned-emaonly-fp16.safetensors: sd_v1-5.safetensors
  v1-5-pruned-emaonly.safetensors: sd_v1-5.safetensors
  v1-5-pruned.safetensors: sd_v1-5.safetensors
  v1-5.safetensors: sd_v1-5.safetensors
  # SDXL aliases
  sd_xl_base_1.0.safetensors: sdxl_base_1.0.safetensors
  sdxl-base-1.0.safetensors: sdxl_base_1.0.safetensors

  

  # VAE aliases
  vae-ft-mse-840000-ema-pruned.safetensors: sd_vae.safetensors
  sdxl_vae.safetensors: sdxl_vae.safetensors
EOL

success "Configuration file created."
# Create model directories
info "Creating model directories..."
mkdir -p models/checkpoints
mkdir -p models/vae
mkdir -p models/lora
mkdir -p models/controlnet
mkdir -p models/embeddings
mkdir -p models/vae_approx
mkdir -p models/clip
success "Model directories created."

# Ask about downloading models

echo
warning "Model files are large (10GB+). Do you want to download them now?"
echo "1: Download all models (SD 1.5, SDXL, VAEs, preview models, ControlNet) [10GB+]"
echo "2: Download minimal set (SD 1.5, VAE, preview models) [2GB]"
echo "3: Skip model download (you'll need to add models manually later)"
echo

read -p "Enter your choice (1-3): " model_choice
if [[ "$model_choice" == "1" ]]; then
  # Download all models
  info "Downloading all models (this will take some time)..."
  info "Downloading SD 1.5 models..."
  curl -L --progress-bar "https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.safetensors" -o "models/checkpoints/sd_v1-5.safetensors"
  info "Downloading SDXL model..."
  curl -L --progress-bar "https://huggingface.co/stabilityai/stable-diffusion-xl-base-1.0/resolve/main/sd_xl_base_1.0.safetensors" -o "models/checkpoints/sdxl_base_1.0.safetensors"
  info "Downloading VAE models..."
  curl -L --progress-bar "https://huggingface.co/stabilityai/sd-vae-ft-mse-original/resolve/main/vae-ft-mse-840000-ema-pruned.safetensors" -o "models/vae/sd_vae.safetensors"
  curl -L --progress-bar "https://huggingface.co/madebyollin/sdxl-vae-fp16-fix/resolve/main/sdxl_vae.safetensors" -o "models/vae/sdxl_vae.safetensors"

  

  info "Downloading preview models..."
  curl -L --progress-bar "https://github.com/madebyollin/taesd/raw/main/taesd_decoder.pth" -o "models/vae_approx/taesd_decoder.pth"
  curl -L --progress-bar "https://github.com/madebyollin/taesd/raw/main/taesdxl_decoder.pth" -o "models/vae_approx/taesdxl_decoder.pth"
  curl -L --progress-bar "https://huggingface.co/comfyanonymous/taesd/resolve/main/taesd3_decoder.pth" -o "models/vae_approx/taesd3_decoder.pth"
  curl -L --progress-bar "https://huggingface.co/comfyanonymous/taesd/resolve/main/taef1_decoder.pth" -o "models/vae_approx/taef1_decoder.pth"

  info "Downloading ControlNet models..."

  curl -L --progress-bar "https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_canny.pth" -o "models/controlnet/control_v11p_sd15_canny.pth"
  curl -L --progress-bar "https://huggingface.co/lllyasviel/ControlNet-v1-1/resolve/main/control_v11p_sd15_openpose.pth" -o "models/controlnet/control_v11p_sd15_openpose.pth"
  # After downloading models, create symbolic links for maximum compatibility

  info "Creating symbolic links for model compatibility..."
  cd models/checkpoints
  ln -s sd_v1-5.safetensors v1-5-pruned-emaonly-fp16.safetensors
  ln -s sd_v1-5.safetensors v1-5-pruned-emaonly.safetensors
  ln -s sd_v1-5.safetensors v1-5-pruned.safetensors
  ln -s sd_v1-5.safetensors v1-5.safetensors
  ln -s sdxl_base_1.0.safetensors sd_xl_base_1.0.safetensors
  ln -s sdxl_base_1.0.safetensors sdxl-base-1.0.safetensors
  cd ../..
  success "Symbolic links created for maximum compatibility."
elif [[ "$model_choice" == "2" ]]; then

  # Download minimal set
  info "Downloading minimal model set..."
  info "Downloading SD 1.5 models..."
  curl -L --progress-bar "https://huggingface.co/runwayml/stable-diffusion-v1-5/resolve/main/v1-5-pruned-emaonly.safetensors" -o "models/checkpoints/sd_v1-5.safetensors"
  info "Downloading VAE model..."
  curl -L --progress-bar "https://huggingface.co/stabilityai/sd-vae-ft-mse-original/resolve/main/vae-ft-mse-840000-ema-pruned.safetensors" -o "models/vae/sd_vae.safetensors"

  

  info "Downloading preview models..."
  curl -L --progress-bar "https://github.com/madebyollin/taesd/raw/main/taesd_decoder.pth" -o "models/vae_approx/taesd_decoder.pth"
  curl -L --progress-bar "https://github.com/madebyollin/taesd/raw/main/taesdxl_decoder.pth" -o "models/vae_approx/taesdxl_decoder.pth"
  # After downloading models, create symbolic links for maximum compatibility
  info "Creating symbolic links for model compatibility..."
  cd models/checkpoints
  ln -s sd_v1-5.safetensors v1-5-pruned-emaonly-fp16.safetensors
  ln -s sd_v1-5.safetensors v1-5-pruned-emaonly.safetensors
  ln -s sd_v1-5.safetensors v1-5-pruned.safetensors
  ln -s sd_v1-5.safetensors v1-5.safetensors
  cd ../..
  success "Symbolic links created for maximum compatibility."

else
  info "Skipping model download. You'll need to add models manually later."
fi

# Create launcher script
info "Creating launcher script..."
cat > "$HOME/start_comfyui.sh" << EOL
#!/bin/bash
# ComfyUI Launcher Script
# Activate the Conda environment
source "\$(conda info --base)/etc/profile.d/conda.sh"
conda activate $ENV_NAME
# Navigate to ComfyUI directory
cd $COMFYUI_DIR
# Start ComfyUI with high-quality previews
python main.py --preview-method taesd
EOL
chmod +x "$HOME/start_comfyui.sh"
success "Launcher script created at ~/start_comfyui.sh"
# Installation complete
echo
echo "=========================================================="
echo "       ComfyUI Installation Complete!"
echo "=========================================================="
echo
success "ComfyUI has been installed successfully!"
echo
info "To start ComfyUI, run:"
echo "  ~/start_comfyui.sh"
echo
info "When ComfyUI is running, access it by opening:"

echo "  http://127.0.0.1:8188 in your web browser"
echo
info "Installation details:"
echo "  - ComfyUI directory: $COMFYUI_DIR"
echo "  - Conda environment: $ENV_NAME"
echo "  - Models directory: $COMFYUI_DIR/models"
echo
warning "Remember to run 'conda activate $ENV_NAME' before using ComfyUI if you don't use the launcher script."
echo
success "Happy generating!"
Echo

Save this script to a file (e.g., install_comfyui.sh), make it executable with

chmod +x install_comfyui.sh,

and run it with

./install_comfyui.sh.

Open your web browser and navigate to http://127.0.0.1:8188 to access the ComfyUI interface.

/fragments/ddt/ai-proposition

Other Articles

path=*
path=*