For one example, socket activation. To get the benefit of systemd (socket activation is supposedly the whole reason they supposedly created systemd) you have to patch your application to use the sd_* family of system calls. Old apps can be patched to support this, but new apps may not have any incentive to be built to use traditional sockets. So newer socket-communicating apps may not work at all on non-systemd systems.
Another is daemonization. In traditional systems, long-lived processes daemonized themselves and took care of themselves. The big benefit was independence and flexibility. You don't have to do a lot of work to port it, or maintain it, or administrate it. A shell script and some simple conventions allow it to run in almost any environment, and all of the services basically worked the same way. Often this was out of the necessity of a complex program's needs, where the way it manages its tasks, or shares memory, or communicates with other processes, or handles signals, or is checkpointed, or debugged, etc may have had complex requirements.
But now, systemd recommends you not daemonize your process. Let systemd manage it for you! This works great for very simple services, but not so well for complex ones. Now people are writing more services that can't manage themselves and thus need something like systemd to take care of it, or it simply won't work as a daemon on a non-systemd system.
The systemd people would say, any system can adopt these calls and these methods! (Which is equivalent to saying, any OS can adopt Linux's completly nonportable and specific syscalls, even though they already have a working alternative) But that's not the end of it. Every piece of systemd that you adopt, then depends on other piece of systemd, so you can't just pick up one piece of the pie. You have to eat the entire thing.