We run a kiosk thing, use i3 without a status bar, directly launch the program from the xinitrc (or whatever script, which launches i3 in the background, sleeps 1 second, then launches the kiosk thing), and all this via startx.
If the script exits, X exits, systemd restarts it. Works pretty well.