Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,33 @@ no sketchy redirects.

## Install

### macOS / Linux

One-liner (installs Node if needed):

```sh
curl -fsSL https://raw.githubusercontent.com/pablostanley/yoinks/main/assets/scripts/install.sh | sh
```

Or install manually with npm (requires Node 18+):

```sh
npm install -g yoinks
```

### Windows (PowerShell)

```powershell
irm https://raw.githubusercontent.com/pablostanley/yoinks/main/assets/scripts/install.ps1 | iex
```

Or install manually:

```powershell
npm install -g yoinks
```

Or try it without installing anything:
### Try without installing

```sh
npx yoinks
Expand Down Expand Up @@ -83,7 +105,7 @@ To try it as a global command without publishing: `npm link`, then run
- [ ] Clipboard detection: launch bare and auto-suggest the url you copied
- [ ] Self-update for the bundled yt-dlp binary (`yt-dlp -U`)
- [x] Publish to npm (`npm i -g yoinks` / `npx yoinks`)
- [ ] `curl yoinks.sh | sh` installer
- [x] `curl yoinks.sh | sh` installer

## A note on fair use

Expand Down
60 changes: 60 additions & 0 deletions assets/scripts/install.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
$ErrorActionPreference = "Stop"

function Write-Info($msg) { Write-Host "▸ $msg" -ForegroundColor Green }
function Write-Warn($msg) { Write-Host "▸ $msg" -ForegroundColor Yellow }
function Write-Error($msg) { Write-Host "▸ $msg" -ForegroundColor Red; exit 1 }

# check if node is installed
function Ensure-Node {
if (Get-Command node -ErrorAction SilentlyContinue) {
$version = (node -v) -replace 'v' -split '\.' | Select-Object -First 1
if ([int]$version -ge 18) {
Write-Info "Node.js v$(node -v) found"
return
} else {
Write-Warn "Node.js v$(node -v) found but v18+ is required"
}
}

Write-Info "Installing Node.js..."
if (Get-Command winget -ErrorAction SilentlyContinue) {
winget install OpenJS.NodeJS.LTS --accept-package-agreements --accept-source-agreements
} elseif (Get-Command choco -ErrorAction SilentlyContinue) {
choco install nodejs-lts -y
} elseif (Get-Command scoop -ErrorAction SilentlyContinue) {
scoop install nodejs-lts
} else {
Write-Error "couldn't install node.js, please install from the website itself."
}

# Refresh PATH
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")

if (-not (Get-Command node -ErrorAction SilentlyContinue)) {
Write-Error "node.js installation failed. Install manually from https://nodejs.org"
}
Write-Info "Node.js v$(node -v) installed"
}

# install yoinks
function Install-Yoinks {
Write-Info "Installing yoinks..."
npm install -g yoinks 2>&1 | Out-Null

if (Get-Command yoinks -ErrorAction SilentlyContinue) {
Write-Info "yoinks installed successfully!"
} else {
Write-Error "Installation failed. Try: npm install -g yoinks"
}
}

# main
Write-Host ""
Write-Info "Installing yoinks — yoink any video"
Write-Host ""
Ensure-Node
Install-Yoinks
Write-Host ""
Write-Info "Done! Run 'yoinks' to start downloading."
Write-Info "Example: yoinks https://youtu.be/dQw4w9WgXcQ"
Write-Host ""
99 changes: 99 additions & 0 deletions assets/scripts/install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/bin/bash
set -e


BOLD="\033[1m"
GREEN="\033[32m"
YELLOW="\033[33m"
RED="\033[31m"
RESET="\033[0m"

info() { printf "${BOLD}${GREEN}▸${RESET} %s\n" "$1"; }
warn() { printf "${BOLD}${YELLOW}▸${RESET} %s\n" "$1"; }
error() { printf "${BOLD}${RED}▸${RESET} %s\n" "$1"; exit 1; }

command_exists() {
command -v "$1" >/dev/null 2>&1
}

# detect os
detect_os() {
case "$(uname -s)" in
Linux*) os="linux";;
Darwin*) os="mac";;
MINGW*|MSYS*|CYGWIN*) os="windows";;
*) error "Unsupported OS: $(uname -s)";;
esac
info "Detected OS: $os"
}

# check if node is installed
ensure_node() {
if command_exists node; then
node_version=$(node -v | sed 's/v//' | cut -d. -f1)
if [ "$node_version" -ge 18 ]; then
info "Node.js $(node -v) found"
return
else
warn "Node.js $(node -v) found but v18+ is required"
fi
fi

info "installing node.js"
if command_exists brew; then
brew install node
elif command_exists apt-get; then
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs
elif command_exists dnf; then
curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash -
sudo dnf install -y nodejs
elif command_exists yum; then
curl -fsSL https://rpm.nodesource.com/setup_20.x | sudo bash -
sudo yum install -y nodejs
elif command_exists pacman; then
sudo pacman -S --noconfirm nodejs npm
elif command_exists apk; then
sudo apk add nodejs npm
else
error "couldn't install node.js, please install from the website itself."
fi

command_exists node || error "node.js installation failed. Install manually from https://nodejs.org"
info "Node.js $(node -v) installed"
}

# install yoinks
install_yoinks() {
info "Installing yoinks..."
npm install -g yoinks 2>/dev/null || {
warn "Global install failed, trying with sudo..."
sudo npm install -g yoinks
}

if command_exists yoinks; then
info "yoinks installed successfully!"
else
warn "npm global bin not in PATH. Adding it..."
npm bin -g >> "$HOME/.bashrc" 2>/dev/null || true
npm bin -g >> "$HOME/.zshrc" 2>/dev/null || true
export PATH="$(npm bin -g):$PATH"
command_exists yoinks || error "Installation failed. Try: npm install -g yoinks"
fi
}

# main
main() {
echo ""
info "Installing yoinks — yoink any video"
echo ""
detect_os
ensure_node
install_yoinks
echo ""
info "Done! Run 'yoinks' to start downloading."
info "Example: yoinks https://youtu.be/dQw4w9WgXcQ"
echo ""
}

main