Aggr: a browser side crypto trade tape across sixteen exchanges
Cryptocurrency trades aggregator
At a glance
- What is it?
- Aggr is a Vue application that connects to sixteen exchange WebSocket APIs, aggregates the raw trade tape in a Worker per exchange and charts the result live in the browser, with historical data supplied by a separate server project. It suits a trader who wants to watch flow on several venues at once, and the browser only gets trades, not order books.
- Who is it for?
- Aggr fits someone who watches the crypto tape and wants one view across several venues, because the per exchange Worker keeps the aggregation off the main thread and the result is a single chart rather than sixteen tabs. Skip it if you need order book depth or a proper trading terminal, since the documentation is explicit that only trades data is charted, and note that the historic tape requires a separate aggr-server instance, so a browser-only install starts empty.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 170 days ago.
- What is it written in?
- Mainly Vue, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Sixteen venues, one tape
Aggr, which the README also calls SignificantTrade, is a cryptocurrency market trades aggregator, and the exchange list is the scope of the project stated plainly.
Currently supporting Kucoin, BitMEX, Bitfinex, Binance, Coinbase, Bitstamp, Deribit, Huobi, Okex, Hitbtc, Poloniex, Bybit, Bitget, Bitunix, Gate.io and Crypto.com, with a pointer to `src/exchanges/` for the detail on each one.
Sixteen venues is a meaningful amount of integration work, because each exchange has its own WebSocket message format, its own symbol naming, its own sequence numbering and its own quirks around what counts as a trade. The directory per exchange in the source tree is the right shape for that, since the differences between the integrations are the thing that actually needs to be maintained.
The set of venues also tells you something about the audience. The list spans the major western venues, the derivatives venues, and a substantial number of the venues popular in Asia and in the wider crypto community, and it is the kind of list that changes over time as venues open and close.
What the tool does with that data is the interesting part. It shows market orders live on the crypto markets of your choice, it filters noise by aggregating trades with the same timestamp, it calculates rolling sums over defined periods, it charts whatever is received from the API so only trades data for now, and it produces dynamic audio based on trade volume and size.
That last feature is unusual and worth flagging. Sound driven by trade flow is a thing you either find useful or distracting, and it is unusual enough in a charting tool that it tells you the author built this for watching, not for a desk.
The project is written in Vue, the licence is GPL-3.0, and the deployed site is at charts.aggr.trade.
One Worker per exchange, aggregation before it reaches the chart
The architectural description in the documentation is short and it is the part that explains the design.
The application is developed using Vue.js and utilizes the JavaScript WebSocket interface to establish connections with exchange APIs and listen for trade events. The core functionality involves an aggregator that processes raw trades within a dedicated Worker for each Exchange. The aggregator's main objective is to group trades based on time, market, and trade side. Periodically, the worker sends the aggregated trades to the user interface, accompanied by relevant statistics regarding market activity, and those statistics include volume sums, trade counts categorized by sides, and information about liquidations.
The grouping key is the interesting design decision. Grouping by time alone would merge a buy and a sell that happened at the same instant, which is the opposite of what you want when reading flow. Grouping by market, time and side gives a tape where a burst of buying at one moment stays distinguishable from a burst of selling, which is the whole point of watching a trade tape.
Putting the work in a Worker per exchange is the other decision that matters. Sixteen WebSocket feeds each delivering a message rate that depends on how busy the venue is, is a lot of parsing and grouping to do on the main thread, where it would block rendering and make the chart stutter exactly when the market is most active. A Worker per exchange means the aggregation happens off the UI thread, and the UI receives a periodic summary instead of a message storm.
The dependency list backs the picture. `protobufjs` is there because some venues deliver binary trade frames rather than JSON, and `pako` is the zlib implementation, which is what you need to inflate a compressed websocket payload. `idb` is an IndexedDB wrapper, so state survives a reload without a server. `lightweight-charts` is the charting library, and notably it is pulled from the author's own fork of the upstream repository at a pinned commit, which is worth knowing if you read the source and find behaviour that does not match the upstream documentation.
There is also `monaco-editor` and `marked`, and `vue-grid-layout` for a draggable panel arrangement, which tells you the application is a workspace of movable panels rather than a single chart.
A Vue 2 application with a forked charting library
The dependency list in the manifest describes the stack, and there is one detail in it that a reader should know about before digging in.
Vue is pinned at `^2.7.13`, with `vue-class-component`, `vue-property-decorator` and `vue-template-compiler` alongside it, and `vuex` at `^3.6.2` for the state. Vue 2 with the class component decorators is the older style of building a Vue application, and 2.7 is the final release of that line, which means the project is on a platform that receives no further feature work upstream. That is a normal choice for an application rather than a library, since the application only has to keep working, not keep improving, but it does explain some of the choices further down the list.
The Vite setup is the interesting counterpoint. `vite` at `^4.4.9` with `@vitejs/plugin-vue2` is a modern build tool driving the older framework, and the plugin exists precisely to make that combination work. The `vite-plugin-comlink` dependency is for sharing a worker across tabs, which is the natural companion to a design where each exchange has a Worker, since two tabs of the same application watching the same pair should not open two sets of WebSocket connections to the exchange.
The charting library is the detail that will surprise anyone comparing the source with the upstream documentation. `lightweight-charts` is not taken from npm but from a git URL, a fork in the author's own GitHub account at a pinned commit hash:
"lightweight-charts": "git+https://github.com/Tucsky/lightweight-charts.git#3ac7ebd731452fb0d9967905e10128b20409b7d7"Pinning a commit rather than a tag is the right thing to do for a fork you depend on, since a branch reference would move under you. But it also means the application depends on changes that are not in the upstream library, so behaviour you see in the app may not match the upstream documentation for the same library. If you are going to read the code, read the fork.
The remaining dependencies explain the rest of the interface. `monaco-editor` is the code editor component, `marked` renders Markdown, `axios` handles the HTTP calls that go through the proxy, `pako` inflates compressed payloads, `protobufjs` decodes the binary frames some venues send, `idb` persists state in IndexedDB, `eventemitter3` is the event bus, `color-fns` handles colour manipulation for the chart, and `lodash.merge` and `@mdi/font` are small utilities.
The development tooling is ordinary and modern. ESLint at version 8 with the vue eslint config, Prettier with the eslint plugin, and a `.browserslistrc` for the browser targets. There is a `conf/` directory, a `docs/` directory, a `docker/` directory and a `scripts/` directory holding the Volta installer, the cors server, the svg2font script and the GitHub Pages deploy script.
Running it locally, and the proxy that makes it work
The installation instructions start by recommending Volta, a node and npm version manager, and the project ships a script to automate its installation, which is compatible with the bash shell and therefore available on all major operating systems including Windows, macOS and Linux:
./scripts/install-volta.shThen the ordinary steps. Clone the repository, install the dependencies, run it:
git clone https://github.com/Tucsky/aggr
npm installFor development there are two commands, and the order matters. `npm run cors` starts a cors proxy for your development environment, and `npm run serve` will automatically open a browser window at localhost:8080.
The proxy is not optional in the general case, and understanding why explains a lot about the project. The application talks directly to exchange WebSocket APIs from the browser, but the HTTP endpoints it needs, such as the Binance product list, are subject to the browser's same origin rules. The `PROXY_URL` setting redirects HTTP requests from the app through a proxy, and the documented example is setting it to `https://cors.aggr.trade/`, in which case the app retrieves Binance's products through that url, `https://cors.aggr.trade/https://api.binance.com/api/v3/exchangeInfo`.
So the shipped deployment has a public CORS proxy that other people's deployments can point at, and the default `PROXY_URL` points at the local development proxy on http://localhost:8080/.
There is also a `cors-anywhere` package in the dev dependencies, which is the same idea, a proxy that forwards requests and relaxes the origin rules, and the local `cors` script runs `node scripts/cors-server.mjs`.
The build path is `npm run build`, and the documentation says you can then access the dist/index.html directly in the browser later without having to run a command. The `prod` script does more work, running `vue-tsc --noEmit` for a type check before building into a temp directory and swapping it into place, and there is a separate `serve:dist` script that runs the built server from `dist-server/`, which is the historical data server.
Historical data needs a second project
The split between the client and the server is the last structural thing to understand, and it is easy to miss.
You can use this project without historical data just by opening the app in your browser, as getting trades from exchanges is made directly in the browser using websocket api. But in order to show historical data you will need to set up your own server to provide the data using aggr-server, and the documentation links the aggr-server repository for that.
So there are two projects. The client you are looking at is the live side, and it is self sufficient for watching the tape as it happens. The historic tape, the chart of what happened before you opened the page, comes from a server that you have to run yourself, and the `API_URL` setting points at it, with the default example being http://localhost:3000/.
The `API_URL` description spells out the role: it is the server instance url, used to fetch historical data for the chart component, with the default value null.
That is a sensible division, since the live feed and the historical store have completely different requirements. The live feed is a WebSocket per exchange and belongs in the browser next to the chart. The historical store is a database and a polling process and belongs on a server. The cost is that a user who wants a populated chart on first load has two things to deploy rather than one.
The documentation gives the concrete invocation for that case. If you have a server instance running on port 3000, start the client with the environment variable `API_URL=http://localhost:3000/ npm run serve`.
The Docker path follows the same logic. You can build your own aggr client with `docker-compose -f "docker\docker-compose.yml" up -d --build` for production, and if you want to use aggr-server as your local data source, load the docker-compose.dev.yml instead.
That the server is a separate repository with its own name rather than a directory in this one is the clearest signal that the two have different deployment lives, and that the client is designed to work without the server.
Editorial conclusion
Aggr fits someone who watches the crypto tape and wants one view across several venues, because the per exchange Worker keeps the aggregation off the main thread and the result is a single chart rather than sixteen tabs. Skip it if you need order book depth or a proper trading terminal, since the documentation is explicit that only trades data is charted, and note that the historic tape requires a separate aggr-server instance, so a browser-only install starts empty. Before you run it, read the disclaimer, which says to use real money at your own risk, and check the exchange list against the venues you trade on. The last push was on 2026-05-06, the manifest version is 3.8.3 and the last tagged release was v3.5.5 in 2024.
Frequently asked questions
Which exchanges does Aggr support?
Kucoin, BitMEX, Bitfinex, Binance, Coinbase, Bitstamp, Deribit, Huobi, Okex, Hitbtc, Poloniex, Bybit, Bitget, Bitunix, Gate.io and Crypto.com, with the per venue detail in the src/exchanges directory.
How does Aggr aggregate the trade tape?
A dedicated Worker per exchange groups raw trades by time, market and trade side, then periodically sends the aggregated trades to the interface with statistics on volume sums, trade counts per side and liquidations.
Do I need a server to run Aggr?
Only for historical data. The live tape works directly in the browser over WebSocket, but showing historic data requires running aggr-server yourself and pointing the API_URL setting at it, for example http://localhost:3000/.
How do I run Aggr in development?
Install Volta with `./scripts/install-volta.sh`, clone the repository, run `npm install`, then start the cors proxy with `npm run cors` and the app with `npm run serve`, which opens a browser at localhost:8080.
What does the Aggr project not do?
It charts trades data only, not order books, and the README says the tool is for watching rather than for a trading desk. The disclaimer says that if you plan to use real money with this, use it at your own risk, and the licence is GPL-3.0.
Official sources
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.
[](https://hysenlabs.com/projects/tucsky-aggr)Was this useful?