diff --git a/src/Html/Builder.php b/src/Html/Builder.php
index 9172874..38fa0f7 100644
--- a/src/Html/Builder.php
+++ b/src/Html/Builder.php
@@ -46,6 +46,11 @@ class Builder
      */
     public Collection $collection;
 
+    /**
+     * @var Collection<int, Row>
+     */
+    public Collection $rows;
+
     /**
      * @var array<string, string|null>
      */
@@ -68,6 +73,7 @@ public function __construct(public Repository $config, public Factory $view, pub
         $defaults = $this->config->get('datatables-html.table', []);
 
         $this->collection = new Collection;
+        $this->rows = new Collection;
         $this->tableAttributes = $defaults;
     }
 
@@ -179,6 +185,18 @@ public function table(array $attributes = [], bool $drawFooter = false, bool $dr
         $tableHtml .= '<thead'.($this->theadClass ?? '').'>';
         $tableHtml .= '<tr>'.implode('', $th).'</tr>'.$searchHtml.'</thead>';
 
+        if ($this->attributes['serverSide'] === false) {
+            $tableHtml .= '<tbody>';
+            foreach ($this->getRows() as $row) {
+                $tableHtml .= '<tr>';
+                foreach ($this->getColumns() as $column) {
+                    $tableHtml .= '<td>'.$row->getCellContentForColumn($column).'</td>';
+                }
+                $tableHtml .= '</tr>';
+            }
+            $tableHtml .= '</tbody>';
+        }
+
         if ($drawFooter) {
             $tf = $this->compileTableFooter();
             $tableHtml .= '<tfoot><tr>'.implode('', $tf).'</tr></tfoot>';
diff --git a/src/Html/Cell.php b/src/Html/Cell.php
new file mode 100644
index 0000000..12e96e2
--- /dev/null
+++ b/src/Html/Cell.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace Yajra\DataTables\Html;
+
+use Illuminate\Support\Fluent;
+
+/**
+ * @property string $column
+ * @property string $content
+ */
+class Cell extends Fluent
+{
+    /**
+     * @param array $attributes
+     */
+    public function __construct(array $attributes = [])
+    {
+        $attributes['attributes'] ??= [];
+
+        parent::__construct($attributes);
+    }
+
+    /**
+     * Make a new column instance.
+     */
+    public static function make(array|string $data = [], string $content = ''): static
+    {
+        $attributes = $data;
+
+        if (is_string($data)) {
+            $attributes = [
+                'column' => $data,
+                'content' => $content,
+            ];
+        }
+
+        return new static($attributes);
+    }
+
+    /**
+     * @return $this
+     */
+    public function column(string $value): static
+    {
+        $this->attributes['column'] = $value;
+
+        return $this;
+    }
+
+    /**
+     * @return $this
+     */
+    public function content(string $value): static
+    {
+        $this->attributes['content'] = $value;
+
+        return $this;
+    }
+}
diff --git a/src/Html/HasOptions.php b/src/Html/HasOptions.php
index 14fcd6d..1a31507 100644
--- a/src/Html/HasOptions.php
+++ b/src/Html/HasOptions.php
@@ -12,6 +12,7 @@ trait HasOptions
     use Options\HasAjax;
     use Options\HasCallbacks;
     use Options\HasColumns;
+    use Options\HasRows;
     use Options\HasFeatures;
     use Options\HasInternationalisation;
     use Options\Plugins\AutoFill;
diff --git a/src/Html/Options/HasRows.php b/src/Html/Options/HasRows.php
new file mode 100644
index 0000000..b2a8d59
--- /dev/null
+++ b/src/Html/Options/HasRows.php
@@ -0,0 +1,60 @@
+<?php
+
+namespace Yajra\DataTables\Html\Options;
+
+use Illuminate\Contracts\Support\Arrayable;
+use Illuminate\Support\Collection;
+use Yajra\DataTables\Html\Row;
+
+/**
+ * DataTables - Row option builder.
+ */
+trait HasRows
+{
+    /**
+     * Set columns option value.
+     *
+     * @return $this
+     *
+     * @see https://datatables.net/reference/option/columns
+     */
+    public function rows(array $rows): static
+    {
+        $this->rows = new Collection;
+
+        foreach ($rows as $key => $value) {
+            if (! is_a($value, Row::class)) {
+                if (array_key_exists('cells', $value)) {
+                    $cells = $value['cells'];
+                    $attributes = $value['attributes'] ?? [];
+                } else {
+                    $cells = $value;
+                    $attributes = [];
+                }
+
+                $this->rows->push(new Row($attributes, $cells));
+            } else {
+                $this->rows->push($value);
+            }
+        }
+
+        return $this;
+    }
+
+    public function setRows(Collection|array $rows): static
+    {
+        $this->rows = collect($rows);
+
+        return $this;
+    }
+
+    /**
+     * Get collection of rows.
+     *
+     * @return \Illuminate\Support\Collection<array-key, array>
+     */
+    public function getRows(): Collection
+    {
+        return $this->rows;
+    }
+}
diff --git a/src/Html/Row.php b/src/Html/Row.php
new file mode 100644
index 0000000..66981e8
--- /dev/null
+++ b/src/Html/Row.php
@@ -0,0 +1,75 @@
+<?php
+
+namespace Yajra\DataTables\Html;
+
+use Illuminate\Support\Fluent;
+use Illuminate\Support\Collection;
+
+/**
+ * @property string $content
+ * @method content($content)
+ */
+class Row extends Fluent
+{
+    public function __construct(array $attributes = [], array $cells = [])
+    {
+        $attributes['attributes'] ??= [];
+
+        $this->buildCells($cells);
+
+        parent::__construct($attributes);
+    }
+
+    /**
+     * Make a new column instance.
+     */
+    public static function make(array $attributes = [], array $cells = []): static
+    {
+        return new static($attributes, $cells);
+    }
+
+    public function cells($cells): static
+    {
+        $this->cells = collect($cells);
+
+        return $this;
+    }
+
+    protected function buildCells(array $cells): static
+    {
+        $this->cells = new Collection;
+
+        foreach ($cells as $key => $value) {
+            if (! is_a($value, Cell::class)) {
+                if (is_array($value)) {
+                    $cellAttributes = array_merge($value, [
+                        'column' => $value['column'] ?? $key,
+                        'content' => $value['content'] ?? null,
+                    ]);
+                } else {
+                    $cellAttributes = [
+                        'column' => $key,
+                        'content' => $value,
+                    ];
+                }
+
+                $this->cells->push(new Cell($cellAttributes));
+            } else {
+                $this->cells->push($value);
+            }
+        }
+
+        $this->cells = $this->cells->keyBy('column');
+
+        return $this;
+    }
+
+    public function getCellContentForColumn(Column $column): mixed
+    {
+        if ($this->cells->has($column->data)) {
+            return $this->cells->get($column->data)->content;
+        }
+
+        return null;
+    }
+}