A feature-parity office suite that runs entirely on your machine. No cloud callbacks, no CDNs, no subscriptions. Rich-text documents (Word-style) and a live spreadsheet (Excel-style), each able to plug in your own local AI.
Everything — editor, spreadsheet engine, formula evaluator, DOCX/XLSX/CSV codecs, persistence — is plain JavaScript running in your browser. There is nothing to install and nothing to serve: open the HTML and it runs.
This is plain HTML/CSS/JS. Open a file and it runs:
open dist/index.html # standalone build — 4 self-contained files, zero deps
# or open the source tree directly:
open index.html # launcher (docs.html / sheets.html / settings.html)
Everything runs from file:// (verified: all pages load with zero errors;
storage is IndexedDB, the optional AI call reaches your local Ollama endpoint).
No web server, no npm, no install — double-click is the whole setup.
Optional extras (dev/test only, never needed to use the app):
python3 serve.py # HTTP origin for the Playwright probes (:8220)
npm test # jsdom unit suite (dev-only dependency)
npm run build # regenerate dist/ from source when you change code
dist/ is committed from the same packer the CI runs (inline everything per
page, no CDN, no network — a git clone is the app).
Both apps have a File menu (New / Open library / Open from disk / Save / Save As where you pick the exact location on disk / Export / Print-PDF) and an AI Settings link in the top bar — like Word/Excel, but fully local.
Runs in Safari, Chrome, Edge, Firefox. No build step, no dependencies, no network access needed after the page loads.
- Rich-text WYSIWYG editing: headings (H1–H3), bold/italic/underline/strike, text color, highlight, font family/size, left/center/right/justify alignment, bulleted & numbered lists, tables, hyperlinks, superscript/subscript.
- Table editing: add/delete rows and columns (above/below/left/right) and delete whole tables, from the Insert menu or right-click menu.
- Change case: uppercase, lowercase, Title Case, and Sentence case on any selected text (Format menu / right-click).
- Undo / redo, live word / character / paragraph counts.
- Save / Open documents in a local browser library (IndexedDB).
- Export / Import: DOCX (real WordprocessingML), HTML, TXT.
- AI Assist panel (see AI below): continue writing, improve, summarize, fix grammar, more formal/casual, shorten — with Insert / Replace-selection.
- Virtualized grid (up to 500,000 rows × 500,000 cols), column/row headers that stay fixed while scrolling, multi-sheet tabs (add/rename). Lazy sparse layout: only user-resized rows/cols are tracked, so default-size sheets scale without materializing huge offset arrays.
- Live formula engine (from scratch): a broad Excel-compatible library —
aggregates (
SUM AVERAGE COUNT COUNTA COUNTBLANK MIN MAX PRODUCT LARGE SMALL MEDIAN MODE GEOMEAN HARMEAN PERCENTILE PERCENTRANK.INC QUARTILE VAR STDEV CORREL COVARIANCE.P/S DEVSQ SKEW KURT TRIMMEAN STANDARDIZE NORM.* REGRESSION SLOPE INTERCEPT RSQ STEYX FORECAST.LINEAR), criteria (SUMIF COUNTIF AVERAGEIF SUMIFS COUNTIFS AVERAGEIFS IFERROR IFNA ISERROR ISNA ISERR NA ERROR.TYPE), lookups (VLOOKUP HLOOKUP XLOOKUP XMATCH INDEX MATCH CHOOSE INDIRECT OFFSET ADDRESS ROW COLUMN ROWS COLUMNS), array/dynamic functions (UNIQUE SORT FILTER SEQUENCE TRANSPOSE TAKE DROP CHOOSECOLS CHOOSEROWS TEXTSPLIT), math/trig (ROUND ROUNDUP ROUNDDOWN ABS SQRT POWER MOD INT FACT COMBIN GCD LCM CEILING FLOOR CEILING.MATH FLOOR.MATH MROUND QUOTIENT SQRTPI MULTINOMIAL BASE DECIMAL TRUNC EXP LN LOG LOG10 SUMSQ SUMX2MY2 SUMX2PY2 SUMXMY2 SUBTOTAL SIN COS TAN ...), text (CONCAT TEXTJOIN LEFT RIGHT MID LEN UPPER LOWER TRIM SUBSTITUTE SEARCH FIND REPLACE VALUE NUMBERVALUE DOLLAR FIXED CHAR CODE UNICHAR UNICODE CLEAN TEXTBEFORE TEXTAFTER PROPER T N), logic (IF IFS SWITCH AND OR NOT XOR ISEVEN ISODD ISLOGICAL), date/time (TODAY NOW DATE DATEVALUE DATEDIF EDATE EOMONTH WEEKDAY WEEKNUM ISOWEEKNUM NETWORKDAYS WORKDAY YEARFRAC DAYS360 YEAR MONTH DAY HOUR MINUTE SECOND DAYS TIME TIMEVALUE), and financial (PMT FV PV NPER NPV IPMT PPMT). Implements an Excel error model (#DIV/0! #N/A #VALUE! #REF! #NAME? #NUM! ...propagate through operators and aggregates),*/?wildcard matching in criteria and lookups, and array-aware operator broadcasting (e.g.A1:A3>1yields a per-cell boolean array for FILTER/SUMPRODUCT). Supports cell refs, ranges, arithmetic/comparison/concat operators,Sheet1!A1cross-sheet references, and relative-reference shifting on paste. - Undo / Redo (Ctrl+Z / Ctrl+Shift+Z / Ctrl+Y), column/row resize by dragging header edges, fill-handle drag-fill (numeric series or copy), Find/Replace across cells.
- Cell formatting: bold/italic/underline, text color, fill, alignment, number formats (General, Number, thousands, currency, percent, date), merge cells, AutoSum.
- Conditional formatting: highlight cells by value rules (greater/less/ equal/between/not between), text-contains rules, or a 3-stop color scale, with custom text/fill colors. Rules apply to a range and update live.
- Data validation: dropdown lists, whole-number / decimal ranges, and text-length limits. Cells that violate a rule get a red-corner warning marker.
- Freeze panes: pin the top N rows and/or left N columns while scrolling.
- Copy / paste with relative formula reference shifting.
- Save / Open workbooks in the local library.
- Export / Import: XLSX (real SpreadsheetML, styles preserved),
CSV (active sheet;
.tsvsupported). - AI Assist: explain a formula, suggest a formula from a natural-language description, data insights, data-cleaning suggestions. Double-click an AI "=FORMULA" answer to apply it to the selected cell.
Both apps have an AI Assist panel wired to any OpenAI-compatible chat endpoint. Nothing leaves your machine by default — it points at your local Ollama.
Open AI Settings (top-right) and configure:
- Base URL — default
http://localhost:11434/v1. Works with Ollama, LM Studio, vLLM, llama.cpp, oMLX, a DGX box, etc. - Model — the "Refresh model list" button enumerates models from the endpoint; pick one.
- Temperature and system prompt (optional).
Click Test connection to confirm. The apps auto-save your settings in
localStorage.
Fully offline? Point Base URL at your local model server and the suite has zero external dependencies.
Files under assets/js/ are self-contained modules (loaded via <script>):
zip.js/readzip.js— dependency-free ZIP writer/reader (nativeDecompressionStream; STORE + DEFLATE). No third-party zip library.docx.js— DOCX codec (write+read) for Word processing XML.xlsx.js— XLSX codec (write+read) with a dynamic style builder.formulas.js— spreadsheet formula tokenizer/parser/evaluator + function registry.storage.js— IndexedDB persistence (documents + workbooks).ai.js— OpenAI-compatible chat client (list/generate/stream).docs-app.js,sheets-app.js,settings-app.js— app logic.
Documents and workbooks persist in your browser's IndexedDB (graith-office
database). Autosave happens on edit (and on workbook change); "Save" writes to
the local library. Export to disk to share a .docx / .xlsx.
node tests/formulas.test.cjs # formula engine unit tests (239 checks)
npm test # all jsdom suites (615 checks)
npm run probe # Playwright browser probes (needs :8220 up)
Honest technical documentation lives in docs/ (gitignored directory —
force-added to the repo):
docs/ARCHITECTURE.md— subsystem contracts (editor, canvas grid renderer, formula engine, codecs, storage, AI client, menus) and an Explicit limits table with file:line citations for every cap.docs/TEST_REPORT.md— what was tested, per-suite counts, how to regenerate.docs/GRIDLINE-COMPARISON.md— the Gridline comparison and what was adopted.
Key caps (full table with file:line in docs/ARCHITECTURE.md):
- Sheets grid is virtual — 500,000 rows × 500,000 columns; only the visible area is painted.
- Dynamic-array spill is capped at 10,000 cells; merged areas cap at 65,536 cells; sheets undo stack caps at 60 entries; saved-version history ring caps at 10 entries.
- Formula engine has no
eval(AST parser); ~213 functions, no LET/LAMBDA, no iterative solvers (RATE/IRR), no pivot functions. - DOCX/XLSX write and read support the common subset (paragraphs, headings, inline formatting, tables, lists, cells, formulas, styles). Exotic features (sections, images, charts authored in Office) may not perfectly round-trip — the data and text always do. Spilled array results export as a single formula cell, not as separate cells.
- Grid virtualization renders the visible area only; very large files can be slow to scroll on the first pass but remain fully editable.
This lives inside the tools/ area of the main Downloads repo. Serve it and
open the launcher to get started.