https://image.wenhaofree.com/2025/06/84543499c9e27ad5d0ed475431ca9953.png

FNM Complete Guide: Fast and Efficient Node.js Version Manager

FNM Complete Guide: Fast and Efficient Node.js Version Manager

FNM (Fast Node Manager) is a modern Node.js version manager written in Rust, known for its fast switching speed and cross-platform support. Compared to traditional version management tools, FNM provides better performance and a more streamlined user experience.


🚀 What is FNM?

FNM is a lightweight, high-performance Node.js version manager with the following characteristics:

Core Advantages

  • ⚡ Lightning Fast: Written in Rust, version switching is several times faster than traditional tools
  • 🌍 Cross-platform Support: Full support for macOS, Linux, and Windows
  • 🔄 Automatic Switching: Supports automatic Node.js version switching when entering project directories
  • 📦 Lightweight: Small installation package with minimal resource usage
  • 🛡️ Type Safety: Memory safety guarantees from Rust

Comparison with Other Tools

Feature FNM NVM N
Language Rust Bash Node.js
Switching Speed 🚀 Extremely Fast 🐌 Slower 🚀 Fast
Cross-platform ✅ Full Support ⚠️ Limited Windows ✅ Full Support
Auto Switching ✅ Supported ✅ Supported ✅ Supported
Installation Size 📦 Small 📦 Medium 📦 Large

📦 Installing FNM

1. macOS / Linux Systems

# Install FNM
brew install fnm

# Verify installation
fnm --version

Using Installation Script (Cross-platform)

# Download and install FNM
curl -fsSL https://fnm.vercel.app/install | bash

# Custom installation options
curl -fsSL https://fnm.vercel.app/install | bash -s -- --skip-shell
curl -fsSL https://fnm.vercel.app/install | bash -s -- --install-dir=/custom/path

2. Windows Systems

Using winget

# Install via winget
winget install Schniz.fnm

# Verify installation
fnm --version

Using Scoop

# Install via Scoop
scoop install fnm

⚙️ Shell Environment Configuration

Bash Configuration

# Add to ~/.bashrc
echo 'eval "$(fnm env --use-on-cd --shell bash)"' >> ~/.bashrc

# Reload configuration
source ~/.bashrc

Zsh Configuration

# Add to ~/.zshrc
echo 'eval "$(fnm env --use-on-cd --shell zsh)"' >> ~/.zshrc

# Reload configuration
source ~/.zshrc

Fish Configuration

# Add to ~/.config/fish/config.fish
echo 'fnm env --use-on-cd --shell fish | source' >> ~/.config/fish/config.fish

PowerShell Configuration

# Add to PowerShell Profile
fnm env --use-on-cd --shell powershell | Out-String | Invoke-Expression

# Or add to profile file
Add-Content -Path $PROFILE -Value 'fnm env --use-on-cd --shell powershell | Out-String | Invoke-Expression'

🔧 Environment Variable Configuration

Common Environment Variables

# Custom FNM installation directory
export FNM_DIR="$HOME/.fnm"

# Set Node.js download mirror (improve download speed)
export FNM_NODE_DIST_MIRROR="https://npmmirror.com/mirrors/node/"

# Set remote version list cache time (seconds)
export FNM_REMOTE_VERSIONS_CACHE_DURATION=86400

China Mirror Configuration

# Use Taobao mirror for faster downloads
export FNM_NODE_DIST_MIRROR="https://npmmirror.com/mirrors/node/"

# Or use Tencent Cloud mirror
export FNM_NODE_DIST_MIRROR="https://mirrors.cloud.tencent.com/nodejs-release/"

📋 Basic Usage Commands

Version Management Commands

# List all available remote versions
fnm list-remote

# List all LTS versions
fnm list-remote --lts

# Install latest LTS version
fnm install --lts

# Install specific major version
fnm install 18

# Install complete version number
fnm install 18.21.1

# Install latest version
fnm install latest

# List locally installed versions
fnm list

# View current version
fnm current

Version Switching Commands

# Switch to specified version (current session)
fnm use 18

# Set default version
fnm default 18

# Switch to latest version
fnm use latest

# Switch to latest LTS version
fnm use --lts

Version Uninstall Commands

# Uninstall specified version
fnm uninstall 18.21.1

# Uninstall current version
fnm uninstall $(fnm current)

# Batch uninstall all versions (Linux/macOS)
fnm list | awk -F' ' 'NR>1 {print $2}' | xargs -n1 fnm uninstall

🏷️ Alias Management

Creating and Using Aliases

# Create alias for version
fnm alias 18.21.1 lts-hydrogen

# Create alias for latest LTS
fnm alias $(fnm current --lts) lts

# Switch version using alias
fnm use lts-hydrogen

# Set default alias
fnm default lts-hydrogen

Managing Aliases

