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

Charaza Ui Laravel Package

savannabits/charaza-ui

Charaza UI by SavannaBits is a Laravel package offering reusable Blade UI components and styling helpers, helping developers build consistent web interfaces and admin panels faster with less custom markup and repetition.

View on GitHub
Deep Wiki
Context7

Getting Started

Step 0 — Identify what you actually adopted. The repo is described three incompatible ways: a "Laravel 7 Scaffold … Admin CRUD generator" (metadata), a "Tailwind Blade component library" (description), and a scaffold that "re-branded to charaza" in v3.1.0. You cannot plan day-to-day work until you know which artifact is in front of you. Five minutes of inspection resolves it:

git clone https://github.com/savannabits/charaza-ui && cd charaza-ui
cat composer.json                     # "type": "project" vs "library"; framework constraint
ls resources/views                    # components/, layouts/, vendor targets
ls -R stubs 2>/dev/null               # generator templates, if they exist
grep -rn "savannabits\|charaza" config src resources routes composer.json

If "type": "project", the correct move is fork and build on top of it, not composer require. If it is genuinely a library, you will publish views/config and compose components. The distinction is the whole risk profile: one means you own the codebase, the other means you hold a dependency.

Step 1 — First boot (scaffold path). v3.1.0 added an app-exec wrapper around docker-compose, and moved the web server inside the app container (nginx → Apache2). Use the wrapper, not raw compose:

cp .env.example .env
./app-exec up -d
./app-exec artisan key:generate
./app-exec artisan migrate --seed
./app-exec artisan storage:link

Find the mapped port in docker-compose.yml. Do not assume the old nginx port — the container topology changed.

Step 2 — Where to look first. The generator's conventions are the package's contract, and they are documented nowhere else. Before touching your real domain, read the generated artifacts:

ls resources/views/components          # available Blade components
sed -n '1,60p' resources/views/components/button.blade.php   # props/slots/attribute merging
ls stubs 2>/dev/null                   # CRUD generator templates

Step 3 — First use case: one throwaway CRUD. Pick a disposable model (Post) and run the generator end-to-end. Read every emitted file — controller, form request, Blade views, routes — before you trust the pattern. This is your one clean value case: list/detail/edit screens over a handful of models with auth and profile plumbing already wired.

Step 4 — Then the Blade layer. Render one component in a view and confirm output before standardizing on the kit. If it renders unstyled, jump immediately to the Tailwind content-scanning gotcha below.

Implementation Patterns

Compose shipped components; don't copy markup. The Tailwind Blade components are the vocabulary of your admin UI. Always forward $attributes so call sites can add spacing, ids, and event handlers without editing the component:

{{-- pattern to verify against the shipped component --}}
@props(['variant' => 'primary'])
<button {{ $attributes->merge(['class' => "btn btn-{$variant}"]) }}>
    {{ $slot }}
</button>
<x-button variant="danger" type="submit" class="w-full">Delete</x-button>

Wrap form fields once, not per screen. The scaffold's compounding value is validation-error display. Build your own field wrapper so old() and @error live in one place:

{{-- resources/views/components/field.blade.php --}}
@props(['name', 'label' => null])
<label for="{{ $name }}" class="block text-sm font-medium">{{ $label ?? str($name)->headline() }}</label>
<input id="{{ $name }}" name="{{ $name }}"
       {{ $attributes->merge(['class' => 'mt-1 block w-full rounded border-gray-300']) }}
       value="{{ old($name, $attributes->get('value')) }}">
@error($name)<p class="mt-1 text-sm text-red-600">{{ $message }}</p>@enderror

