npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ioi-dev/vue-table

v0.2.3

Published

A performance-first Vue 3 data table component with a streamlined API surface and JavaScript-first defaults

Readme

@ioi-dev/vue-table

A performance-first Vue 3 data table component with a streamlined API surface and JavaScript-first defaults. Designed to deliver enterprise-grade performance without the complexity of larger alternatives.

v0.2.3 - Server-Side Mode, Full Accessibility (WCAG 2.1 AA), and Performance Benchmarks

Overview

IOI Vue Table provides a lightweight yet powerful solution for rendering large datasets in Vue 3 applications. It combines virtual scrolling, efficient sorting and filtering, and flexible customisation options whilst maintaining a small bundle footprint.

Key Features

  • Performance-First Architecture: Optimised for rendering thousands of rows with minimal overhead
  • Virtual Scrolling: Built-in virtualisation for smooth scrolling through large datasets
  • Row Grouping: Group rows by single or multiple columns with aggregate calculations
  • Flexible Column Definitions: Strongly-typed column configuration with support for various data types
  • Headless Pagination: Full control over pagination state with reactive bindings
  • Header Filters: Built-in support for text and select-based column filtering
  • Row Expansion: Expandable rows with custom content slots
  • CSV Export/Import: Secure data export with formula sanitisation and preview-based import
  • Server-Side Mode: Fetch data from server with debounced requests, loading/error states, cursor-based pagination, and infinite scroll support
  • Accessibility (a11y): Full keyboard navigation (Arrow keys, Home/End, PageUp/PageDown), focus management, ARIA attributes, live region announcements, and WCAG 2.1 AA compliance
  • Performance Benchmarks: Built-in benchmark harness with 8 scenarios for measuring render, sort, filter, and scroll performance
  • TypeScript Support: Comprehensive type definitions for enhanced developer experience
  • Zero-Dependency Core: Minimal external dependencies to reduce bundle size

Keywords

vue, vue3, vuejs, vue-3, table, datatable, data-table, grid, data-grid, table-component, vue-component, virtual-scroll, virtualization, virtual-list, sorting, filtering, pagination, grouping, row-groups, aggregations, group-by, row-expansion, csv-export, csv-import, typescript, ts, performance, lightweight, enterprise, responsive, headless, reactive, composition-api, vue-composition-api, frontend, ui-component, data-display, spreadsheet, ag-grid-alternative, tanstack-alternative

Installation

npm install @ioi-dev/vue-table

CSS Integration

The default package entry includes library CSS. For zero-CSS integration, use the unstyled entry point:

@ioi-dev/vue-table/unstyled

Available CSS import paths:

  • Canonical: @ioi-dev/vue-table/styles.css
  • Compatibility alias: @ioi-dev/vue-table/style.css

Quick Start

<script setup lang="ts">
import { Table, type ColumnDef } from '@ioi-dev/vue-table';

interface UserRow {
  id: number;
  name: string;
  score: number;
}

const columns: ColumnDef<UserRow>[] = [
  { field: 'id', header: 'ID', type: 'number', width: 90 },
  { field: 'name', header: 'Name', type: 'text' },
  { field: 'score', header: 'Score', type: 'number' }
];

const rows: UserRow[] = [
  { id: 1, name: 'Alpha', score: 91 },
  { id: 2, name: 'Beta', score: 77 }
];
</script>

<template>
  <Table :rows="rows" :columns="columns" row-key="id" :height="320" />
</template>

Note: IoiTable remains available as a backward-compatible alias for Table.

Advanced Usage

Pagination with Header Filters

This example demonstrates headless pagination with reactive state management and built-in header filters:

<script setup lang="ts">
import { ref } from 'vue';
import { Table, type ColumnDef } from '@ioi-dev/vue-table';

interface UserRow {
  id: number;
  name: string;
  status: string;
}

const rows = ref<UserRow[]>([]);
const pageIndex = ref(0);
const pageSize = ref(25);

const columns: ColumnDef<UserRow>[] = [
  { field: 'id', header: 'ID' },
  { field: 'status', header: 'Status', headerFilter: 'select' },
  { field: 'name', header: 'Name', headerFilter: 'text' }
];
</script>

<template>
  <Table
    v-model:pageIndex="pageIndex"
    v-model:pageSize="pageSize"
    :rows="rows"
    :columns="columns"
    row-key="id"
  />
</template>

Row Grouping

Group rows by single or multiple columns with aggregate calculations:

<script setup lang="ts">
import { ref } from 'vue';
import { Table, type ColumnDef } from '@ioi-dev/vue-table';

interface SalesRow {
  id: number;
  region: string;
  product: string;
  amount: number;
}

const rows = ref<SalesRow[]>([
  { id: 1, region: 'North', product: 'Widget', amount: 100 },
  { id: 2, region: 'North', product: 'Gadget', amount: 200 },
  { id: 3, region: 'South', product: 'Widget', amount: 150 },
  { id: 4, region: 'South', product: 'Gadget', amount: 250 }
]);

const expandedGroups = ref<string[]>(['North']);

const groupAggregations = {
  amount: ['sum', 'avg']
};
</script>

<template>
  <Table
    v-model:expandedGroupKeys="expandedGroups"
    :rows="rows"
    :columns="[
      { field: 'region', header: 'Region' },
      { field: 'product', header: 'Product' },
      { field: 'amount', header: 'Amount', type: 'number' }
    ]"
    row-key="id"
    group-by="region"
    :group-aggregations="groupAggregations"
  />
</template>

Server-Side Mode

For large datasets or real-time data, use server-side mode to fetch data on demand:

<script setup lang="ts">
import { ref } from 'vue';
import { Table, type ServerDataOptions, type ColumnDef } from '@ioi-dev/vue-table';

interface UserRow {
  id: number;
  name: string;
  email: string;
}

const columns: ColumnDef<UserRow>[] = [
  { field: 'id', header: 'ID', type: 'number' },
  { field: 'name', header: 'Name', type: 'text' },
  { field: 'email', header: 'Email', type: 'text' }
];

const serverOptions: ServerDataOptions<UserRow> = {
  fetch: async (params) => {
    const response = await fetch(`/api/users?page=${params.pageIndex}&size=${params.pageSize}`);
    const data = await response.json();
    return {
      rows: data.items,
      totalRows: data.total
    };
  },
  debounceMs: 300
};
</script>

<template>
  <Table
    data-mode="server"
    :server-options="serverOptions"
    :columns="columns"
    row-key="id"
  />
</template>

Accessibility

The table is built with accessibility in mind:

  • Keyboard Navigation: Full support for Arrow keys, Home/End, Page Up/Down
  • Focus Management: Visible focus indicators and focus trapping in edit mode
  • Screen Reader Support: ARIA attributes and live region announcements
  • WCAG 2.1 AA Compliance: Color contrast, focus visibility, and reduced motion support
<template>
  <Table
    :rows="rows"
    :columns="columns"
    row-key="id"
    aria-label="Employee directory"
  />
</template>

Configuration Options

Behaviour Defaults

| Option | Default | Description | |--------|---------|-------------| | sanitizeFormulas | true | Sanitises formula-like prefixes in CSV exports to prevent injection attacks | | globalSearchDebounceMs | 0 | Debounce interval for global search input (milliseconds) | | filterDebounceMs | 0 | Debounce interval for filter operations (milliseconds) | | rowHeight | Configurable | Height of each row for virtualisation calculations | | overscan | Configurable | Number of extra rows to render outside viewport for smoother scrolling |

Documentation

Requirements

  • Vue 3.4 or higher
  • Modern browser with ES2020 support

License

MIT

Contributing

Contributions are welcome. Please refer to the repository guidelines for submission requirements and coding standards.