Open-source project
AhmadHassan-BTed/Ledgerify avatar
AhmadHassan-BTed/Ledgerify

Ledgerify: a browser-only Shopify ledger analytics dashboard in React

Shopify Excel Ledger intelligence platform with dark aesthetic, multi-sheet workbook analysis, 7 departmental dashboards, and live comparative benchmarking.

2,644 stars0 forksTypeScriptLicense varies

At a glance

What is it?
Ledgerify parses Shopify Excel exports in the browser with SheetJS, normalises the messy schema, and serves eight departmental dashboards without a backend. It suits an operator who wants order-level analytics that never leaves the machine, and the cost is a licence that is not clearly stated and a dependency on the export's own columns.
Who is it for?
Ledgerify suits an operator or analyst who works from Shopify Excel exports and wants finance, inventory, marketing and executive views computed locally without uploading customer data anywhere. It does not suit a team that needs multi-user access, scheduled reports or a stable published contract, since there is no server component and no GitHub release to pin.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 10 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The workbook never leaves the browser

Ledgerify is a browser-native analytics platform for Shopify Excel exports, and its defining constraint is that there is no backend at all. The project describes a zero-backend architecture, and the privacy rule it calls Zero-Knowledge Privacy says computation is entirely client side: workbooks are parsed in memory, cached in browser IndexedDB, and never transmitted over the network. That is a genuinely different proposition from the hosted analytics tools a shop might otherwise use, because the ledger contains order numbers, customer names, emails, cities and provinces. The application layer confirms the same idea, describing an Obsidian dark interface, browser-native SheetJS parsing, dynamic schema normalization and a dependency injection container as the pieces that turn multi-megabyte spreadsheets into domain intelligence. The stated purpose is to give leaders and operators synthesised conclusions rather than raw tables.

Eight services, one container, eight views

The architecture diagram in the project description shows a client layer, a service layer and a presentation layer, and the service layer is where the departmental structure lives. The IoC container resolves eight domain services: ExecutiveService, FinanceService, InventoryService, OperationsService, MarketingService, CreativeService, AdminDataQualityService and CompareService. Business logic sits in those decoupled domain services and is injected rather than imported, which is the second of the project's stated engineering pillars, the first being a strict separation between parsing, storage, metric calculation and presentation. In the presentation layer, React Context providers feed departmental view controllers, which drive the interactive visualisations and drill-downs. Note the small inconsistency in the project's own description: the repository summary talks about seven departmental dashboards while the architecture lists eight services, one of which is the data quality service rather than a business department. Eight is the number the code shows.

Header fuzzy matching is what makes the pipeline work

The normalisation pipeline is the part that determines whether the tool is useful on a real export, and the project describes its stages precisely. A raw workbook buffer goes to workbook sheet discovery, then to header fuzzy normalisation, then to value sanitisation and type coercion, then to compound bundle splitting, then to flag and anomaly tagging, and finally into the NormalizedOrder schema. The transformation rules attached to those stages say header matching is case and whitespace agnostic regex matching, Excel serial dates are converted to ISO UTC, compound bundles are split so individual bottles are extracted from Discovery and Trio sets, and the anomaly pass identifies zero dollar test orders, missing emails and spike quantities. In other words, the pipeline is not doing schema mapping against a fixed template, it is guessing the columns. That is what makes it survive exports from different stores, countries and export configurations, and it is also the part that will misfire silently on a column it reads differently than you expect.

What a real export actually looks like

The repository includes a requirements.txt that was used to inspect a sample workbook, and it shows the shape of the data better than any description would. The sample file is a UK orders workbook, and the sheet names read as Summary, Ledger, Trio and Discovery, then a repeating pattern of Aug, Sep and Oct with a Ledger and a Summary sheet for each, followed by Returning Cust. and Refunds. The Ledger sheet carries columns such as Order #, Customer Name, Email, City, Province/State, Country, Fragrance(s) Ordered, Order Quantity, Order Value, Status, Date, Has Trio, Has Discovery, Trio Qty, Trio Amount, Discovery Qty, Discovery Amount, 50ml Qty and Amount, and 100ml Qty and Amount. The Summary sheet, by contrast, reads as four unnamed columns, with the first row holding a title and the second a note that testing and dev orders and zero value orders are excluded from the figures below. Any normalisation rule you rely on has to cope with that mix of well named and unnamed columns.

