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 🙏

© 2025 – Pkg Stats / Ryan Hefner

vanillajs-excelike-table

v2.3.3

Published

Simple and powerful JavaScript table with all features enabled by default - no configuration needed!

Readme

VanillaJS ExceLikeTable

The simplest Excel-like table for JavaScript
Zero configuration needed - all features work out of the box! ✨

npm version License Size

✨ Why This Library?

  • 🎯 Zero Configuration: Just pass data and columns - everything works!
  • All Features Enabled: Filtering, sorting, pagination, column pinning - all included by default
  • 🚀 Modern ESM: Works with Vite, Webpack, Next.js, and all modern tools
  • 📦 Lightweight Package: Pure vanilla JavaScript (~100KB minified)
  • 💾 Auto-Save Settings: User preferences saved automatically
  • 🎨 Excel-like UX: Familiar interface for end users

🚀 Quick Start

Installation

npm install vanillajs-excelike-table

Option 1: With Build Tools (Vite/Webpack - Recommended)

Step 1: Install the package (see above)

Step 2: Create your HTML file:

<!DOCTYPE html>
<html>
<head>
  <title>My Table App</title>
</head>
<body>
  <div id="my-table"></div>
  <script type="module" src="/src/main.js"></script>
</body>
</html>

Step 3: Create src/main.js:

import ExceLikeTable from 'vanillajs-excelike-table';
import 'vanillajs-excelike-table/dist/excelike-table.css';

const table = new ExceLikeTable('#my-table', {
  data: [
    { id: 1, name: 'John Doe', age: 30, city: 'New York' },
    { id: 2, name: 'Jane Smith', age: 25, city: 'Los Angeles' },
    { id: 3, name: 'Bob Johnson', age: 35, city: 'Chicago' }
  ],
  columns: [
    { key: 'name', title: 'Name', dataIndex: 'name' },
    { key: 'age', title: 'Age', dataIndex: 'age' },
    { key: 'city', title: 'City', dataIndex: 'city' }
  ]
});

Step 4: Run your dev server:

npm run dev  # For Vite
# or
npm start    # For Webpack/other bundlers

That's it! ✅ You now have:

  • ✓ Sortable columns (click headers)
  • ✓ Filterable data (click filter icons)
  • ✓ Pagination (10 items per page)
  • ✓ Resizable columns (drag edges)
  • ✓ Pinnable columns (column settings menu)
  • ✓ Auto-saved user preferences

Option 2: CDN (No Build Tools Required)

Copy and paste this complete HTML file - it works immediately!

<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>ExceLikeTable Demo</title>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vanillajs-excelike-table@latest/dist/excelike-table.css">
</head>
<body>
  <div id="my-table"></div>

  <script src="https://cdn.jsdelivr.net/npm/vanillajs-excelike-table@latest/dist/excelike-table.browser.js"></script>
  <script>
    const table = new ExceLikeTable('#my-table', {
      data: [
        { id: 1, name: 'Alice', age: 28, city: 'Tokyo' },
        { id: 2, name: 'Bob', age: 32, city: 'NYC' },
        { id: 3, name: 'Carol', age: 25, city: 'London' }
      ],
      columns: [
        { key: 'name', title: 'Name', dataIndex: 'name' },
        { key: 'age', title: 'Age', dataIndex: 'age' },
        { key: 'city', title: 'City', dataIndex: 'city' }
      ]
    });
  </script>
</body>
</html>

Just open this HTML file in your browser - no npm, no build step needed!


📖 More Usage Examples

CommonJS (Node.js SSR)

const ExceLikeTable = require('vanillajs-excelike-table');
// CSS must be loaded separately in your HTML

const table = new ExceLikeTable('#container', {
  data: myData,
  columns: myColumns
});

TypeScript

import ExceLikeTable, { ExceLikeTableOptions, ExceLikeTableColumn } from 'vanillajs-excelike-table';
import 'vanillajs-excelike-table/dist/excelike-table.css';

const options: ExceLikeTableOptions = {
  data: myData,
  columns: myColumns
};

const table = new ExceLikeTable('#container', options);

🎯 Column Helpers (Easy Setup)

Use ColumnHelpers for common column types with pre-configured features:

import ExceLikeTable, { ColumnHelpers } from 'vanillajs-excelike-table';
import 'vanillajs-excelike-table/dist/excelike-table.css';

