Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Imagekit Bundle Laravel Package

geekcell/imagekit-bundle

GeekCell ImageKit Bundle provides Symfony integration for ImageKit.io, with dependency-injection configuration and helpers for uploading, transforming, and delivering optimized images via ImageKit’s CDN. It simplifies service setup for media workflows in PHP applications.

View on GitHub
Deep Wiki
Context7

Getting Started

Read this first: it is a Symfony bundle, not a Laravel package. geekcell/imagekit-bundle ships a Bundle subclass plus a DI extension and services.yaml, so composer require will install fine but Laravel has no bundles.php and will never boot it. There is no service provider, no facade, no config publish. In a Laravel codebase you would get zero runtime behaviour out of this package.

Given that, plus 0 stars, 0 dependents, an archived repository and a last release of 2023-07-21, the correct day-to-day move is:

  1. Do not install the bundle. Install the underlying official SDK instead: composer require imagekit/imagekit. Everything the bundle does is a thin wrapping of that client.
  2. Treat the bundle as a reference implementation. Skim it on GitHub for two things only: the config key names it chose (public key / private key / URL endpoint) and whether it wrapped anything beyond the raw SDK (a Twig extension, a URL builder). Those are the only ideas worth copying.
  3. Where to look in the repo, in order: composer.json (Symfony version constraints — this tells you immediately how stale it is), src/DependencyInjection/*Extension.php (the actual config tree), Resources/config/services.yaml (what gets registered and under which service id), and any Twig/ directory (the only part with reusable logic).

The first use case you actually want in Laravel is almost always this one:

// config/imagekit.php  (your own file, not the bundle's)
return [
    'public_key'   => env('IMAGEKIT_PUBLIC_KEY'),
    'private_key'  => env('IMAGEKIT_PRIVATE_KEY'),
    'url_endpoint' => env('IMAGEKIT_URL_ENDPOINT'), // https://ik.imagekit.io/yourid
];
// app/Providers/ImageKitServiceProvider.php
public function register(): void
{
    $this->app->singleton(\Imagekit\Imagekit::class, fn () => new \Imagekit\Imagekit(
        config('imagekit.public_key'),
        config('imagekit.private_key'),
        config('imagekit.url_endpoint'),
    ));
}

Then generate a delivery URL:

app(\Imagekit\Imagekit::class)->url([
    'path'           => '/products/hero.jpg',
    'transformation' => [['width' => 800, 'quality' => 80, 'format' => 'auto']],
]);

That is 90% of real usage: building transformation URLs into Blade templates. Uploads and deletes are the remaining 10%.

Implementation Patterns

URL generation in views. The bundle's presumed value-add is a Twig function; the Laravel equivalent is a Blade directive or a small helper class. Prefer a dedicated ImageKitUrl class over a global helper so you can swap it, cache it, and mock it.

Blade::directive('ik', fn ($expr) => "<?php echo e(app(\App\Support\ImageKitUrl::class)->make($expr)); ?>");
// <img src="@ik(['/products/hero.jpg', ['width' => 400]])" alt="">

Upload as a queued job, not inline. Uploads are network I/O with variable latency. Put the SDK call in a ShouldQueue job, dispatch from an observer on model create/update, and store both file_id and url on the model. Never store only the URL — you cannot delete or update a file from a URL.

class UploadToImageKit implements ShouldQueue
{
    public int $tries = 3;
    public function __construct(public Product $product, public string $localPath) {}

    public function handle(\Imagekit\Imagekit $client): void
    {
        $result = $client->uploadFile(fopen($this->localPath, 'r'), [
            'fileName'   => basename($this->localPath),
            'folder'     => '/products',
            'useUniqueFileName' => true,
        ]);

        $this->product->update([
            'image_file_id' => $result->result->fileId,
            'image_url'     => $result->result->url,
        ]);
    }
}

Client-side uploads via authentication parameters. The private key must never leave the server. Expose only the signature payload from a small endpoint and let the browser POST directly to ImageKit — this keeps large files off your app server:

Route::get('/imagekit/auth', fn () => response()->json(
    app(\Imagekit\Imagekit::class)->getAuthenticationParameters()
));
// returns { token, expire, signature } — safe for the browser

Gate this route behind auth middleware and rate-limit it; a public signature endpoint lets anyone upload into your account.

Transformations belong in the URL, not at upload time. Upload the original at full quality and let w-, q-, f-auto do the work at delivery. This lets you change your responsive breakpoints later without re-processing a single asset.

Caching. The url() call is pure string concatenation — cheap, but if you render it in a loop over 50 products on every request, cache the resulting strings (Cache::remember("ik:{$path}:{$preset}", ...)) or memoise inside your wrapper. Also cache signed URLs slightly shorter than their expiry to avoid serving stale signatures at the boundary.

Local development and tests. The SDK makes real HTTP calls through its own transport, so Http::fake() will not intercept it. Bind a fake implementation of your own ImageKitUrl/uploader interface in testing/local:

$this->app->bind(ImageKitUrl::class, FakeImageKitUrl::class);

Otherwise your test suite will hit ImageKit, cost time, and flake.

Gotchas and Tips

  • The archived status is the headline. Last release July 2023 with 0 stars and no dependents means no security patches, no Symfony 7 compatibility work, and no one upstream to ask. If you are on Symfony 6.3+, expect the bundle's DI extension to break on typed TreeBuilder/ConfigurationInterface requirements. Pin it exactly if you insist on using it, and plan to fork.
  • It cannot be used from Laravel at all. Symfony\Component\HttpKernel\Bundle\Bundle has no Laravel analogue. Any tutorial that says "install this bundle and add it to config/app.php" is wrong. Use the raw SDK.
  • Private key leakage is the failure mode that matters. getAuthenticationParameters() output (token, expire, signature) is public-safe. private_key is not, and neither is calling uploadFile() from a browser context. Audit your JS bundle and any /api/config style debug endpoint.
  • URL endpoint formatting. The endpoint must be the bare origin (https://ik.imagekit.io/yourid) with no trailing slash. A trailing slash produces //path and silently 404s — ImageKit does not complain about malformed URLs, it just returns a broken image.
  • Transformation typos fail silently. widht-400 or qulity-80 is passed through verbatim and yields either the original image or a 400 on delivery. There is no client-side validation. Keep transformations in named constants or a preset map rather than string literals scattered across templates.
  • Path vs. query strings. Paths containing ? or # break the transformation URL construction. Sanitise or slugify filenames on upload — do not trust user-supplied names. useUniqueFileName: true also saves you from accidental overwrites.
  • Overwrites and CDN cache. If you overwrite a file at the same path, the CDN keeps serving the old bytes until purged. Either use unique filenames (preferred) or call purgeCache() and accept the propagation delay. Never assume an upload is immediately visible.
  • Bulk operations are slow, not paginated. Deleting or listing many files requires manual skip/limit loops; the SDK does not auto-page. Wrap bulk deletes in a job with a timeout well above the default.
  • Extension point if you do use the bundle: the registered client service id is aliased in services.yaml, so you can override it in services_prod.yaml with your own decorated implementation. For logging/auditing, a Symfony Decorator around the client is cleaner than editing the bundle — and that same decorator pattern ports to Laravel as a wrapper class.
  • Vendor lock-in check. ImageKit URLs are just CDN URLs; you are not storing proprietary metadata beyond fileId. Keep file_id and url in your own table and you can re-point at S3/CloudFront later with a single backfill job.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle