Skip to main content
Sher’s link command accepts several flags to customize the build and deployment process.

Quick Reference

sher link                  # Build and share
sher link --no-build       # Skip build step
sher link --dir ./my-build # Share a specific directory
sher link --ttl 4          # Set link expiry in hours
sher link --pass           # Password-protect (Pro)
sher link --pass mysecret  # Password-protect with specific password (Pro)

Build Options

--no-build

Skip the build step and upload an existing output directory. Use case: When you’ve already built your project or want to share pre-built files.
sher link --no-build
This is useful for CI/CD pipelines where the build happens in a separate step.

--dir <path>

Specify a custom output directory to upload. Default behavior: Sher auto-detects the output directory based on your framework:
  • Vite → dist/
  • Next.js → out/
  • Astro → dist/
  • Create React App → build/
sher link --dir ./public
The directory must exist and contain an index.html file (or equivalent entry point) for the preview to work correctly.

--ttl <hours>

Set the time-to-live (expiry time) for the preview link in hours. Default: 24 hours Limits by tier:
TierMax TTL
Free (anonymous)6 hours
Starter (GitHub login)24 hours
Pro ($8/mo)168 hours (7 days)
sher link --ttl 4
The TTL value is automatically clamped to the maximum allowed for your tier. If you specify a value higher than your tier’s limit, it will be reduced to the maximum.

--pass [password]

Password-protect the preview link. Behavior:
  • Without a value: Generates a random 8-character password
  • With a value: Uses the specified password
sher link --pass
Example output:
$ sher link --pass

  sher share your work

  framework  Vite
  building   npm run build

  files      12 files (194KB)

  https://a8xk2m1p.sher.sh  (copied)
  password   f7a3c9e1
  expires 2/19/2026, 11:00 AM
Password protection is only available on the Pro tier. You’ll get an error if you try to use this flag without a Pro subscription.

Random Password Generation

When you use --pass without a value, Sher generates a cryptographically secure 8-character hexadecimal password (e.g., f7a3c9e1). Implementation from src/index.ts:186-190:
let password: string | undefined;
if (flags.pass) {
  password =
    typeof flags.pass === "string"
      ? flags.pass
      : randomBytes(4).toString("hex"); // 8-char random
}

General Options

--help or -h

Display help information.
sher --help

--version or -v

Show the installed version of Sher.
sher --version

Combining Options

You can combine multiple flags to customize your deployment:
sher link --dir ./output --ttl 12

Best Practices

Set shorter TTLs for temporary shares:
# Quick demo (2 hours)
sher link --ttl 2

# Client review (24 hours)
sher link --ttl 24

# Long-term staging (Pro only)
sher link --ttl 168
Always use --pass for private client work or internal previews:
# Random password (share via secure channel)
sher link --pass

# Pre-shared password
sher link --pass "client-demo-2024"
In monorepos, specify the exact output directory:
# Frontend in a monorepo
sher link --dir ./apps/web/dist

# Specific package
sher link --dir ./packages/ui/build
When deploying from CI, build first and use --no-build:
- name: Build
  run: npm run build

- name: Deploy preview
  run: sher link --no-build

Error Handling

Rate Limits

If you exceed your tier’s daily limit, Sher will show an error before building:
Rate limit reached (1/day). Run `sher login` for up to 25/day.
Solutions:
  • Free tier: Run sher login to upgrade to Starter (25/day)
  • Starter tier: Run sher upgrade for Pro (200/day)

Upload Size Limits

If your build output exceeds the maximum upload size:
Error: Build output is 55.2MB (max 50MB)
Solutions:
  • Remove unused assets from your build
  • Optimize images and other media files
  • Use --dir to upload only necessary files
  • Upgrade to Pro for 100MB limit

Invalid TTL

TTL values are automatically clamped between 1 and 168 hours. Invalid values are corrected:
// From src/index.ts:192-194
const ttlVal =
  typeof flags.ttl === "string" ? parseInt(flags.ttl, 10) : DEFAULT_TTL;
const ttl = Math.min(Math.max(ttlVal || DEFAULT_TTL, 1), 168);

Build docs developers (and LLMs) love