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

Krait Laravel Package

mtrdesign/krait

Krait is a Laravel package from mtrdesign that provides lightweight, framework-native utilities and reusable components to reduce boilerplate and streamline common backend development tasks, helping teams build PHP applications faster with a simple, Laravel-friendly API.

View on GitHub
Deep Wiki
Context7

Getting Started

Krait is a small, opinionated package that pairs a Laravel endpoint with a Vue table component, so the fastest path is to get one server-side table rendering before touching styling or filters.

  1. Install both halves. Krait ships a Composer package and front-end assets/component. Expect something like:

    composer require mtrdesign/krait
    npm install krait   # or the published asset path documented in the README
    
  2. Publish config/assets if offered.

    php artisan vendor:publish --provider="Mtrdesign\Krait\KraitServiceProvider"
    

    Check config/krait.php (or similar) for route prefix, middleware, and default page length.

  3. Read these first, in order: the README usage example, the Vue component's props, and the backend request handler class in src/. The package is small (10 stars), so the source is the real documentation — confirm exact facade/method names there rather than trusting blog posts.

  4. Build one endpoint + one component. A minimal working slice:

    // routes/web.php
    Route::get('/users/table', [UserTableController::class, 'data'])
        ->middleware('auth');
    
    // app/Http/Controllers/UserTableController.php
    public function data()
    {
        return Krait::table(User::query())          // verify facade name in src/
            ->columns([
                ['data' => 'id',    'name' => 'id',    'orderable' => true],
                ['data' => 'name',  'name' => 'name'],
                ['data' => 'email', 'name' => 'email'],
            ]);
    }
    
    <!-- resources/js/pages/users/Index.vue -->
    <template>
      <krait-table url="/users/table" :columns="columns" />
    </template>
    
  5. First real use case: an admin listing page (users, orders, logs) with server-side pagination, global search, and sortable columns. That is exactly the workload Krait targets — if your table fits in memory, plain Vue + v-for is simpler.

Verify the response shape early: DataTables clients expect { draw, recordsTotal, recordsFiltered, data }. If the endpoint returns that, the component will work; if not, inspect src/ for the serializer.

Implementation Patterns

One controller method per table. Keep query construction in the controller (or a dedicated UserTable class) and treat the Krait call as the boundary between HTTP and SQL. This makes it easy to reuse the same query for CSV export later.

Whitelist columns explicitly. Define columns as a literal array, and use name for the database column while data is the JSON key. Never accept order[0][column] or search values and splice them into SQL yourself — let the package map indices back to your declared list.

Scope before you hand off. Authorization and tenancy belong in the query, not the Vue side:

$query = Order::query()->where('tenant_id', auth()->user()->tenant_id);
return Krait::table($query)->columns($this->columns());

Eager load anything rendered. If a column reads user.name or an accessor that touches a relation, add ->with('user') to the base query. DataTables will request 10–50 rows per page, and an N+1 there is immediately visible in query logs.

Custom cells via scoped slots. Use the component's slot API for action buttons, status badges, and links:

<krait-table url="/orders/table" :columns="columns">
  <template #actions="{ row }">
    <a :href="`/orders/${row.id}`">View</a>
  </template>
</krait-table>

For backend-rendered HTML, keep a tight allowlist of tags; raw HTML columns plus unescaped user input is the classic DataTables XSS bug.

Extra filters as query params. Pass filter state from Vue through the component's ajax/params option (or an axios interceptor), then read it in the controller with $request->input('status') and apply ->when(...). This keeps filtering server-side and survives pagination.

Wrap the component once. Create AppDataTable.vue that sets your defaults — page length, language strings, loading state, error toast on failed request — and use that everywhere. When Krait is upgraded or replaced, you change one file.

Reuse the definition for exports. Extract columns() and baseQuery() into a small class; the Krait controller and a CSV/Excel endpoint then share one source of truth.

Gotchas and Tips

  • Small-package risk. With ~10 stars, expect sparse docs and slow issue response. Pin the version in composer.json, read the changelog before upgrading, and budget for the possibility of forking. Vendor the Vue component if you need stability.
  • Vue 2 vs Vue 3. Older Laravel/Vue table packages often assume Vue 2 or a specific build setup. Confirm compatibility with your vue version and with Vite vs Laravel Mix before wiring it into a real page — asset publishing is the most common first failure.
  • Server-side means server-side. If you pass a plain array or get() instead of a query, you lose pagination and search. The whole point is that Krait runs count(), offset(), and limit() for you.
  • Sorting on computed/accessor columns usually needs a real database column or a custom order handler. A column that displays full_name but has no name mapping will silently fall back or error on sort.
  • Search across relations behaves the same way: LIKE against the base table won't match joined data unless you add the join or a custom filter.
  • CSRF and verbs. If your endpoint is POST, include the CSRF token in the ajax headers. A 419 in the network tab is the usual culprit when the table stays empty.
  • Response contract debugging. In the browser devtools, check that the JSON has draw, recordsTotal, recordsFiltered, and data. If recordsFiltered is missing, pagination controls will misbehave even though rows render.
  • Date/time and money formatting — do it in the front end or via an accessor, and pick one timezone. Mixing UTC storage with local rendering produces off-by-one-day bugs in filters.
  • Debugging SQL. Log the generated query (DB::listen, Telescope, or ->toSql() on the base query) to catch missing where clauses from tenant scoping and to spot N+1s.
  • Extension points to favor: published config, the column definition array, and the Vue wrapper component. Avoid editing files in vendor/; if you need behavior changes, subclass the controller/table class or fork the component.
  • Test the endpoint, not the UI. A feature test hitting /users/table with a draw/start/length payload catches authorization leaks and response-shape regressions far faster than clicking through the table.
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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource