Your Guide to Laravel Excellence

Laravel Tailwind DataTable with Vanilla JS (No jQuery)

Laravel Tailwind DataTable with Vanilla JS (No jQuery)

If you’re building a Laravel application and using Tailwind CSS v4, you probably want your tables to look clean, modern, and fast. But adding features like search, sort, pagination, and CSV export can quickly become a headache — especially if you're trying to avoid jQuery or bloated plugins.

That’s where vanillajs-datatable comes in.

This zero-dependency JavaScript library helps you turn plain HTML tables into fully interactive Tailwind-styled DataTables — perfect for Laravel projects using Blade, Livewire, or Inertia.

Why vanillajs-datatable?

  • ✅ Works out of the box with Tailwind CSS v4
  • ✅ No jQuery or frontend framework needed
  • ✅ Integrates with Laravel Blade templates
  • ✅ Adds search, sorting, pagination, export features and many more
  • ✅ Fully customizable with Tailwind classes

Step-by-Step Installation (Copy-Paste)

Install

npm i vanillajs-datatable

Import once in resources/js/app.js

import DataTable from 'vanillajs-datatable';
window.DataTable = DataTable;

Tailwind purge safety (skip if using CDN)

/* resources/css/app.css */
@source '../../node_modules/vanillajs-datatable/dist/**/*.{js,mjs}';

Add a Table in Your Blade View

<div class="overflow-x-auto">
    <table id="userTable" class="min-w-full divide-y divide-gray-200">
		
        <!-- rows injected by JS -->
				
    </table>
</div>

Initialize the DataTable

const columns = [
  {
    name: "id",
    label: "ID",
    render: (value) => `#${value}`,
  },
  {
    name: "name",
    label: "Name",
    group: "personal",
    highlightable: true,
    render: (value) => `<strong>${value}</strong>`,
  },
  {
    name: "email",
    label: "Email",
  },
  {
    name: "created_at",
    label: "Created At",
    render: (val) => new Date(val).toLocaleDateString(),
  },
  {
    name: "actions",
    label: "Actions",
    render: (value, row) => {
      return `
        <button class="btn btn-sm py-2 px-3 rounded-lg bg-blue-600 hover:bg-blue-700 text-white mr-2"
          onclick="showDetails(${row.id})">
          Show
        </button>
        <button class="btn btn-sm py-2 px-3 rounded-lg bg-yellow-500 hover:bg-yellow-600 text-white"
          onclick="editRecord(${row.id})">
          Edit
        </button>
      `;
    },
  },
];
 
const table = new DataTable({
  tableId: "datatable",
  url: "/users/datatable",
  dataSrc: "users",
  columns: columns,
 
  columnGroups: columnGroups,
 
  exportable: {
    enabled: true,
    buttons: {
      print: true,
      excel: true,
      csv: true,
      pdf: true,
    },
    title: {
      print: "Leads Printable Report",
      pdf: "Leads PDF Export",
    },
    chunkSize: {
      print: 1000,
      pdf: 500,
      excel: 500,
      csv: 500,
    },
    fileName: {
      print: "leads_report",
      pdf: "leads_pdf",
      excel: "leads_excel",
      csv: "leads_csv",
    },
 
    pdfOptions: {
      orientation: "portrait", // or 'portrait'
      unit: "mm", // "pt" (points), "mm", "m", "px".
      format: "a4",
      theme: "grid", // 'striped', 'grid'
      watermark: {
        text: "test",
        opacity: 0.2,
        angle: 45,
      },
    },
    footer: true,
  },
 
  columnFiltering: true,
  filterableColumns: ["name", "email"],
 
  perPageSelector: true,
  perPageOptions: [10, 25, 50, 100],
 
  baseTheme: "daisyui", // "daisyui", "bootstrap", "tailwind"
 
  pagination: true,
  // paginationType: 'simple', // 'simple' (Previous/Next) or 'detailed' (numbered pagination)
 
  searchable: true,
  // searchDelay: 800, // Search delay in milliseconds
 
  sortable: true,
  // sortableColumns: ['id', 'name'],
 
  loading: {
    show: false,
    elementId: "custom-loading-spinner",
    delay: 1000,
  },
 
  selection: {
    enabled: false,
    mode: "single", // 'single'|'multiple'
    rowClass: "row-selected",
    backgroundClass: "bg-blue-100",
  },
 
  // saveState: true,
  // saveStateDuration: 60 * 60 * 1000, // 1 hour
 
  // theme: {
  //     table: "w-full border border-green-100 rounded-lg shadow-sm",
  //     header: "bg-green-600 text-white",
  //     headerCell: "px-4 py-3 font-medium text-white",
  //     row: "hover:bg-green-50",
  //     cell: "px-4 py-3 text-green-900",
  //     paginationButtonActive: "bg-green-600 text-white"
  // },
});

Controller

Create an API endpoint with proper validation and filtering:

 
use Illuminate\Http\Request;
use Illuminate\Support\Str;
 
public function index(Request $request)
{
    $request->validate([
        'search' => 'nullable|string|max:500',
        'sortBy' => 'nullable|string|in:id,name,email,created_at',
        'order' => 'nullable|string|in:asc,desc',
        'perPage' => 'nullable|integer|min:5|max:100',
    ]);
 
    $query = User::query();
 
    // Search functionality
    if ($searchTerm = $request->input('search')) {
        $query->where(function ($q) use ($searchTerm) {
            $q->where('name', 'like', "%{$searchTerm}%")
                ->orWhere('email', 'like', "%{$searchTerm}%");
        });
    }
 
    // Sorting
    $sortBy = $request->input('sortBy', 'id');
    $order = $request->input('order', 'desc');
    $query->orderBy($sortBy, $order);
 
    $perPage = $request->input('perPage', 10);
    $paginated = $query->paginate($perPage);
 
    return response()->json([
        'users' => $paginated->items(),
        'total' => $paginated->total(),
        'current_page' => $paginated->currentPage(),
        'last_page' => $paginated->lastPage(),
    ]);
}

📘 Visit full documentation: Docs

Output

vanillajs-datatable demo –  lightmood

vanillajs-datatable demo – darkmood

Recommeded Posts

Laravel DataTable Solution with Tailwind & Bootstrap Support

Laravel DataTable Solution with Tailwind & Bootstrap Support

Learn how to replace heavy jQuery DataTables with the lightweight, framework-agnostic vanillajs-datatable package—perfect for Laravel, Blade, and Tailwind CSS.

19 hours ago Read article →
Using Tailwind, Flowbite and Simple-DataTables in Laravel

Using Tailwind, Flowbite and Simple-DataTables in Laravel

Learn how to set up Tailwind CSS, Flowbite, and Simple-DataTables in a Laravel project. This easy guide shows you how to use Tailwind for styling, build responsive designs with Flowbite components, and add dynamic tables using Simple-DataTables

3 months ago Read article →