A fast, modern Node.js command-line tool that uploads files to Amazon S3 and instantly copies the URL to your clipboard. Built with TypeScript and the AWS SDK v3.
- Upload files to S3 with a single command
- Automatic URL copying to clipboard
- Support for unique file hashing (cache-busting)
- Interactive configuration wizard
- Environment variable support
- Comprehensive debug logging with verbose mode
- Modern ES modules and TypeScript
- Comprehensive input validation
- Helpful error messages
- Built with AWS SDK v3 for optimal performance
- Node.js 20 or higher (uses modern ES modules)
- AWS account with S3 access
- Valid AWS credentials
Install globally using your preferred package manager:
# Using npm
npm install -g pushfile
# Using pnpm
pnpm add -g pushfile
# Using yarn
yarn global add pushfileYou have two options to configure pushfile:
Run the interactive configuration wizard:
pushfile --configureThis creates a .pushfilerc.json file in your project directory with:
{
"awsKey": "your-aws-access-key",
"awsSecret": "your-aws-secret-key",
"s3Bucket": "your-bucket-name",
"customURL": "https://your-cdn.com" // optional
}Set these environment variables instead of using a config file:
export PUSHFILE_AWS_KEY="your-aws-access-key"
export PUSHFILE_AWS_SECRET="your-aws-secret-key"
export PUSHFILE_S3_BUCKET="your-bucket-name"
export PUSHFILE_CUSTOM_URL="https://your-cdn.com" # optional- Go to the AWS IAM Console
- Create a new IAM user with programmatic access
- Attach the
AmazonS3FullAccesspolicy (or create a custom policy with S3 write permissions) - Save your Access Key ID and Secret Access Key
Upload a file to S3 and copy the URL to your clipboard:
pushfile /path/to/file.extpushfile [options] <file>
Options:
-V, --version Output the version number
-h, --help Display help information
-c, --configure Create or update your configuration file
-u, --unique Generate a unique hash for the uploaded file
-v, --verbose Enable verbose debug loggingUpload a file:
pushfile cat.jpg
# URL automatically copied to clipboard
# Output: File is available at https://s3.amazonaws.com/your-bucket/MzgYBx...jpgUpload with unique filename:
pushfile -u screenshot.png
# Generates a unique hash each time (useful for cache busting)Configure pushfile:
pushfile --configure
# Starts interactive configuration wizardEnable debug logging:
pushfile -v cat.jpg
# Shows detailed debug outputPushfile includes comprehensive debug logging to help troubleshoot issues. There are two ways to enable debug output:
Use the -v or --verbose flag to enable all debug output:
pushfile -v myfile.txtThis will show detailed logs including:
- Configuration loading and validation
- File validation steps
- S3 client initialization
- File hashing progress
- Upload progress and results
For more granular control, use the DEBUG environment variable:
# Enable all pushfile debug logs
DEBUG=pushfile:* pushfile myfile.txt
# Enable specific modules only
DEBUG=pushfile:main,pushfile:s3 pushfile myfile.txt
# Available debug namespaces:
# - pushfile:cli - CLI argument parsing and flow
# - pushfile:config - Configuration loading and validation
# - pushfile:validate - File validation
# - pushfile:main - Main upload logic
# - pushfile:s3 - S3 client operations$ pushfile -v test.jpg
pushfile:cli CLI started with options: { unique: false, verbose: true } +0ms
pushfile:cli File argument: test.jpg +1ms
pushfile:cli Starting file upload process +0ms
pushfile:main Starting file upload: test.jpg (unique: false) +0ms
pushfile:validate Validating file: test.jpg +0ms
pushfile:validate Checking if file exists... +0ms
pushfile:validate File exists +2ms
pushfile:validate Checking file readability... +0ms
pushfile:validate File is readable +0ms
pushfile:config Loading configuration... +0ms
pushfile:config Config file found: /Users/user/project/.pushfilerc.json +1ms
pushfile:s3 Initializing S3 client... +0ms
pushfile:s3 S3 client initialized for region: us-east-1 +15ms
pushfile:main Hashing file... +0ms
pushfile:s3 Sending PutObject request: bucket=my-bucket, key=abc123.jpg +25ms
pushfile:s3 Upload successful: ETag="xyz789" +543ms
File is available at https://s3.amazonaws.com/my-bucket/abc123.jpgProblem: You get an error about incomplete configuration.
Solution: Either run pushfile --configure or set environment variables:
export PUSHFILE_AWS_KEY="your-key"
export PUSHFILE_AWS_SECRET="your-secret"
export PUSHFILE_S3_BUCKET="your-bucket"Problem: pushfile can't find your file.
Solution:
- Check the file path is correct
- Use absolute paths or ensure you're in the correct directory
- Verify the file exists:
ls /path/to/file
Problem: Your bucket name doesn't meet AWS requirements.
Solution: S3 bucket names must:
- Be 3-63 characters long
- Start and end with a lowercase letter or number
- Contain only lowercase letters, numbers, dots, and hyphens
Problem: AWS rejects your upload.
Solution:
- Verify your AWS credentials are correct
- Ensure your IAM user has S3 write permissions
- Check the bucket exists and you have access to it
Problem: File uploads successfully but the URL returns 403 Forbidden.
Solution: Check your S3 bucket's permissions. Pushfile uploads files with public-read ACL, so ensure:
- Your bucket allows public read access
- Block Public Access settings aren't preventing public reads
This project is built with TypeScript and uses modern tooling.
- Node.js 20+
- pnpm (recommended) or npm
- Clone the repository:
git clone https://github.com/joshfinnie/pushfile.git
cd pushfile- Install dependencies:
pnpm install- Build the project:
pnpm run build# Build the project
pnpm run build
# Watch mode (rebuild on changes)
pnpm run dev
# Run tests
pnpm test
# Run tests with coverage
pnpm run test:coverage
# Type checking
pnpm run typecheck
# Format code with Biome
pnpm run format
# Run all checks (CI)
pnpm run ciLink the local package to test your changes:
pnpm run link
pushfile /path/to/test-filepushfile/
├── src/
│ ├── cli.ts # CLI entry point
│ └── helpers.ts # Core functionality
├── test/
│ └── helpers.spec.ts
├── dist/ # Compiled output
├── tsconfig.json # TypeScript config
├── tsup.config.ts # Build config
└── biome.json # Linting/formatting config
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
This project is licensed under the MIT License - see the LICENSE file for details.
Josh Finnie - josh@jfin.us
- Will Laurance
- Matthew Chase Whittemore