krystal-sf/ux-bootbox
A PHP UX package that integrates Bootbox.js, giving developers simple helpers for Bootstrap-styled alerts, confirmations, prompts, and modal dialogs. Keep frontend interactions consistent, accessible, and easy to wire into your app.
This is a Symfony UX bundle, not a Laravel package. Before writing any code, confirm that reality with composer show krystal-sf/ux-bootbox — you'll see symfony/ux-* in the requirements and no extra.laravel.providers. Laravel's package auto-discovery will find nothing to register, so the "install" step below is only useful if you're mining the source.
The honest day-to-day answer for a Laravel dev: don't composer require this. Open the GitLab repo, read three files, and rebuild the ~40 lines of glue yourself against your own stack. The whole package is a Stimulus controller wrapping Bootbox.
What to read first (10 minutes, in order):
composer.json — tells you the real dependency chain: which bootbox version, whether jquery is a hard require (Bootbox ≤5 does, 6.x doesn't), and whether a Flex recipe exists. This decides feasibility more than the package itself.assets/controllers.json — the Stimulus identifier you'd use in Twig (data-controller="..."). In Laravel this maps to Alpine or a small vanilla module instead.assets/controllers/*.js — one or two short files that are the documentation. They call bootbox.alert/confirm/prompt and marshal options. Copy the option shape; that's the value.Your first use case in Laravel is almost certainly destructive-action confirmation on a delete form — the one place a modal.confirm pays for itself immediately:
{{-- resources/views/components/confirm-delete.blade.php --}}
<form method="POST" action="{{ $action }}"
x-data @submit.prevent="
bootbox.confirm(@js($message ?? 'Delete this?'), ok => {
if (ok) $el.submit()
})">
@csrf @method('DELETE')
<button type="submit" class="btn btn-danger">{{ $label ?? 'Delete' }}</button>
</form>
Wire bootbox via Vite (npm i bootbox bootstrap), expose it on window, and you have everything this package provides — without the Symfony surface. If you do have a Symfony + Bootstrap app, composer require krystal-sf/ux-bootbox, bin/console assets:install, and use the registered Twig/Stimulus helpers directly.
The "wrapper, don't scatter" pattern. Expose exactly one interface — a Blade component or an Alpine directive — so a future replacement (Radix-style headless, Alpine x-modal, Livewire) is a single-file change. Do not sprinkle bootbox.confirm() calls across ten views; centralize:
// resources/js/dialogs.js — one public API
import bootbox from 'bootbox';
export const confirm = (message, opts = {}) => new Promise(resolve =>
bootbox.confirm({ message, ...opts, callback: resolve }));
export const alert = (message, opts = {}) => bootbox.alert({ message, ...opts });
export const prompt = (message, cb, opts = {}) => bootbox.prompt({ message, ...opts, callback: cb });
Programmatic invocation from server-rendered markup. This is the pattern the package is built around and it translates directly: a Blade/Alpine x-data binds a click to a dialog whose text comes from a data-* attribute or a translated @js() string. Keep the message server-side (i18n, entity names) and the behavior client-side.
Promise-based confirm → form submit. The one genuinely useful pattern: intercept submit, open a confirm dialog, and on true submit programmatically (not the original event), so you avoid double-fire. Bootbox's callback form is what the package's Stimulus controller marshals.
Integration tips:
DELETE route must still authorize. Don't let the dialog lull you into skipping $this->authorize().x-modal or a headless component. Bootbox markup assumes Bootstrap 4/5 classes; you'll fight it otherwise.import 'bootbox' in resources/js/app.js and you're at parity with the bundle's asset step.Migration mindset. If the goal is "adopt the idea, not the dependency": port the option-object shapes (title, message, buttons, callback) into your own component so feature parity is a checklist, then delete the fork.
composer require will succeed even if the repo is private/unlisted with a VCS entry, and Laravel will happily load the class files without ever registering anything — no error, no dialogs. The most common first failure, easily misdiagnosed as a config bug.Extension, config/bundles.php, Flex recipes, Twig namespace registration — none of it runs. You port Twig → Blade by hand.<dialog>). Check composer.json/npm ls jquery before committing.bootstrap is loaded once.aria-modal posture is dated. If accessibility is a requirement, build on a maintained headless primitive instead.How can I help you explore Laravel packages today?