BufferPeek is a local-first developer tool that provides a real-time, in-browser preview dashboard for your document exports (similar to Prisma Studio or Drizzle Studio). It supports instant, live previews for spreadsheet and PDF libraries including ExcelJS, SheetJS (xlsx), and jsPDF.
Developers building dynamic spreadsheet or PDF exports often experience a slow and repetitive feedback loop:
- Script Execution: Running the script or triggering the export code in your application.
- File Pollution: Saving the generated file to the local disk.
- Application Locking: Locating and opening the file using external applications (such as Microsoft Excel, Google Sheets, or local PDF readers). On Windows, these viewers often lock the file, preventing you from writing to it again until you close the viewer.
- Cleanups: Deleting temporary files to avoid polluting the workspace repository.
This process is repeated for every minor adjustment to layouts, borders, font weights, column widths, or text alignments, significantly slowing down development velocity.
BufferPeek eliminates this friction by providing a live, local preview server. By adding thin capture wrappers to your export code, the generated file structures are intercepted in-memory, normalized, and immediately transmitted to a local web dashboard.
With BufferPeek:
- Explicit Control: Wrap exports with meaningful names in your code.
- Deterministic Hot-Reloads: Captured documents use stable names to update in-place in the UI, avoiding list duplicates.
- In-Browser Preview: Review interactive spreadsheet grids (with fonts, alignments, colors, merges, and sizes) and multi-page PDF views side-by-side.
- No File Pollution: See actual runtime data without polluting your disk with temporary files.
- Premium Theme Design: A clean, developer-focused light theme built with Material-UI (MUI), featuring a zero-padding spreadsheet layout and translucent loading states.
BufferPeek is built as a workspace monorepo consisting of:
- CLI & Server (
packages/cli): A lightweight Node/Express server that runs locally, maintains captured files in-memory, writes dynamic ports to.bufferpeek/port.json, and broadcasts updates to UI clients via WebSockets (ws). - Runtime Capture Library (
packages/runtime): Dynamic, dependency-free wrapper functions (captureExcel,captureSheet,capturePDF) imported in your code asbufferpeek/runtime. - UI Preview Dashboard (
packages/ui): A React + Vite SPA built with Material-UI (MUI) components configured with a light theme, featuring virtualized sheet grids and same-origin canvas-based PDF rendering.
Add the package as a development dependency:
npm install --save-dev bufferpeek
# or using pnpm
pnpm add -D bufferpeek
# or using yarn
yarn add -D bufferpeekStart the local server using npx:
npx bufferpeekbufferpeek [options]
Options:
-p, --port <port> Port to run on (default: 5550)
--no-open Don't open browser automatically
-w, --watch <file> Watch and auto-execute an export script on changes
-v, --version Show version
-h, --help Show helpBy default, BufferPeek runs on port 5550. If the port is in use, it will automatically find and run on the next available port (5551, 5552, etc.) and write the active port configuration to .bufferpeek/port.json.
If you are developing a standalone script that generates documents, you can instruct BufferPeek to watch that script and run it automatically on file changes:
npx bufferpeek -w src/index.tsThis runs the local preview server, opens the browser, and watches your file. Whenever you save changes to your export logic, the script re-runs, and your preview updates in the browser dashboard in real-time!
Import capture functions from bufferpeek/runtime in your code.
import { captureExcel } from 'bufferpeek/runtime';
import ExcelJS from 'exceljs';
const workbook = new ExcelJS.Workbook();
const sheet = workbook.addWorksheet('Sales Summary');
sheet.addRow(['Product', 'Quantity', 'Revenue']);
sheet.addRow(['Enterprise License', 12, 120000]);
// Intercept workbook and upload to the dashboard
await captureExcel(workbook, 'Sales Report 2026', ['sales', 'monthly']);
// Keep your original write code
await workbook.xlsx.writeFile('sales-report.xlsx');import { captureSheet } from 'bufferpeek/runtime';
import * as XLSX from 'xlsx';
const workbook = XLSX.utils.book_new();
const sheet = XLSX.utils.aoa_to_sheet([
['Customer Name', 'Status'],
['John Doe', 'Active'],
['Jane Smith', 'Pending']
]);
XLSX.utils.book_append_sheet(workbook, sheet, 'Main Data');
// Intercept workbook and upload to the dashboard
await captureSheet(workbook, 'Customer Database', ['users', 'raw']);import { capturePDF } from 'bufferpeek/runtime';
import { jsPDF } from 'jspdf';
const doc = new jsPDF();
doc.text('Invoice INV-98203', 20, 20);
doc.text('Amount Due: $2,450.00', 20, 30);
// Intercept PDF document and upload to the dashboard
await capturePDF(doc, 'Invoice INV-98203', ['invoice', 'billing']);
// Keep your original output code
doc.save('invoice.pdf');BufferPeek supports two separate actions to regenerate exports during development:
- Where: Triggered via the "Sync Codebase" button at the top-right of the dashboard header, or the "Sync Codebase & Generate Previews" button inside the empty onboarding card.
- Purpose: Runs the entire watch target script (e.g. the path passed via the
-woption, such assrc/index.ts) for the first time. - Job: Scans and registers any new files or documents. This action only renders the previews at first and will not overwrite target refreshes.
- Where: Triggered via the "Refresh Preview" button on each active document view header.
- Purpose: Refreshes only the specific document or sheet you are currently inspecting.
- How: BufferPeek extracts stack-trace information at runtime to locate the exact caller-file that generated that preview (e.g.,
src/excel-export.ts). When you click "Refresh Preview", the server executes only that file, keeping the refresh isolated and extremely fast.
- Debounced Search: The search bar in the left sidebar keeps text typing local and propagates updates after a
150msdelay. - Component Memoization: Heavy preview panels (
SpreadsheetViewandPDFView) are wrapped inReact.memoto skip re-rendering while you type in the search bar or toggle filters, ensuring zero interface lag.
| Feature | Details |
|---|---|
| CLI & Server | Node.js, Express, WebSocket (ws), Commander |
| Dashboard UI | React, Vite, Material-UI (MUI) components, Slate theme |
| Spreadsheet Normalizer | In-memory cell styling, merges, and dimensions extractor (safely ignores merged placeholder cell errors in ExcelJS) |
| PDF Renderer | Same-origin canvas page painter using pdfjs-dist (served locally to avoid CORS restrictions) |
| Port Detection | Active port probing using Node's net module with auto-port lookup |
| Zero Conflicts | ExcelJS, SheetJS, and jsPDF are loaded dynamically or compiled type-safely. Developers are never forced to install libraries they do not use. |
| Silent Fallback | In production or if the preview server is closed, capture helpers fail silently with standard console warnings to prevent interrupting your application. |
MIT