Checking an export before you trust a dashboard

The inspection script in requirements.txt is the fastest way to see whether a given export will parse cleanly, and it is worth running before loading anything into the app. It uses pandas to open the workbook, print the sheet names, and then for each sheet print the columns and the first rows:

python
import pandas as pd

xls = pd.ExcelFile('UK Orders.xlsx')
print("Sheets:", xls.sheet_names)

for sheet in xls.sheet_names:
    df = pd.read_excel('UK Orders.xlsx', sheet_name=sheet)
    print(f"\n--- Sheet: {sheet} ---")
    print("Columns:", df.columns.tolist())
    print("Head:\n", df.head(2))

What you get back is the sheet list and the real column names, which is exactly the input the normaliser needs. If a sheet comes back with a different set of headers than the ones the pipeline was written against, that is the moment to know, not after a dashboard has produced a confident number.

A Vite and React app with an unusual dependency list

The build is a conventional Vite project with React 18 and TypeScript, and the package scripts are the standard three. The dev script runs the Vite dev server, the build script runs the TypeScript compiler and then Vite, and the preview script serves the built output. The dependency list explains what each part of the interface does. SheetJS under the name xlsx does the spreadsheet parsing, recharts draws the charts, lucide-react supplies the icons, date-fns handles the date work, clsx and tailwind-merge handle conditional class names, simple-statistics provides the statistics, and canvas-confetti is there for celebration effects, which says something about the intended audience. The styling is Tailwind, with the config in tailwind.config.js and the PostCSS config alongside it, and the TypeScript settings live in tsconfig.json. There is no test script, no lint script and no server dependency in the manifest.

Licence and release status are the weak points

Two facts here deserve attention before you build a workflow on this. First, the licence is not stated cleanly. The repository has no recognised licence, the package.json names ISC as its licence, and the README badge points to an MIT LICENSE file, which are two different grants with different obligations. Since the project has no published GitHub releases, there is also no tagged version to pin, and the package manifest sits at version 1.0.0. The last push was on 2026-10-13, so the work is current, and a CHANGELOG and a TODO file sit in the repository root next to an ARCHITECTURE.md that the README points to for the class diagrams, normalisation rules and state management flow. The honest summary is that this is an actively developed project with an unresolved licence question, and the licence question is the one to settle first.

Editorial conclusion

Ledgerify suits an operator or analyst who works from Shopify Excel exports and wants finance, inventory, marketing and executive views computed locally without uploading customer data anywhere. It does not suit a team that needs multi-user access, scheduled reports or a stable published contract, since there is no server component and no GitHub release to pin. Before adopting it, check the licence, which package.json names as ISC while a README badge points to an MIT LICENSE file, and look at a real export's sheet names, because the normalization rules were written against workbooks with a Summary sheet, a Ledger sheet and per-month pairs.

Frequently asked questions

Does Ledgerify send my Shopify export to a server?

No. The project describes a zero-backend architecture where workbooks are parsed in memory, cached in browser IndexedDB and never transmitted over the network. All computation happens in the browser.

How do I run Ledgerify locally?

The package manifest defines a dev script that runs vite, a build script that runs tsc and then vite build, and a preview script that serves the built output. The project also publishes a live demonstration and a system architecture document at the root of the repository.

Which libraries does Ledgerify use to read the Excel file?

Parsing is done with SheetJS, listed in the dependencies under the name xlsx at version 0.18.5. Charts come from recharts, icons from lucide-react, dates from date-fns and statistics from simple-statistics, all in a React 18 and TypeScript 5 project built with Vite and Tailwind.

What does the normalisation pipeline do with a Shopify export?

It discovers the workbook sheets, matches headers with case and whitespace agnostic regex, coerces values including converting Excel serial dates to ISO UTC, splits compound bundles into individual bottles, and tags anomalies such as zero value test orders, missing emails and spike quantities, before producing the NormalizedOrder schema.

Official sources

  1. AhmadHassan-BTed/Ledgerify on GitHub
  2. Issues
  3. Project website
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/ahmadhassan-bted-ledgerify.svg)](https://hysenlabs.com/projects/ahmadhassan-bted-ledgerify)

Was this useful?