const table = new ExceLikeTable('#container', {
  data: employees,
  columns: [
    ColumnHelpers.text('name', 'Employee Name'),
    ColumnHelpers.number('salary', 'Salary', { currency: '$' }),
    ColumnHelpers.date('joinDate', 'Join Date'),
    ColumnHelpers.status('status', 'Status', {
      'Active': '#52c41a',
      'On Leave': '#faad14',
      'Terminated': '#ff4d4f'
    })
  ]
});

Available Helpers

| Helper | Usage | Features | |--------|-------|----------| | text() | ColumnHelpers.text('key', 'Title') | Basic text column | | number() | ColumnHelpers.number('price', 'Price', { currency: '¥' }) | Formatted numbers with currency | | date() | ColumnHelpers.date('date', 'Date') | Auto-formatted dates with hierarchy filter | | status() | ColumnHelpers.status('status', 'Status', colors) | Colored status badges | | actions() | ColumnHelpers.actions('Actions', buttons) | Action buttons |


📋 API Reference

Constructor

new ExceLikeTable(container, options)

Parameters

container string | HTMLElement
CSS selector or DOM element where table will be rendered

options Object

| Property | Type | Default | Description | |----------|------|---------|-------------| | data | Array | [] | Your data array | | columns | Array | [] | Column definitions | | rowKey | string | 'id' | Unique row identifier | | pagination | Object\|false | {pageSize: 10, showSizeChanger: true} | Pagination config or false to disable | | bordered | boolean | true | Show table borders | | size | 'small'\|'middle'\|'large' | 'middle' | Table size | | tableId | string | 'excelike-table' | Unique ID for settings storage | | persistSettings | boolean | true | Auto-save user preferences |


Column Definition

All features are enabled by default for each column!

{
  key: 'columnKey',        // Required: Unique identifier
  title: 'Column Title',   // Required: Display name
  dataIndex: 'dataKey',    // Required: Property name in data
  width: 150,              // Optional: Column width (default: 150)
  sortable: true,          // Optional: Enable sorting (default: true)
  filterable: true,        // Optional: Enable filtering (default: true)
  filterType: 'text',      // Optional: 'text' | 'date-hierarchy' | 'range'
  render: (value, record) => `<b>${value}</b>`,  // Optional: Custom renderer
  hidden: false            // Optional: Hide column (default: false)
}

Methods

// Update table data
table.setData(newData);

// Get current filters
const filters = table.getFilters();

// Set filters programmatically
table.setFilters({ name: ['John'], age: [30] });

// Clear all filters
table.clearFilters();

// Clean up and destroy table
table.destroy();

💡 Real-World Examples

Employee Management Table

import ExceLikeTable, { ColumnHelpers } from 'vanillajs-excelike-table';
import 'vanillajs-excelike-table/dist/excelike-table.css';

const employees = [
  { id: 1, name: 'Alice', department: 'Engineering', salary: 120000, joinDate: '2020-03-15', status: 'Active' },
  { id: 2, name: 'Bob', department: 'Marketing', salary: 85000, joinDate: '2019-07-22', status: 'Active' },
  { id: 3, name: 'Carol', department: 'Sales', salary: 95000, joinDate: '2021-01-10', status: 'On Leave' }
];

const table = new ExceLikeTable('#employee-table', {
  data: employees,
  columns: [
    ColumnHelpers.text('name', 'Employee Name'),
    ColumnHelpers.text('department', 'Department'),
    ColumnHelpers.number('salary', 'Salary', { currency: '$' }),
    ColumnHelpers.date('joinDate', 'Join Date'),
    ColumnHelpers.status('status', 'Status', {
      'Active': '#52c41a',
      'On Leave': '#faad14',
      'Terminated': '#ff4d4f'
    }),
    ColumnHelpers.actions('Actions', [
      { key: 'edit', label: 'Edit' },
      { key: 'delete', label: 'Delete' }
    ])
  ]
});

Sales Dashboard

const salesData = [
  { date: '2024-01-15', product: 'Widget A', quantity: 120, revenue: 2400, profit: 15 },
  { date: '2024-01-16', product: 'Widget B', quantity: 85, revenue: 3400, profit: 22 },
  { date: '2024-01-17', product: 'Widget C', quantity: 200, revenue: 5000, profit: -5 }
];

