If you are a WordPress veteran, you surely remember TimThumb. It was a small PHP script found in almost every “premium theme” around 2010. It allowed for easy on-the-fly image cropping and resizing.
In 2011, a critical Zero-Day vulnerability was discovered in it, allowing hackers to compromise millions of sites. That marked the end of the “simple script” era.
Today, in 2026, WordPress has a powerful media handling engine. If you still see timthumb.php in your theme – delete it immediately. In this guide, I’ll show you how to do it professionally.
Why was TimThumb bad?
TimThumb worked “on the fly”: it took an image from a URL, processed it, and saved it in a cache. Problems:
- Security: Allowed Remote Code Execution (RCE) if not perfectly configured.
- Performance: Burdened the PHP server with every new image request.
- No Integration: Didn’t recognize the WordPress Media Library.
Method 1: Native sizes (add_image_size)
WordPress has had the add_image_size() function for years. It allows you to define formats that the system will generate automatically during file upload.
IN functions.php:
function wppoland_setup_theme() {
// Enable support for post thumbnails
add_theme_support( 'post-thumbnails' );
// Standard sizes (soft crop - maintains aspect ratio)
add_image_size( 'blog-list', 800, 400 );
// Hard Crop (cuts off excess)
// WordPress will crop exactly the center of the image
add_image_size( 'team-member', 300, 300, true );
// Crop with positioning (e.g., from top, from left)
add_image_size( 'hero-banner', 1920, 600, ['center', 'top'] );
}
add_action( 'after_setup_theme', 'wppoland_setup_theme' );
IN the template file (e.g., single.php):
if ( has_post_thumbnail() ) {
the_post_thumbnail( 'hero-banner', ['class' => 'img-fluid'] );
}
Advantage: Images are generated once (during upload). They are served as ready-made static files. Zero PHP load when displaying.
Method 2: On-the-fly generation
Native sizes have a downside: if you change your theme, you have to regenerate thumbnails (e.g., with the Regenerate Thumbnails plugin), which takes ages for a 100GB library.
In 2026, servers are fast and CDNs are cheap. We often use a hybrid approach or external services.
Solution: Cloudflare / CDN
Instead of burdening your PHP server, use URL parameters.
<img src="https://yoursite.com/wp-content/uploads/image.jpg?width=400&height=300&format=avif">
Most WordPress hosting in 2026 (Kinsta, WP Engine, Cloudways) offers this as standard. You don’t need a PHP script on your server!
Method 3: Srcset and sizes attributes
WordPress automatically generates the srcset attribute for your images, allowing the browser to choose the appropriate size for the device (phone vs desktop 4K).
<!-- WordPress generates this automatically: -->
<img src="image-800x400.jpg"
srcset="image-300x150.jpg 300w,
image-800x400.jpg 800w,
image-1024x512.jpg 1024w"
sizes="(max-width: 600px) 100vw, 800px">
Your job as a developer is only to correctly define sizes using the wp_calculate_image_sizes filter.
Optimization: WEBP and AVIF
In 2026, JPG and PNG are relics for photos. WordPress natively supports WebP (since version 5.8) and AVIF (since version 6.5).
You don’t need plugins. Just upload an AVIF file, and WordPress handles it. Or use a plugin (like Performance Lab) to automatically convert old JPGs to AVIF during upload.
Clean up (removing TimThumb)
If you inherited an old project:
- Scan: Search the
wp-contentdirectory fortimthumb.phporthumb.php. - Delete: Delete the file.
- Fix: Find where it was called in the code:
// OLD CODE (BAD) <img src="<?php echo get_template_directory_uri(); ?>/timthumb.php?src=..." /> // REPLACE WITH (GOOD) <?php the_post_thumbnail( 'my-size' ); ?> - Regenerate: Install
WP-CLIand runwp media regenerate.
Summary
The history of TimThumb is a lesson in humility. Convenience (on-the-fly scaling) cannot stand above security. we have native add_image_size(), responsive srcset, and CDNs processing images in the cloud. There is no reason to go back to solutions from 15 years ago.


