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

lomboktablesheet

v1.0.1

Published

Fast, lightweight, portable Table + Spreadsheet library. Core engine, framework-agnostic.

Readme

LombokTableSheet


GitHub

CI PHP Port CI Go Port CI Linter Deploy docs License


NPM

npm version npm downloads jsDelivr hits types runtime deps

The npm badges above will read not found until the first publish. v1.0.0 is the release intended to go out; see DEPLOYMENT.md. Everything else on this page is live today.


A Table + Spreadsheet library with a framework-agnostic core and thin adapters for React, Vue, and vanilla JS. The core carries no runtime dependencies and is written deliberately without eval, reflection, or host-language tricks — so the same design ports mechanically to other languages rather than being rewritten per platform.

LombokTableSheet

| | | | -------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | | Architecture | Usage | | Detailed Usage | Security | | Plugin API | HostEngine |


Status — v1.0.0

| | | |---|---| | TS/JS core | 71 source files, ~4,500 lines · 252 tests passing | | Formula engine | Pratt parser, no eval anywhere on the evaluation path | | Codecs | CSV · JSON · Markdown · XLSX · HTML · ZIP — all hand-written, no codec dependencies | | i18n | 30-locale flat UI catalog, plus a namespaced manager with pluralization for 6 languages | | Plugins | Registry, loader, semver range matching, 8 lifecycle hooks | | Statistics | One-way and two-way ANOVA, cross-validated against SciPy and statsmodels | | PHP port | ports/php — data/formula layer, 33 test methods, PHP 8.1–8.3 | | Go port | ports/go — data/formula layer, 37 test functions, Go 1.21–1.22 | | CI/CD | 13 workflows — see WORKFLOWS.md for what's automated and what honestly isn't |

Numbers under "TS/JS core" come from an actual test run, not an estimate. The PHP and Go figures are counts of test methods/functions in those trees; they run in their own CI workflows rather than in the TS suite.

Known gaps, stated plainly:

  • ports/rust/ does not build. Its Cargo.toml declares src/lib.rs, three test files, and an example that do not exist — the directory holds only src/formula.rs. Treat the Rust port as unstarted, not as a port in progress.
  • npm run lint is broken. The script is eslint src --ext .ts, but ESLint 9 removed --ext and requires a flat eslint.config.js, which this repo does not have. The Linter badge above will stay red until that is fixed properly.
  • XLSX, i18n, and the DOM adapters are TypeScript-only. The PHP and Go ports cover the data and formula layers; they are not full ports.
  • dist/index.js does not load in a browser via a plain <script type="module">. The barrel re-exports the XLSX codec, which reaches formats/zip.js and its import { deflateRawSync } from 'node:zlib'. Import the subpaths you need instead (dist/formats/csv.js, dist/adapters/dom.js, …) — see DEPLOYMENT.md for the full browser-safe list. Bundlers are unaffected; only direct module-script loading hits this.

Install

npm install lomboktablesheet

Not published yet — until the first release lands, install straight from the repository:

npm install github:codinglombok/LombokTableSheet

PHP port (once on Packagist):

composer require codinglombok/lomboktablesheet

Quick start

// Via a bundler or in Node, the package barrel is fine:
import { LombokTable, decodeCsv } from 'lomboktablesheet';
// Loading straight into a browser instead? Import subpaths — see "Known gaps" above.

const { workbook } = decodeCsv('name,age\nAlice,30\nBob,25\n');
const table = new LombokTable(document.getElementById('app')!, {
  workbook,
  template: 'report',
  locale: 'en-US',
});

Import / export

import {
  decodeCsv, encodeCsv, decodeJson, encodeJson, encodeMarkdown,
  decodeXlsx, encodeXlsx, decodeHtml, encodeHtml,
} from 'lomboktablesheet';

const { workbook, warnings } = decodeCsv(csvText);   // never throws — check `warnings`
const csvOut = encodeCsv(workbook);
const jsonOut = encodeJson(workbook);
const mdOut = encodeMarkdown(workbook);              // GitHub-flavored Markdown table

// XLSX: dependency-free — hand-written ZIP writer, no external xlsx library
const xlsxBuf = encodeXlsx(workbook);
const { workbook: fromXlsx } = decodeXlsx(xlsxBuf);

// HTML tables
const htmlOut = encodeHtml(workbook, { className: 'my-table' });
const { workbook: fromHtml } = decodeHtml('<table>...</table>');

Split / merge

import { splitByRows, splitByColumns, splitBySheet, merge } from 'lomboktablesheet';

const [top, bottom] = splitByRows(workbook, 'Sheet1', 100);
const [left, right] = splitByColumns(workbook, 'Sheet1', 3);
const combined = merge([top, bottom], { onConflict: 'left-wins' });

Editable spreadsheet + formulas

import { LombokSheet, Workbook } from 'lomboktablesheet';

const workbook = new Workbook('en-US');
const sheet = new LombokSheet(document.getElementById('app')!, { workbook });

sheet.on('cellChange', (row, col) => console.log('edited', row, col));
// Double-click a cell to edit. Type "=SUM(A1:A3)*2" — formulas recalculate when
// their dependencies change. Ctrl+Z / Ctrl+Y for undo/redo.