const table = new ExceLikeTable('#sales-table', {
  data: salesData,
  columns: [
    ColumnHelpers.date('date', 'Date'),
    ColumnHelpers.text('product', 'Product'),
    ColumnHelpers.number('quantity', 'Qty'),
    ColumnHelpers.number('revenue', 'Revenue', { currency: '¥' }),
    {
      key: 'profit',
      title: 'Profit %',
      dataIndex: 'profit',
      render: (value) => {
        const color = value >= 0 ? '#52c41a' : '#ff4d4f';
        return `<span style="color: ${color}; font-weight: bold;">${value}%</span>`;
      }
    }
  ],
  pagination: { pageSize: 20 }
});

Minimal Configuration

// Simplest possible usage
const table = new ExceLikeTable('#container', {
  data: myData,
  columns: [
    { key: 'col1', title: 'Column 1', dataIndex: 'col1' },
    { key: 'col2', title: 'Column 2', dataIndex: 'col2' }
  ]
});
// Everything just works! ✨

⚙️ Customization

Disable Specific Features

All features are enabled by default. You can disable them if needed:

const table = new ExceLikeTable('#container', {
  data: myData,
  columns: myColumns,
  pagination: false,          // Disable pagination
  persistSettings: false      // Disable auto-save
});

// Or disable per-column:
columns: [
  { 
    key: 'id', 
    title: 'ID', 
    dataIndex: 'id',
    sortable: false,    // Disable sorting for this column
    filterable: false   // Disable filtering for this column
  }
]

Custom Pagination

const table = new ExceLikeTable('#container', {
  data: myData,
  columns: myColumns,
  pagination: {
    pageSize: 25,
    showSizeChanger: true,
    showTotal: (total, range) => `Showing ${range[0]}-${range[1]} of ${total}`
  }
});

Custom Styling

/* Override default styles */
.excelike-table-wrapper {
  --table-border-color: #e0e0e0;
  --table-header-bg: #fafafa;
  --table-row-hover: #f5f5f5;
}

/* Customize specific elements */
.table-header {
  background: linear-gradient(to bottom, #f9f9f9, #ececec);
  font-weight: 600;
}

.table-cell {
  padding: 12px 16px;
}

🎨 Built-in Features

Sorting

  • Click column headers to sort
  • Multi-level sorting support
  • Custom sort functions

Filtering

  • Text filter with search
  • Date hierarchy filter (year/month/day)
  • Numeric range filter
  • Custom filter functions

Pagination

  • Configurable page sizes
  • Page navigation
  • Total count display
  • Can be disabled

Column Management

  • Resizable columns (drag edges)
  • Pinnable columns (lock to left)
  • Show/hide columns
  • Auto-save column preferences

Settings Persistence

  • Column widths
  • Column visibility
  • Pinned columns
  • Font size & padding
  • Saved to LocalStorage automatically

Conditional Formatting

  • Built-in feature - No plugins or extra imports needed!
  • Highlight rows/cells based on rules
  • 8 comparison operators: Equals (=), Not-Equals (≠), Greater (>), Greater-Equal (≥), Less (<), Less-Equal (≤), Contains, Not-Contains
  • Multiple data types: Text, Number, Date
  • Custom background and text colors
  • Auto-save rules to LocalStorage
  • Multi-language support (English, Japanese, Spanish, French, German)
  • Access via table menu (⚙️) → "Conditional Formatting"

Security & Performance

  • CSV Formula Injection Prevention: Automatic formula escape in exports to prevent Excel injection attacks
  • Virtual Scrolling: High-performance rendering for large datasets (10,000+ rows)
  • Optimized Rendering: 60-75% performance improvement with virtual scroll
  • Automatic Data Type Detection: Smart detection of numbers, dates, and text without configuration

🌐 Browser Support

Works in all modern browsers and environments:

| Environment | Support | |-------------|---------| | Chrome/Edge | ✅ Latest | | Firefox | ✅ Latest | | Safari | ✅ Latest | | Node.js | ✅ 14+ | | Vite | ✅ Yes | | Webpack | ✅ Yes | | Next.js | ✅ Yes | | React/Vue/Angular | ✅ Yes (framework-agnostic) |


🤝 Contributing

Contributions are welcome! Please feel free to submit pull requests.


📄 License

MIT License - feel free to use this library in your projects!


📞 Support

For questions, issues, or feature requests, please visit the GitHub repository.


Made with ❤️ for developers who love simplicity