"to create and apply diff patches to small component files"
The file/file system aware approach is the method most would use to get to your position. Usually in the form of a batch file, something that can rip files from a given system's ISO/ROM and then return it after patching.
You can drop down a level lower and do pointer, or possibly content, aware stuff if you must (though you will likely be coding it yourself). You usually see this for high level game editing tools but no reason you could not do it here.
This is what the patcher I wrote does. Other than STR and XA files, the game has two main types of data- and code-containing files: MRG files and BPE files. The MRG files are composed of a bunch of smaller data files indexed by an LBA table at the head of the MRG file. Some MRG files are composed of MRG files themselves, up to a few layers deep. Since I can just change the address and file size in the LBA table, these are the files I can alter the size of if I need to. In my case, it's just text overflow, rather than code.
The BPE files are byte-pair encoded by block, usually 2048 bytes per decompressed block, sometimes less. When I mod these, I decompress only the blocks I'm interested in, then recompress them. Due to where many of these files are loaded in RAM, I don't
change their sizes.
So the process I use is: extract game files from disc -> decompress blocks/extract subfiles to smallest possible LBA-table-referenced unit -> patch -> recompress/reinsert subfiles -> insert game files into disc
Stacking theoretically dynamic/size altering patches though is mathematically tricky, even more so when you consider most such dynamic/relocation scans are computers doing something like a compression algorithm and not humans assigning meaning to sections of code.
I think the BPE's are the only ones where I need to stack patches, so I actually doubt I'll need to stack size-altering patches.
What I need is something that can potentially stack static patches or
change file size, but does not have to be able to do both at the same time.
"to make sure they aren't going to modify the same bytes"
Which will work until you repoint something and thus render something else redundant. If you are dealing with pointers that is not even a rare case. If you know you are not going to do this and thus have a limited case then so be it.
I consider this scenario unlikely, if I'm understanding you correctly.