Layouts first, views second. Pick one layout from resources/views/layouts/* and route every new admin screen through it. The moment you copy a sidebar or nav block into a second page, convert it to a component — that copy is exactly the cost the kit exists to eliminate.

Override by publishing, never by editing vendor. For a library-style install:

php artisan vendor:publish --list                 # confirm the actual tag name first
php artisan vendor:publish --tag=charaza-views

Edit only resources/views/vendor/charaza-ui/.... Keep a short docs/ui-overrides.md listing every vendor view you touched — an upgrade becomes a re-publish, not a diff review.

CRUD generator cadence (the day-to-day workflow). Treat the generator as a first draft with a fixed review loop:

  1. Write the migration, model, and factory by hand — generators are poor at domain decisions.
  2. Run the generator against the finished model.
  3. Review pass every time: authorization ($this->authorize / policies), validation extracted into a FormRequest, $fillable / $casts, pagination, eager loading.
  4. Only then wire routes.

With no release since 2020-11-20, you are the maintainer of every generated line. Generated code never reaches main unread.

Adding a user/profile field touches four places. v3.1.0 "edited profile update fields to match the user fields." Miss one and validation silently drops the value:

  1. Migration.
  2. $fillable on User.
  3. The Livewire component's $state / rules.
  4. The Blade form.

Locate the component before editing anything:

grep -rn "profile" resources/views resources/js app/ --include=*.php --include=*.blade.php

Verify with a real form submit — fillable omissions fail silently and look like a UI bug.

Standardize on app-exec for all artisan/composer/npm work. Teammates should never memorize compose invocations:

./app-exec artisan make:model Invoice -mf
./app-exec composer require ...
./app-exec npm run dev

Add project aliases (test, fresh) on top of app-exec rather than introducing a second wrapper.

Tailwind must scan the package's views. If components render styled in npm run dev but unstyled in production, it is content scanning, not a broken component:

// tailwind.config.js
content: [
  './resources/**/*.blade.php',
  './vendor/savannabits/charaza-ui/resources/views/**/*.blade.php',
]

Gotchas and Tips

Re-brand residue is your most likely first-day bug. v3.1.0 re-branded to charaza. Stale names surface as "view not found" or "class not found" errors that look unrelated to a rename. Grep before trusting anything:

grep -rn "savannabits" config app resources database routes composer.json
grep -rn "charaza" config app resources routes

Check config keys, view namespaces, asset paths, mail view names, and the package name together.

Do not install into a modern Laravel app. The constraint pins Laravel 7/8, both past security support. On Laravel 10/11 you will either get a hard resolution failure (the cheap, correct answer) or an unpatched framework. If you only want the components, copy the Blade files into your app and own them — drop the dependency entirely.

Pin the commit, not the version. ^3.1.0 means nothing with no releases since 2020-11-20 and no semver contract. Pin an exact tag or commit hash in composer.json, or vendor the code into the repo so an upstream deletion cannot break your build.

Removed DB init data breaks onboarding. v3.1.0 "removed unnecessary data from the database init file." Seeders and tests written against the old data will now fail or produce empty states. Make seeders explicit and idempotent, and assert row counts in tests so this class of breakage is loud.

Apache-in-app-container invalidates ops muscle memory. Verify: document root is public/, mod_rewrite is enabled, .htaccess is honored (AllowOverride), storage/ and bootstrap/cache are writable by the Apache user, and the exposed port matches your assumptions. If your infra expects nginx, you get 404s on pretty URLs or 500s on storage writes. Log paths moved too — find them in the Dockerfile before hunting /var/log/nginx.

"Blade component not found" — debug in this order:

  1. php artisan view:clear.
  2. Is it an anonymous component in resources/views/components/, or a class component needing registration?
  3. Is the view namespace prefix right for the package-vs-app path?
  4. Is there a name collision with a Jetstream component of the same name? Namespace or rename yours.

Vendor overrides not appearing is almost always cached compiled views or a wrong publish tag. Run php artisan view:clear && php artisan optimize:clear before debugging anything else.

Livewire/Alpine drift. The scaffold uses Livewire 2-era conventions. Dropping Livewire 3 in will break component syntax and asset injection. Keep the pinned versions; treat an upgrade as a migration project, not a version bump.

EOL is a day-to-day tax. You will hand-patch framework-level CVEs and composer audit will report issues you cannot fix without a framework upgrade. Scope the package to internal admin screens only, keep it out of customer-facing or audit-scoped surfaces, and record a written EOL acceptance with a target upgrade date.

Extension points, in escalating order of safety:

  1. Publish config.
  2. Publish and override views.
  3. Wrap components in your own app-level resources/views/components layer.
  4. Edit vendor code — and if you do, fork it, because merging upstream is not realistically happening.

Step 3 is your cheapest insurance: your call sites stay valid even if you rip the package out later.

Check licensing before vendoring. The re-brand arrived with no visible license or attribution statement in the release notes. Confirm a license file exists before you fork, commit, and redistribute it internally.

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.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource