BytCrush

Developer reference

Code lives under the BytCrush\ namespace in includes/. The prefix for options, meta keys and hooks is bytcrush_. The REST namespace is bytcrush/v1.

Filters

bytcrush_skip_auto_optimize

Skip automatic optimization for a specific upload. The image stays pending and can still be optimized by a bulk run or by hand.

add_filter( 'bytcrush_skip_auto_optimize', function ( $skip, $attachment_id ) {
	// e.g. leave uploads to a "Print files" folder alone.
	$file = get_attached_file( $attachment_id );
	return $skip || false !== strpos( (string) $file, '/print/' );
}, 10, 2 );

bytcrush_mimes

The attachment mime types BytCrush works on. Default: image/jpeg, image/png, image/webp, image/gif. The engine can only process these four, so this is mainly useful for removing one.

add_filter( 'bytcrush_mimes', function ( $mimes ) {
	return array_diff( $mimes, array( 'image/gif' ) ); // never touch GIFs.
} );

bytcrush_levels

The compression presets shown on the Settings screen, keyed by slug. Each preset is an array:

Key Type Meaning
label string Card title
hint string Card description
jpeg int JPEG quality, 1–100
webp int WebP quality, 1–100
avif int AVIF quality (added by BytCrush at priority 10 when missing)
subsample bool 4:2:0 chroma subsampling for JPEG
png_lossy bool Palette PNGs (honoured by the Ultra module, Imagick only)
lossless bool Lossless WebP copies of PNGs
pro bool Locked without Pro
add_filter( 'bytcrush_levels', function ( $levels ) {
	$levels['balanced']['jpeg'] = 76;
	return $levels;
} );

A saved level that no longer exists falls back to balanced.

bytcrush_sibling_formats

The next-gen copies created for one file. Only the webp and avif keys are used.

apply_filters( 'bytcrush_sibling_formats', $siblings, $settings, $level, $format );
// $siblings: array( 'webp' => array( 'quality' => 80, 'lossless' => false, 'sources' => array( 'jpeg', 'png', 'gif' ) ) )
// $format:   format of the file being processed: jpeg | png | webp | gif

A copy is created only when the file's format is in that entry's sources. Removing an entry deletes that copy from the file the next time it's processed.

// No WebP copies for PNGs.
add_filter( 'bytcrush_sibling_formats', function ( $siblings, $settings, $level, $format ) {
	if ( 'png' === $format ) {
		unset( $siblings['webp'] );
	}
	return $siblings;
}, 10, 4 );

bytcrush_served_formats

The formats delivered to browsers, best first (array( 'avif', 'webp' ) when both are on). Used by picture tags and by the rewrite rules.

apply_filters( 'bytcrush_served_formats', $formats, $settings );

The rewrite rules are written when settings are saved, so save the Settings screen once after changing this filter.

bytcrush_driver

Force the image library: 'imagick' or 'gd'. Empty (the default) means Imagick when available, otherwise GD. Only 'gd' changes anything in practice, since Imagick is already preferred.

add_filter( 'bytcrush_driver', function () {
	return 'gd';
} );

bytcrush_encoded

Post-process an encode. Pro's Smart target file size uses it to re-encode until the file fits. The callback must return the same shape.

apply_filters( 'bytcrush_encoded', $encoded, $driver, $format, $flags, $options );
// $encoded: array( 'blob' => string, 'quality' => int, 'resized' => bool )
// $driver:  BytCrush\Engine\Driver\Driver (may be resized by the callback)
// $format:  jpeg | png | webp | avif
// $flags:   array( 'subsample' => bool, 'png_lossy' => bool, 'lossless' => bool )
// $options: the compress options, including 'target_bytes' and 'min_width'

bytcrush_img_tag

Filter each <img> tag of a front-end page. The page is buffered and processed once; <img> tags inside <picture>, <noscript>, <script>, <style>, <textarea> and HTML comments are skipped. Picture delivery hooks in at priority 20 (Pro's page fixes at 5). The page is only buffered when at least one callback is attached.

add_filter( 'bytcrush_img_tag', function ( $tag, $index ) {
	// $index: 0-based position among the page's images.
	return 0 === $index ? str_replace( '<img ', '<img fetchpriority="high" ', $tag ) : $tag;
}, 10, 2 );

bytcrush_picture_enabled

Return false to skip <picture> wrapping for the current request.

add_filter( 'bytcrush_picture_enabled', function ( $enabled ) {
	return $enabled && ! is_page( 'gallery' );
} );

bytcrush_buffer_enabled

Return false to turn off all of BytCrush's HTML processing for the current request (picture tags and Pro page fixes).

bytcrush_bulk_time_budget

Seconds one bulk request keeps processing images before it returns. Default 20. Applies to the dashboard runner, background batches and Restore all. Lower it on hosts with a short PHP time limit.

add_filter( 'bytcrush_bulk_time_budget', function () {
	return 10;
} );

bytcrush_bg_dispatch_url

The URL the server calls to start the next background batch. Default: admin_url( 'admin-ajax.php?action=bytcrush_bg' ). Change it when the site can't reach itself on its public address, for example behind a proxy. The request is a non-blocking POST carrying the run's random token; the handler answers 403 without a valid one.

apply_filters( 'bytcrush_bg_dispatch_url', $url );

The request is sent with WordPress's https_local_ssl_verify filter value for certificate checks.

Actions

Action Arguments Fires when
bytcrush_optimized $attachment_id, $result BytCrush has run its pipeline on an image. $result has status (optimized, error or skipped), message, and for successes before, after and served byte totals.
bytcrush_restored $attachment_id, $restored (number of files put back) An image's originals were restored.
bytcrush_settings_saved $new, $previous Settings were saved. BytCrush uses it to rewrite the .htaccess rules.
bytcrush_imagick_png $image (Imagick), $flags Just before a PNG is encoded with Imagick.
bytcrush_fs_loaded none The Freemius SDK (or the built-in stub) is ready.
add_action( 'bytcrush_optimized', function ( $id, $result ) {
	if ( 'error' === $result['status'] ) {
		error_log( "BytCrush could not optimize #{$id}: {$result['message']}" );
	}
}, 10, 2 );

Functions

Function Returns
bytcrush_settings() The effective settings array (stored values over defaults, with Pro-only options off when Pro isn't active).
bytcrush_format_bytes( $bytes ) A human-readable size, such as 1.4 MB.
bytcrush_percent( $before, $after ) The reduction as a percentage, 0–100, one decimal.

Settings keys: level, auto_optimize, backup, strip_metadata, resize, max_width, max_height, webp, avif, delivery (picture, rewrite or off), target_size, target_kb, background, fix_srcset, fix_dimensions, fix_lazy, remove_data. Defaults are listed in the Settings reference.

REST API

All routes are under /wp-json/bytcrush/v1/ and need a logged-in user with a REST nonce, as the admin screens use them.

Route Method Permission Does
/stats GET manage_options Library totals and recent failures
/settings GET, POST manage_options Read or save settings (POST takes a JSON object of keys to change)
/bulk/start POST manage_options Checks folders and recovers interrupted images before a run
/bulk/run POST manage_options Processes pending images for one time budget
/bulk/retry POST manage_options Puts every failed image back in the queue
/bulk/restore POST manage_options Restores originals for one time budget
/background, /background/start, /background/stop, /background/tick GET / POST manage_options Status, start, stop and a browser-driven batch of the background run
/image/{id}/optimize POST upload_files and edit_post on that image Optimizes one image. force: true restores the original first.
/image/{id}/restore POST upload_files and edit_post on that image Restores one image

Pro adds /audit/analyze, /audit/fix and /audit/fixes (manage_options).

Data the plugin stores

What Name
Settings option bytcrush_settings
Version option bytcrush_version
Backup folder name option bytcrush_backup_dirname
Background run options bytcrush_bg_run, bytcrush_bg_state; scheduled event bytcrush_bg_cron (every minute, only while a run is active)
Cached totals transients bytcrush_stats, bytcrush_backup_size; option bytcrush_stats_flushed
Per-image locks options _bytcrush_lock_{id} (removed when the image is done)
Per-image results post meta _bytcrush, _bytcrush_status, _bytcrush_before, _bytcrush_after, _bytcrush_served
Dismissed notice user meta bytcrush_notice_dismissed
Page audit (Pro) options bytcrush_audit_history, bytcrush_lcp_pages, bytcrush_sized_pages, bytcrush_has_page_fixes

_bytcrush_status is optimized, skipped, error or processing. An image without it is pending.

Deleting _bytcrush_status (and the other _bytcrush* meta) for an image puts it back in the queue without touching its files.

Code map

Folder Contents
includes/Engine/ Optimizer (per-image pipeline and restore), Compressor (single-file encoder), Backup, Background, Stats, Avif, Driver/ (Imagick and GD)
includes/Delivery/ Buffer (front-end HTML processing), Picture, Rewrite (.htaccess rules)
includes/Core/ Plugin, Settings, Hooks (upload and delete hooks), Activator, Uninstaller, Lock
includes/Admin/ Admin (screens), MediaColumn
includes/Rest/ Controller
includes/Freemius/ Gate (plan checks), Stub
includes/Pro/ Premium-only modules: Audit, Fixer, Ultra, TargetSize, Media. Not included in the free build.
views/ Admin screen templates