Skip to content

How to Reduce Binary Size

Taner Sener edited this page Jul 15, 2026 · 2 revisions

The size of an FFmpegKitNext binary is mainly controlled by four things:

  1. Architectures or slices built into the artifact
  2. Optional external libraries enabled
  3. FFmpeg components enabled
  4. Debug, speed and packaging options

FFmpegKitNext already builds for size by default: optional external libraries are disabled unless requested, FFmpeg programs and documentation are disabled, --enable-small is used, and release builds strip debug information.

The examples below use Nix wrappers. If you manage the host SDK/toolchain yourself, pass the same build options to the matching scripts/start-<target>.sh script.

Build fewer architectures

Only build the ABIs or slices your application actually ships.

For example, an Android app that only ships arm64-v8a can disable the other Android ABIs:

./nix-android.sh -p android-r27d \
  --disable-arm-v7a \
  --disable-arm-v7a-neon \
  --disable-x86 \
  --disable-x86-64

For Apple platforms, use the matching platform script and disable simulator, Mac Catalyst or extra CPU slices you do not need. Run --help on the script you use to see the exact architecture names.

Enable fewer external libraries

Do not use --full unless you really need most external libraries. Start from the default build and add only the libraries required by your commands.

./nix-android.sh -p android-r27d --enable-libwebp

If you start from --full, remove unused libraries with --disable-lib-LIBRARY.

./nix-android.sh -p android-r27d --full --disable-lib-tesseract --disable-lib-libjxl

Use the same rule for GPL libraries: enable --enable-gpl and GPL libraries only when your application needs them.

Keep size-oriented defaults

Avoid these options when size is the priority:

  • --speed: optimizes for speed instead of size.
  • --debug: keeps debug information and disables stripping.
  • --no-link-time-optimization: disables LTO on platforms that support it.
  • --prefab: adds Android Prefab metadata to the AAR for native/CMake consumers.

If you do not use ffkitmem:, ffkitstream: or Android SAF protocol support, you can also pass --no-ffmpeg-kit-protocols for a smaller native build.

Disable unused FFmpeg components

For the smallest binaries, reduce the FFmpeg component set itself. Edit the platform ffmpeg.sh script you build with:

  • Android: scripts/android/ffmpeg.sh
  • Apple platforms: scripts/apple/ffmpeg.sh
  • Linux: scripts/linux/ffmpeg.sh

Add FFmpeg configure flags near the existing configure command, before ${CONFIGURE_POSTFIX}. A common pattern is to disable everything and enable only the codecs, formats, protocols and filters your commands require.

For example, a build that reads image files and creates an MPEG-4 video can start with:

  --disable-everything \
  --enable-protocol=file \
  --enable-demuxer=image2 \
  --enable-decoder=bmp,jpeg2000,jpegls,mjpeg,mjpegb,smvjpeg \
  --enable-muxer=mp4 \
  --enable-encoder=mpeg4 \
  --enable-filter=scale,format,null \

Treat this as a starting point. Test every command your app runs and add back the missing parser, demuxer, muxer, encoder, decoder, filter, protocol or bitstream filter reported by FFmpeg.

Flutter and React Native

Flutter and React Native packages use the native artifacts you build locally. To reduce their size, rebuild the native Android, iOS or macOS artifacts with the smaller configuration, then run the plugin's copy_local_binaries.sh again.

For final Android app size, also restrict packaged ABIs in the consuming app if you do not ship every ABI contained in the local AAR.

Clone this wiki locally