This design is now OSHWA certified:
I should also mention how I chose the resistor values, since that is something that can be tuned to individual preference.
10k resistors for the LED current limiting is quite weak and the LEDs are only dimly lit. That is by choice so I can stare at them comfortably continuously while counting which ones are lit. They are very viewable in a dim room, but could get washed out with bright ambient lighting. You may wish to choose something in the 1k to 3k range for better visibility.
I also chose 10k resistors for the I2C pullups. I really like this value for I2C pullups, at least for peripherals. Besides being one of the most common resistor values you may have laying around, it is usually just strong enough to run at a reasonable speed, but weak enough that it would rarely overload the open drain drivers when combined with any other pullups on the bus. If this were the I2C host, I would probably use stronger 3.3k or 2.2k Ohm resistors, but 10k is a nice safe value for a peripheral when you don't know what is on the other end.
These assumptions are based on a 3.3V supply, but the PCF8574 is also rated for 5V operation and 10k resistors should operate safely with 5V, providing better LED visibility.
Seems like the first thing I test on just about every board I design is I2C. This is probably why I am such a fan of the SparkFun Qwiic connector, since it save me time trying to remember the order of SCL/SDA on a header.
Now that all my boards are using Qwiic connectors, I'm always looking for a Qwiic peripheral board to check out the hardware/tools/libraries. The closest one is usually one of my Qwiic NFCEEPROMs or badges. That is not quite ideal, because I don't have that register map committed to memory. What I a really want is a simple device that can provide some quick feedback.
That is why I chose the PCF8574, it is just about the simplest I2C device you will find. There is no secondary addressing, A read always returns the physical state of the pins, and a write always updates the open drain outputs. As long as you don't force the pins high, you don't even need to worry about contention since the outputs are open drain.
So now we have a simple way to read and write digital I/O, all that is left is to convert that to a more human friendly interface. An LED on each pin makes the output visible, and the dual row 100mil pitch header performs double duty as an input jumper and connectivity to the rest of the world.
The board is only as large as it needs to be. All the resistors, caps and LEDs are 0603, and I opted for an old school through hole SIP resistor network since it was easier to solder and greatly simplified the routing.
If you think it is too small or wish there were mounting holes, go ahead an modify to your hearts content. All the KiCad files are on github.