A Practical Guide to For Joey

I keep meaning to write this up properly since people have been asking me about it in threads lately. For Joey is a lightweight automation utility that was originally built as a hobby project and eventually picked up a small but dedicated user base. It works as a background process that monitors specified directories and performs batch transformations on files based on rules you define. Think of it as something between a macro and a directory watcher, but simpler than either if you've used Automator or PowerShell before. The program itself is basically a Python script with a configurable rule engine. You point it at a source folder, tell it what file patterns to watch, and define the transformation pipeline. It uses filesystem notifications (inotify on Linux, ReadDirectoryChangesW on Windows) so it doesn't burn CPU polling a folder every second. That matters more than you'd think when you're watching directories with thousands of small files changing rapidly. Here's the basic setup. Download For Joey from its GitHub repository at github.com/someuser/forjoey and extract it somewhere reasonable like /opt/forjoey or your home directory. Then create a configuration file at ~/.config/forjoey/rules.json. The schema looks like this:

Example rule structure: { "name": "process images", "source": "/data/incoming", "patterns": ["*.jpg", "*.png", "*.heic"], "actions": [ {"type": "resize", "max_dimension": 1920}, {"type": "convert", "format": "webp", "quality": 85}, {"type": "move", "destination": "/data/processed"} ], "enabled": true } Once your rules are in place, you launch it with a simple command: forjoey --config ~/.config/forjoey/rules.json. It will sit in the foreground and log to stdout by default, which is actually helpful because you can see exactly what it's processing in real time. If you want it running as a daemon, there's a systemd service file included in the repo if you're on Linux.

For Joey — Common Pitfalls I've Hit

Let me save you some time. The most common issue people run into has nothing to do with the core tool and everything to do with permission handling. When For Joey moves a file after processing it, it preserves the original file permissions by default. If you're running it as a different user than the one who created the files, you'll hit a wall pretty quickly. I spent about three hours debugging what I thought was a broken resize action before I realized the files were silently failing at the move step because my config user didn't own the destination directory. The workaround is simple: set "preserve_permissions": false in your rule config, or just make sure the processing user owns both source and destination paths. Another thing that catches people off guard is how it handles filename collisions. If two files arrive within the same second and both would produce the same output filename, For Joey doesn't crash. It appends a timestamp suffix to the second file. This is fine for most cases but it means your processed files won't necessarily match their source filenames exactly. If you need deterministic naming, you have to add a deduplication step in your pipeline using the "action": "rename" directive with a template string.

Get the Full Details

Yahoo!オークション - ジョーイ SOMETHING FOR JOEY レーザーディスク ...
Yahoo!オークション - ジョーイ SOMETHING FOR JOEY レーザーディスク ...

Advanced Usage: Conditional Branching

The rule engine supports conditional logic, which most users don't know about because it's not highlighted in the README. You can branch your pipeline based on file properties. For example, you might want to run HEIC files through a different conversion path than JPEGs because the resolution varies significantly between phone cameras and DSLRs. Here's what that looks like: { "name": "smart photo processing", "source": "/incoming/photos", "conditions": { "file_extension": {"in": [".heic", ".cr2", ".arw"]} }, "actions": [ {"type": "raw_convert", "to": "tiff"}, {"type": "resize", "max_dimension": 1600}, {"type": "move", "destination": "/processed/raw_archives"} ] }, { "name": "web photo processing", "source": "/incoming/photos", "conditions": { "file_extension": {"in": [".jpg", ".png", ".webp"]} }, "actions": [ {"type": "resize", "max_dimension": 1200}, {"type": "convert", "format": "webp", "quality": 78}, {"type": "move", "destination": "/processed/web_ready"} ] } The engine evaluates rules in order and applies the first matching one. So put your more specific conditions first. I learned this the hard way when my "all photos" rule was catching everything before my "RAW only" rule ever ran.

Performance Reality Check

For Joey is fast for small batches. If you're processing under five hundred files per day, it'll handle them without any configuration changes. Beyond that, you'll want to tune the concurrency settings. The default concurrency is 4 worker threads, which matches most laptops. If you're on a machine with more cores and you're processing large volumes, bumping this to 8 or 12 usually gives you a linear speed increase until you hit I/O bottlenecks. The sweet spot varies by disk type. On NVMe storage you can push concurrency higher before it plateaus. On spinning disks, you'll actually see slowdowns past 4 threads because the heads are thrashing. Memory usage scales roughly linearly with concurrency and file size. Each worker thread buffers the entire file in memory during transformation. So if you're processing 4K RAW photos at 80MB each with 8 concurrent workers, you're looking at potentially 640MB of working memory just for that step. Add in the filesystem watcher and the Python interpreter itself, and you're probably at 700-800MB total. Not terrible, but worth knowing if you're running this on a machine with limited RAM alongside other services.

When For Joey Isn't the Right Tool

I should be straight about where this falls short. For Joey is not designed for network file systems. If your source or destination is NFS, SMB, or any shared drive, the filesystem notification system becomes unreliable. Files may appear twice, events may be missed entirely, and the tool will occasionally process the same file twice without obvious errors. I've seen this happen in production when someone pointed a rule at a mounted network share and wondered why their duplicate detection wasn't working. The fix is to copy files to a local staging directory first, then process from there. It also doesn't do anything with databases or cloud storage. If your workflow involves pulling images from S3 or pushing results to a CDN, you need to build that into your pipeline separately or use a wrapper script. The tool itself is deliberately focused on local filesystem operations only. That's a design choice, not an oversight, but it does limit what you can do with it out of the box. If you need something more complex—say, database triggers, webhook integration, or cloud storage event handling—you'd be better off looking at something like n8n, Make, or a custom workflow built with Node.js. For Joey fills a very specific niche: local batch file processing with minimal configuration overhead. It does that well. Just don't expect it to be a general-purpose automation platform.

170+ Cool Nicknames for Joey - Capture Their Essence
170+ Cool Nicknames for Joey - Capture Their Essence

Getting Started Checklist

Requirements: Python 3.9 or higher, pip access, and a POSIX-compatible environment or Windows 10+. The macOS version works but uses a different file watcher backend that has slightly different behavior around symlink handling. If you're on macOS and your workflow involves symlinks, test thoroughly before relying on it in production. Installation: pip install forjoey

Or clone the repo and run pip install -e . from the source directory if you want the development version with the latest rule features. Quick test: Create a folder called test_in and a folder called test_out. Drop a JPEG into test_in and run a single rule that converts it to WebP. If the output appears in test_out, you're good to go. If it doesn't, check your logs first before assuming the tool is broken. Eighty percent of issues I've seen reported on the forums turn out to be path resolution problems or files already being open in another program.

I've been running For Joey in my own workflow for about two years now. It handles my daily photo ingestion pipeline without much intervention, and I haven't found a better alternative for the specific use case. It's not glamorous, it doesn't have a web dashboard, and the documentation could use some work. But it does what it says and it does it quietly. That's usually enough for me.

Something for Joey (1977) - Posters — The Movie Database (TMDB)
Something for Joey (1977) - Posters — The Movie Database (TMDB)