Supports + - * / ^, comparisons, cell refs (A1) and ranges (A1:B3), and SUM, AVG, MIN, MAX, COUNT, IF, ROUND, CONCAT. Failures become #DIV/0!, #CIRC!, #NAME?, #VALUE! error cells rather than exceptions — see ARCHITECTURE.md §3.3/§6 for why there is no eval in the evaluator.

Plugins

import { PluginRegistry, type IPlugin } from 'lomboktablesheet';

const registry = new PluginRegistry();
registry.register({
  name: '@acme/uppercase',
  version: '1.0.0',
  capabilities: ['formula-extension'],
  hooks: [{ hook: 'registerFormula', callback: () => ({
    name: 'UPPER', arity: 1, fn: (s: string) => String(s).toUpperCase(),
  }) }],
});

Dependencies between plugins are resolved with real semver ranges (^, ~, >=, <, conjunctions), and the registry refuses to unregister a plugin others still depend on. Full reference: docs/PLUGIN_API.md · docs/PLUGIN_DEV_GUIDE.md.

HostEngine — plugins + i18n + formulas together

import { HostEngine, anovaPlugin, catalogs } from 'lomboktablesheet';

const engine = new HostEngine({ defaultLanguage: 'en' });
engine.registerLanguage('en', catalogs.en);
engine.registerLanguage('es', catalogs.es);
await engine.loadPlugin(anovaPlugin);

engine.listFormulaNames();               // ['ANOVA_ONEWAY', 'ANOVA_TWOWAY']
engine.evalFormula('ANOVA_ONEWAY', [23, 25, 21], [30, 32, 29], [28, 26, 30]);

Errors surface as FormulaEngineError with an already-localized message; the original English, code-prefixed error stays on .cause for logs. See docs/HOST_ENGINE.md.

Statistics

import { anovaOneWay, anovaTwoWay } from 'lomboktablesheet';

const r = anovaOneWay([[23, 25, 21], [30, 32, 29], [28, 26, 30]]);
r.f_statistic; r.p_value; r.eta_squared; r.significant;

Reference values and the scripts that generated them live in docs/anova/, so every expected number in the test suite is traceable to SciPy or statsmodels output rather than to a previous run of this library.

Templates

Built in: plain, report, invoice, financial-statement. Register your own:

import { defaultTemplates } from 'lomboktablesheet';

defaultTemplates.register({
  name: 'dashboard',
  description: 'Compact dashboard style',
  header: { bold: true, sticky: true },
  zebraRows: true,
  borders: 'horizontal',
  numberAlign: 'right',
  cssHooks: ['lts-dashboard'],
});

Templates are pure JSON/CSS and never couple to your data — export to CSV or JSON and the presentation concerns disappear entirely.

i18n

Two surfaces, deliberately separate:

import { I18n, I18nManager, catalogs } from 'lomboktablesheet';

// Intl-backed formatting + a flat UI-string catalog, 30 locales
const i18n = new I18n('ar-EG');
i18n.isRtl();                        // true
i18n.formatCurrency(1500, 'USD');

// Namespaced catalogs with pluralization, 6 languages
const m = new I18nManager({ defaultLanguage: 'de' });
m.registerLanguage('de', catalogs.de);
m.tp('plurals.row_count', 3);        // "3 Zeilen"

Framework adapters

React and Vue are opt-in sub-paths — the core bundle contains no React or Vue code.

// React
import { LombokTableReact, LombokSheetReact } from 'lomboktablesheet/react';

function App() {
  return <LombokTableReact data={rows} template="report" locale="en-US" />;
}
<!-- Vue 3 -->
<script setup>
import { LombokTableVue } from 'lomboktablesheet/vue';
</script>
<template>
  <LombokTableVue :workbook="workbook" template="invoice" />
</template>

Both wrappers mount the same framework-agnostic LombokTable / LombokSheet core underneath — they are thin, not reimplementations.

Optional peers

  • LombokCharts — chart rendering from the same Workbook data.
  • LombokCSS — themeable styling via the cssHooks that templates expose.

Both are optional peerDependencies; LombokTableSheet works standalone without them.

Documentation

| Document | What's in it | |---|---| | PROJECT_SUMMARY.md | What exists, in numbers | | ARCHITECTURE.md | Design, data model, trade-offs, roadmap | | USAGE.md | Quick how-to (TS + PHP) | | DETAILED_USAGE.md | Exhaustive API reference, all ports | | docs/PLUGIN_API.md | Plugin interfaces and hooks | | docs/PLUGIN_DEV_GUIDE.md | Building a plugin, start to finish | | docs/HOST_ENGINE.md | How plugins, i18n and formulas wire together | | SECURITY.md | Hardening record and disclosure process | | WORKFLOWS.md | Every CI workflow, and the ones deliberately not built | | DEPLOYMENT.md | How to ship it |

Development

npm install
npm run typecheck   # tsc --noEmit
npm test            # node --test — 252 tests
npm run build       # emits dist/ (ESM + type declarations)

The test suite runs on Node's built-in runner, not Jest. tests/expect.ts is a small Jest-compatible assertion shim so suites written against the Jest API run unchanged — add matchers there rather than introducing a test framework dependency.

README artwork is generated, not hand-drawn: python3 docs/assets/generate_assets.py. Those are designed graphics rather than screenshots — real demo captures should come from the Pages site once it is enabled.

License

Apache 2.0 — see LICENSE.