[One (M8) Android Development] Captain_Throwback:
You would need to add f2fs into the kernel. There is a backport of f2fs kernel source for our kernel version here (note that that's a full kernel, but the f2fs files you'll need will be under fs/f2fs). You may also need the last two patches from here in order to avoid build errors with F2FS_ENCRYPTION enabled (depending on how up-to-date your kernel source is).

In the fstab, to support f2fs on /data, you'd only have to add a line for /data with f2fs as the fs_type (you'd need to leave the ext4 line there in case someone isn't using f2fs).

/dev/block/platform/msm_sdcc.1/by-name/userdata /data ext4 nosuid,nodev,barrier=1,noauto_da_alloc,discard wait,formattable,encryptable=/dev/block/platform/msm_sdcc.1/by-name/extra
[B]/dev/block/platform/msm_sdcc.1/by-name/userdata /data f2fs rw,nosuid,nodev,noatime,nodiratime,inline_xattr wait,check,formattable,encryptable=/dev/block/platform/msm_sdcc.1/by-name/extra[/B]

Userdata is the most commonly converted partition for f2fs support, but I've also been able to use both /cache and /system as f2fs. That, however, requires some additional ramdisk changes, since those partitions are mounted in init.project.rc, not in fstab.qcom. For any partition that you want the ability to mount as f2fs, you'll have to move the mount to the fstab. This is what mine looks like:

# Android fstab file.
# The filesystem that contains the filesystem checker binary (typically /system) cannot
# specify MF_CHECK, and must come before any filesystems that do specify MF_CHECK

#TODO: Add 'check' as fs_mgr_flags with data partition.
# Currently we dont have e2fsck compiled. So fs check would failed.

#<src> <mnt_point> <type> <mnt_flags and options> <fs_mgr_flags>
/dev/block/platform/msm_sdcc.1/by-name/system /system ext4 ro,seclabel,noatime,data=ordered wait
/dev/block/platform/msm_sdcc.1/by-name/system /system f2fs ro,noatime,nodev,discard,nodiratime,inline_xattr wait
/dev/block/platform/msm_sdcc.1/by-name/userdata /data ext4 nosuid,nodev,barrier=1,noauto_da_alloc,discard wait,formattable,encryptable=/dev/block/platform/msm_sdcc.1/by-name/extra
/dev/block/platform/msm_sdcc.1/by-name/userdata /data f2fs rw,nosuid,nodev,noatime,nodiratime,inline_xattr wait,check,formattable,encryptable=/dev/block/platform/msm_sdcc.1/by-name/extra
/dev/block/platform/msm_sdcc.1/by-name/cache /cache ext4 nosuid,nodev,barrier=1 wait,formattable
/dev/block/platform/msm_sdcc.1/by-name/cache /cache f2fs rw,nosuid,nodev,noatime,nodiratime,inline_xattr wait,check,formattable
/dev/block/platform/msm_sdcc.1/by-name/devlog /devlog ext4 nosuid,nodev,barrier=1,errors=continue wait,check,formattable
/dev/block/platform/msm_sdcc.1/by-name/fataldevlog /fataldevlog ext4 nosuid,nodev,barrier=1,errors=continue wait,check,formattable
/dev/block/platform/msm_sdcc.1/by-name/custdata /custdata ext4 ro,nosuid,nodev,barrier=1 wait,formattable

# Removable storage
/devices/msm_sdcc.2/mmc_host	auto vfat defaults wait,voldmanaged=ext_sd:auto,noemulatedsd,encryptable=footer
/devices/platform/xhci-hcd auto vfat defaults voldmanaged=usb:auto

I'm using my BeyondStockᵀᴹ GPE ROM + BeyondStockᵀᴹ kernel with /data, /cache & /system formatted as f2fs with no issues.

One note about the flashing process, though - unless you have a custom update-binary that formats a partition based on it's current file system rather than whatever file system is specified in the format() command, you may end up overriding the user's format with whatever you specify.