# List all aliases
fnm aliases

# Delete alias
fnm unalias lts-hydrogen

# Create aliases for multiple versions
fnm alias 18.21.1 stable-18
fnm alias 20.12.2 stable-20

📁 Project-level Version Management

Using .node-version File

# Create .node-version file in project root
echo "18.21.1" > .node-version

# Or create using FNM command
fnm use 18.21.1 --save

Using .nvmrc File

# Create .nvmrc file (compatible with NVM)
echo "18.21.1" > .nvmrc

# FNM will automatically recognize .nvmrc files

Specifying Version in package.json

{
  "name": "my-project",
  "version": "1.0.0",
  "engines": {
    "node": ">=18.0.0",
    "npm": ">=8.0.0"
  },
  "volta": {
    "node": "18.21.1"
  }
}

Automatic Switching Feature

# Enable automatic version switching when entering directory
fnm use 18.21.1 --save-if-exists

# --use-on-cd parameter already included in shell configuration
# Automatic switching occurs when entering project directory
cd ~/my-project
# FNM will automatically detect and switch to version specified in .node-version or .nvmrc

🔄 Advanced Usage Tips

Batch Operations

# Install multiple versions
for version in 16 18 20; do
  fnm install $version
done

# Batch uninstall old versions
fnm list | grep -E "v(14|16|17)" | awk '{print $2}' | xargs -n1 fnm uninstall

Scripted Usage

#!/bin/bash
# Script to automatically select best Node.js version

PROJECT_VERSION_FILE=".node-version"
if [ -f "$PROJECT_VERSION_FILE" ]; then
  REQUIRED_VERSION=$(cat "$PROJECT_VERSION_FILE")
  echo "Project requires Node.js version: $REQUIRED_VERSION"
  
  if ! fnm list | grep -q "$REQUIRED_VERSION"; then
    echo "Installing required version..."
    fnm install "$REQUIRED_VERSION"
  fi
  
  fnm use "$REQUIRED_VERSION"
  echo "Switched to version: $(fnm current)"
else
  echo "No project version file found, using default LTS version"
  fnm use --lts
fi

Integration with Other Tools

# Docker integration
FROM node:18-alpine
RUN curl -fsSL https://fnm.vercel.app/install | bash -s -- --install-dir=/opt/fnm
ENV PATH="/opt/fnm:${PATH}"
RUN fnm install 18 && fnm use 18

# CI/CD integration (GitHub Actions)
- name: Setup FNM
  run: |
    curl -fsSL https://fnm.vercel.app/install | bash
    echo 'eval "$(fnm env --use-on-cd --shell bash)"' >> ~/.bashrc
    source ~/.bashrc
    fnm install --lts
    fnm use --lts

🛠️ Uninstalling FNM

macOS / Linux Uninstallation

# 1. Delete FNM installation directory
rm -rf ~/.local/share/fnm
# Or if using custom directory
rm -rf ~/.fnm

# 2. Remove FNM configuration from shell config
# Edit ~/.bashrc, ~/.zshrc etc., remove the following line:
# eval "$(fnm env --use-on-cd --shell bash)"

# 3. Delete environment variables
unset FNM_DIR
unset FNM_NODE_DIST_MIRROR

# 4. Verify uninstallation
fnm --version  # Should show command not found

Windows Uninstallation

# 1. Uninstall using winget
winget uninstall Schniz.fnm

# 2. Manually delete installation directory
Remove-Item -Recurse -Force $env:LOCALAPPDATA\fnm

# 3. Remove configuration from PowerShell Profile
# Edit $PROFILE file, remove FNM related configuration

# 4. Delete environment variables
[Environment]::SetEnvironmentVariable("FNM_DIR", $null, "User")
[Environment]::SetEnvironmentVariable("FNM_NODE_DIST_MIRROR", $null, "User")

🔍 Troubleshooting Common Issues

Slow Download Speed

# Set domestic mirror
export FNM_NODE_DIST_MIRROR="https://npmmirror.com/mirrors/node/"

# Or use Tencent Cloud mirror
export FNM_NODE_DIST_MIRROR="https://mirrors.cloud.tencent.com/nodejs-release/"

Version Switching Not Working

# Reload shell configuration
source ~/.zshrc  # or ~/.bashrc

# Manually execute environment loading
eval "$(fnm env --use-on-cd --shell zsh)"

# Check current version
fnm current
node --version

VS Code Terminal Version Issues

// VS Code settings.json
{
  "terminal.integrated.profiles.osx": {
    "zsh": {
      "path": "/bin/zsh",
      "args": ["-l"]
    }
  },
  "terminal.integrated.defaultProfile.osx": "zsh"
}

Permission Issues

# Fix FNM directory permissions
chmod 755 ~/.local/share/fnm
chmod -R 644 ~/.local/share/fnm/node-versions

# Or change installation directory to user home
export FNM_DIR="$HOME/fnm"

📊 Performance Optimization

Cache Configuration

# Set version list cache time (default 1 hour)
export FNM_REMOTE_VERSIONS_CACHE_DURATION=86400  # 24 hours

# Clear cache
fnm list-remote --clear-cache

Concurrent Installation

# Install multiple versions in parallel
fnm install 16 & fnm install 18 & fnm install 20 & wait

🎯 Best Practices

Project Management

  1. Always use version files: Create .node-version files for each project
  2. Semantic versioning: Use major versions (like 18) instead of specific versions
  3. Team collaboration: Include .node-version files in version control

Development Workflow

# 1. After cloning project
cd my-project

# 2. FNM automatically detects and switches version
fnm current  # Shows project required version

# 3. Verify environment
node --version
npm --version

# 4. Install dependencies
npm install

Version Strategy

# Development environment: use latest LTS
fnm use --lts

# Production environment: fixed version
fnm use 18.21.1

# Testing environment: multi-version testing
for version in 16 18 20; do
  fnm use $version
  npm test
done


Conclusion

FNM, as a modern Node.js version management tool, provides developers with an efficient version management experience through its excellent performance and clean design. With the detailed introduction in this guide, you should be able to master FNM’s usage methods and improve your development efficiency.

The Ultimate Codex CLI MCP Guide: From Beginner to Advanced

Have you ever encountered this situation: your AI assistant is powerful enough, but still falls short in certain specific scenarios? For example, it cannot access real-time information, directly operate browsers, or connect to specific databases?

Don’t worry! Today I’m going to introduce you to a game-changer—Codex CLI’s MCP (Model Context Protocol). It’s like installing “USB-C ports” for AI, allowing it to connect to various external tools and services, instantly doubling your AI assistant’s capabilities!

Prisma Complete Guide: Modern Next.js Database ORM Tool Deep Dive

Prisma Complete Guide: Modern Next.js Database ORM Tool Deep Dive

Prisma is a modern database ORM (Object-Relational Mapping) tool designed specifically for TypeScript and Node.js. It provides type-safe database access, auto-generated type definitions, and an intuitive query API that makes database operations simple and efficient.


🚀 What is Prisma?

Prisma is a next-generation database toolkit that includes the following core components:

Core Features

  • Type Safety: Auto-generated TypeScript types catch errors at compile time
  • Auto-completion: Complete intelligent hints support in IDEs
  • Database Migration: Version control friendly database schema management
  • Visual Tool: Prisma Studio provides intuitive database management interface

Differences from Traditional ORMs

Feature Prisma Traditional ORM (like TypeORM)
Type Safety ✅ Fully type-safe ⚠️ Partially type-safe
Learning Curve 📉 Gentle and friendly 📈 Relatively steep
Query Syntax 🎯 Intuitive and concise 🔧 Relatively complex
Migration Tools ✅ Built-in powerful ⚠️ Basic functionality

📦 Installation and Configuration

1. Project Initialization

# Create new Next.js project
npx create-next-app@latest my-prisma-app

# Enter project directory
cd my-prisma-app

# Install Prisma
npm install prisma --save-dev
npm install @prisma/client

2. Initialize Prisma

# Initialize Prisma project
npx prisma init

This creates the following file structure:

Next.js Project Structure: Detailed Comparison of Using src/ Directory vs Root Directory

When developing projects with Next.js (especially v13 and above), you’ll often encounter two common directory structure choices: • Placing app/ or pages/ directories directly in the project root (i.e., not using src/) • Creating a src/ folder in the root directory and placing app/ or pages/ directories under src/app or src/pages (i.e., using src/)

Below, I’ll compare these two approaches in detail from three perspectives: “structural differences,” “pros and cons,” and “use cases.”

Full-Stack Test with Claude Code + Sub-agents: The Decisive Factor in the 'Process Power' of Four Domestic Models

Background and Methods

Evaluating AI programming models in real full-stack tasks is the only way to see if they can “deliver.” This test used a tech stack of Astro + TypeScript + Tailwind + WordPress Headless (REST) to deliver a company website and an independent blog (list, details, search, pagination, SEO). Standardized prompts and constraints (strict TS, pnpm, responsive and performance metrics) were used, and the entire front-end and back-end pipeline was run through the automatic coordination of Claude Code’s sub-agents, recording latency, repair costs, and billing data.

App Store Review Guideline 2.1 (Performance - App Completeness): Fix Subscription Page Infinite Loading (Receipt Validation and Frontend Timeout)

App Store Review Guideline 2.1 (Performance - App Completeness): Fix Subscription Page Infinite Loading (Receipt Validation and Frontend Timeout)

A common rejection reason: subscription page spins forever due to improper receipt validation and missing frontend timeouts.


1. Issue Context (Guideline 2.1)

  • Symptom: loading never ends; poor UX.
  • Causes:
    • Backend only calls production endpoint; sandbox receipts not handled (must handle 21007).
    • Frontend requests have no timeout or error UI, leading to infinite waiting.

2. Solution Overview

  1. Backend: production-first receipt validation with sandbox fallback; enforce timeouts.
  2. Frontend: set request timeouts; show loading state; surface errors; allow retry.
  3. Platform: ensure paid apps agreement is accepted in App Store Connect.

3. Backend: Receipt Validation (Python/Requests)

import requests

APPLE_PRODUCTION_URL = "https://buy.itunes.apple.com/verifyReceipt"
APPLE_SANDBOX_URL = "https://sandbox.itunes.apple.com/verifyReceipt"

TIMEOUT_SECONDS = 10


def validate_receipt(receipt_data: str, password: str) -> dict:
    """Try production first; if status == 21007 then retry sandbox. Apply request timeouts."""
    payload = {
        "receipt-data": receipt_data,
        "password": password,
        "exclude-old-transactions": True,
    }

    # 1) production first
    resp = requests.post(APPLE_PRODUCTION_URL, json=payload, timeout=TIMEOUT_SECONDS)
    result = resp.json()

    # 2) sandbox fallback
    if result.get("status") == 21007:
        resp = requests.post(APPLE_SANDBOX_URL, json=payload, timeout=TIMEOUT_SECONDS)
        result = resp.json()

    return result

Key points:

Choosing JDK Versions: A Comprehensive Comparison of JDK 8/11/17/21/24 and Community Consensus

Choosing JDK Versions: A Comprehensive Comparison of JDK 8/11/17/21/24 and Community Consensus

1. JDK 8

  • Considered the foundation of modern Java; extremely stable and widely adopted.
  • Lambda/Streams greatly improved productivity; mature ecosystem; low upgrade cost.
  • Best for stability-first projects with high migration cost.

2. JDK 11 (LTS)

  • Start of modern Java; inherits features from 9/10: modules, HttpClient, ZGC, etc.
  • Leaner: removed legacy modules; JDK/JRE merged; G1 default.
  • Recommended for new projects; smoother upgrade path from 8.

3. JDK 17 / 21 (LTS)

  • Ongoing evolution: sealed classes, records, virtual threads, pattern matching, etc.
  • Future-facing; ecosystem support maturing; mainline LTS choices.

4. JDK 24 (latest stable, non-LTS)

  • Latest syntax and API updates; great for experimenting and testing.
  • Prefer LTS for production; evaluate feature ROI.

5. Consensus & Recommendations

  • Most teams use 8/11/17/21 (LTS first) for stability.
  • New projects: latest LTS; legacy: stay on 8 or plan phased upgrades.

If you share your project’s framework/dependencies/runtime details, I can propose a tailored migration matrix and step-by-step checklist.

Fix GitHub SSH Hang: Port 443, HTTPS, and Proxy Configuration Guide

Fix GitHub SSH Hang: Port 443, HTTPS, and Proxy Configuration Guide

If ssh -T [email protected] never returns, your network to GitHub’s SSH port (22) is likely blocked or unstable. This is common in certain regions, corporate/campus environments, or some cloud servers.


Solutions

  • Use the repository’s HTTPS URL for clone/pull/push; it’s typically more stable.
  • Use a Personal Access Token (PAT) as the password when prompted.

2. Force SSH via Port 443

Sometimes port 22 is blocked but 443 is open. Route SSH via 443 by adding to ~/.ssh/config:

Xcode StoreKit Configuration: Complete Guide to Local In-App Purchase and Subscription Testing

Xcode StoreKit Configuration: Complete Guide to Local In-App Purchase and Subscription Testing

During app development, using a StoreKit configuration file (.storekit) allows local simulation of payment flows without network or sandbox accounts. This article details setup, testing, and related code to help you efficiently develop and debug IAP.


Why StoreKit Configuration?

A StoreKit configuration file acts like a “virtual store” to simulate various purchase and subscription scenarios locally, speeding iteration and avoiding frequent sandbox account switching or App Store review waiting.

APP Layout Terminology Guide: 30 Core Concepts Detailed Explanation

APP Layout Terminology Guide: 30 Core Concepts Detailed Explanation

This article systematically organizes common layout terminology in mobile application (APP) development, with detailed explanations combined with practical effects, suitable for iOS (Swift/SwiftUI/UIKit), Android, and cross-platform developers.


1. Frame

Definition:
Frame refers to the absolute coordinates and dimensions of a view, including x, y (position) and width, height (size).
Effect:
Elements are fixed at a specific position and size on screen, suitable for static, simple layouts.
Analogy: Like pinning a painting on the wall with fixed position and size.