Skip to content
v3 betaRebuilt from the ground up

The data framework for Vue.

A framework-independent engine searches, sorts, pages, selects, edits, and undoes. Headless components, a styled theme, and a full spreadsheet sit on top. Take one layer, or all of them.

Get started Explore the layers
pnpm add vueye-table@beta
Live, and rendered on the server
Ada LovelaceEngineering$40,000Away
Alan TorvaldsSupport$47,919Active
Grace LiskovDesign$55,838Active
Edsger TuringFinance$63,757Active
Barbara PerlmanSales$71,676Away
Accent
Density
Both are one custom property and one prop: --vt-accent, density.
  • TypeScript-first
  • SSR-safe
  • Accessible markup
  • Zero-dependency engine
  • MIT licensed

Architecture

Five layers. One engine.

Each package depends only on the layers beneath it. Start at the top with one tag, and drop down a layer whenever you need more control. Columns, state, and data stay the same.

01 / 05 Builds on the styled layer and re-exports every layer.

Full UI

vueye-table

<VueyeTable> and <VueyeGrid> give you a complete table or spreadsheet in one tag, with a v-model for every piece of state.

Use it when you want a complete table or spreadsheet in one tag.

vue
<script setup lang="ts">
import { VueyeTable, defineColumns } from "vueye-table";

const columns = defineColumns<User>([
  { id: "name.first", header: "First name" },
  { id: "age", align: "end", format: (age) => `${age} years` },
  { id: "city" },
]);
</script>

<template>
  <VueyeTable :data="users" :columns="columns" selectable striped />
</template>
Read the guide

02 / 05 Builds on the headless layer.

Styled components

@vueye-table/styled

Vt* components and a theme of CSS custom properties, with dark mode and three densities, arranged your own way.

Use it when you want the look, arranged your own way.

vue
<script setup lang="ts">
import { VtSearch, VtStatus, VtTable, VtToolbar } from "vueye-table";
import { provideDataTable, useDataTable } from "vueye-table";

const table = useDataTable({ data: users, columns });
provideDataTable(table);
</script>

<template>
  <VtToolbar>
    <VtSearch placeholder="Filter people" />
    <VtStatus />
  </VtToolbar>
  <VtTable :table="table" density="compact" bordered />
</template>
Read the guide

03 / 05 Builds on the composables.

Headless components

@vueye-table/headless

DataTable* and DataGrid* render accessible markup with aria and data attributes, and no styles at all.

Use it when you want accessible behavior with your own markup and CSS.

vue
<script setup lang="ts">
import { DataTableRoot, DataTableSearch } from "vueye-table";
import { useDataTable } from "vueye-table";

const table = useDataTable({ data: users, columns });
</script>

<template>
  <DataTableRoot :table="table" as="div">
    <DataTableSearch />
    <article v-for="row in table.rows" :key="row.key">
      {{ row.getDisplay("name.first") }}
    </article>
  </DataTableRoot>
</template>
Read the guide

04 / 05 Builds on the engine.

Vue composables

@vueye-table/vue

useDataTable and useDataGrid turn the engine into reactive state for your own components, and render nothing.

Use it when you want reactive state and nothing rendered.

ts
import { useDataTable } from "@vueye-table/vue";

const table = useDataTable({ data: users, columns });

table.search("lon");
table.toggleSort("age");

// Plain reactive properties: templates read them directly.
table.rows; // the current page
table.pageCount;
table.selectedCount;
Read the guide

05 / 05 No framework and no runtime dependencies.

Engine

@vueye-table/core

Searches, filters, sorts, pages, selects, edits with undo, copies, pastes, and exports. It knows nothing about Vue and runs on a server.

Use it when you are outside Vue, on a server, or writing a binding.

ts
import { createTable } from "@vueye-table/core";

const table = createTable({ data: users, columns });

table.search("lon");
table.toggleSort("age");
table.getSnapshot().rows; // the current page
table.getState(); // plain data: save it, restore it, send it
table.exportRows(); // CSV of every filtered row
Read the guide
Nuxt 4@vueye-table/nuxt auto-imports the components and composables and adds the stylesheet.

What it does

Built like a spreadsheet. Shaped like Vue.

Keyboard-first spreadsheet

Arrows move and Shift extends the range. Enter or F2 edits, and copy, cut, paste, Delete, undo, and redo work the way they do in a spreadsheet.

Typed to the leaf

Column ids are typed paths into your rows, so format on a salary receives a number.

Server-driven when you need it

Add manual and row-count, and your server searches, sorts, and pages. The table presents whatever page comes back.

State is plain data

Sorting, search, filters, pages, and selection serialize as they are. Save them, restore them, or keep them in the URL.

Never mutates your data

Every edit, undo, and redo arrives as a new array. Rows you did not touch are shared, not copied.

Accessible markup, with or without styles

The headless layer renders roles, states, and a polite live status. Focus in the spreadsheet moves with aria-activedescendant, so screen readers follow the active cell.

Rendered on the server, ready for Nuxt

No package reads a browser global, and a check enforces it on every commit. The Nuxt module auto-imports the components and composables and adds the stylesheet.

Start with one tag.

Drop down a layer whenever you need more control. Columns, state, and data stay the same.

pnpm add vueye-table@beta

3.0.0-beta: documented APIs stay stable through the beta, but it is not yet production ready. The 2.x component lives on the legacy branch.

Released under the MIT License. 3.0.0-beta: not yet production ready.