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

Vesper Laravel Package

suraj-kashyap-dev/vesper

Vesper is a Laravel/PHP package from suraj-kashyap-dev that offers a lightweight, developer-friendly way to integrate its functionality into your application. It emphasizes simple setup, clean Laravel integration, and maintainable code for faster feature delivery.

View on GitHub
Deep Wiki
Context7

Getting Started

Vesper v2 themes a Filament panel without publishing config. Three steps:

  1. Install

    composer require suraj-kashyap-dev/vesper:^2.0
    
  2. Register the plugin on your panel (in the PanelProvider's panel() method), instead of touching a config file:

    use Kashyap\Vesper\Enums\ThemePreset;
    use Kashyap\Vesper\VesperPlugin;
    
    $panel->plugin(
        VesperPlugin::make()
            ->preset(ThemePreset::Sunset)
            ->branding(name: 'Acme', eyebrow: 'Acme Admin', mark: 'AC'),
    );
    
  3. Run your normal asset/build step (php artisan filament:assets / npm run build) and load any panel page.

Where to look first:

  • Kashyap\Vesper\VesperPlugin — the single entry point; every fluent method (preset, branding, header, sidebar, fonts, colors, tokens, layout, themeId, themeAsset, registerPreset) is documented by its signature here.
  • src/Theme — the shipped presets and token definitions. Read AbstractPreset and the Preset contract before customising anything; this is where the old config/vesper/presets/*.php content now lives.
  • PresetRepository, StructuralTokens, ThemeDefaults — the resolution chain. Understanding these explains what your fluent calls actually override.

First use case: pick a built-in preset, set your brand name/mark, and ship. That's it — no 520-line config file, no vendored presets to keep in sync.

Coming from 1.x: keep your existing config/vesper.php; it still works as a fallback. Then delete the presets and tokens keys — they are ignored in favour of the package's built-in data — and move the remaining settings onto the plugin at your own pace.

Implementation Patterns

Panel baseline. Treat the plugin call as the panel's single theming block; keep it near the top of panel() so it's the first thing a reviewer reads:

$panel
    ->id('admin')
    ->plugin(
        VesperPlugin::make()
            ->preset(ThemePreset::Emerald)
            ->branding(name: config('app.name'), eyebrow: 'Admin', mark: 'AC')
            ->header(helpUrl: 'https://example.com/docs', showHelpUrl: true)
            ->sidebar(overviewLabel: 'Overview', userRole: 'Owner')
    );

Custom presets as classes. Extend AbstractPreset, implement the Preset contract, and register it before selecting it:

VesperPlugin::make()
    ->registerPreset(new AcmePreset())
    ->preset(new AcmePreset()); // or however your instance is resolved

Keep custom presets in app/Filament/Theme/ so they're autoloaded and testable like any other class. This is the biggest day-to-day win over 1.x: design tokens are now PHP you can unit-test, not arrays in a published config.

Layering. Think of configuration as a stack: package defaults → preset → individual fluent calls (colors(), tokens(), layout(), fonts()) → optional config/vesper.php fallback beneath. Use preset() for the broad strokes and colors()/tokens() for the handful of CSS variables your brand actually needs:

->colors(['primary' => 'teal'])
->tokens(['shared' => ['vs-control-radius' => '999px']])

Don't copy a whole preset into tokens() just to change one radius — override the leaf only.

Reading theme data in views. Blade overrides and TopbarNavigation now read the active plugin, and so should yours:

@php($vesper = \Kashyap\Vesper\VesperPlugin::current())
{{ $vesper?->branding->name ?? config('app.name') }}

Always null-safe: current() returns null outside a panel/plugin context (mailables, error pages, artisan-rendered views).

Multi-panel setups. VesperPlugin::current() resolves via the active panel, so give each panel its own plugin instance — e.g. a marketing-ish app panel with a light preset and a dense admin panel with layout() tweaks. Anything shared (branding name, help URL) should come from config() so it isn't duplicated per provider.

Gradual migration. For a large 1.x app, migrate one panel per PR: add the plugin, verify visuals against the old config, then delete the corresponding keys from config/vesper.php. Because the config is a fallback, a half-migrated state is coherent rather than broken — but only if you don't duplicate the same setting in both places, which makes it ambiguous which one is winning.

Bespoke themes. themeId() and themeAsset() let you point at your own compiled asset instead of a package preset — useful when a designer hands you a CSS bundle and you still want the plugin's structural tokens and layout plumbing.

Gotchas and Tips

  • The breaking change is quiet, not loud. config/vesper/presets/*.php and config/vesper/tokens.php no longer exist in the package. If you published them in 1.x, they're now dead files on disk being ignored. Delete them rather than leaving them in config/ where the next developer will assume they matter.
  • Fluent beats config, silently. A leftover 'preset' => 'emerald' in config/vesper.php plus ->preset(ThemePreset::Sunset) on the plugin won't warn you — the plugin wins. When a theme "isn't applying", check for stale config keys before you check the plugin.
  • preset() type mismatch is the likely first error. The docs show ThemePreset::Sunset; 1.x configs used strings like 'emerald'. Don't mix them — if a preset name is rejected, inspect the enum cases in src/Enums/ThemePreset.php rather than guessing.
  • Named arguments must match the source exactly. branding(name:, eyebrow:, mark:), header(helpUrl:, showHelpUrl:), sidebar(overviewLabel:, userRole:). These signatures are the API; a rename in a patch release would break you, so if you're wrapping Vesper in your own helper class, pin the constraint (^2.0) and keep a smoke test that renders a panel.
  • showHelpUrl is independent of helpUrl. Setting a URL does not imply the link shows. If the help link vanished after upgrading, that's the config key show_help_url default or an explicit false — not a missing URL.
  • Custom Blade that reads config('vesper.*') is now stale. The package's own overrides moved to the plugin; yours didn't. Grep your resources/views for config('vesper and swap to VesperPlugin::current() with null-safe access.
  • Null-safety on current(). Outside panel rendering it's null. Use ?-> everywhere; a stray direct property access will only fail in the mailer or the error page, which is exactly where you don't want a new exception.
  • Assets need a rebuild after the upgrade. Presets and tokens moved into src/Theme, so the generated CSS changed even if your settings didn't. If colours look half-applied or tokens look stale, re-run the Filament asset publish and your front-end build, then hard-refresh.
  • Debugging the resolved theme: the fastest check is a temporary dump(VesperPlugin::current()) inside a panel view or a TopbarNavigation override — it shows exactly which preset, branding, and tokens survived the chain. Delete it before committing.
  • Extension points to prefer: AbstractPreset for whole themes, tokens() for per-project CSS variable overrides. Reaching into PresetRepository directly is possible but couples you to internals that just changed significantly between 1.x and 2.0 — don't.
  • Watch the 2.x patch line for signature churn. This release moved a lot of surface area into a fluent API. Treat the plugin call in your PanelProvider as public API: one place, reviewable, with a test that boots the panel.
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.
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels