Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,52 @@ jobs:
if: steps.should-run.outputs.run == 'true'
run: pnpm --filter @wraith-protocol/test-vectors differential

bundle-size:
name: Bundle size (size-limit)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: dorny/paths-filter@v3
id: filter
if: github.event_name == 'pull_request'
with:
filters: |
src:
- 'src/**'

- name: Determine whether to run
id: should-run
run: |
if [ "${{ github.event_name }}" != "pull_request" ] || [ "${{ steps.filter.outputs.src }}" = "true" ]; then
echo "run=true" >> "$GITHUB_OUTPUT"
else
echo "run=false" >> "$GITHUB_OUTPUT"
fi

- uses: pnpm/action-setup@v4
if: steps.should-run.outputs.run == 'true'
with:
version: 10

- uses: actions/setup-node@v4
if: steps.should-run.outputs.run == 'true'
with:
node-version: 22
cache: pnpm

- name: Install dependencies
if: steps.should-run.outputs.run == 'true'
run: pnpm install --frozen-lockfile

- name: Build SDK
if: steps.should-run.outputs.run == 'true'
run: pnpm build

- name: Check bundle sizes
if: steps.should-run.outputs.run == 'true'
run: pnpm size

slow-tests:
name: Property fuzz (nightly)
runs-on: ubuntu-latest
Expand Down
88 changes: 54 additions & 34 deletions BUNDLE_SIZE.md
Original file line number Diff line number Diff line change
@@ -1,56 +1,76 @@
# Bundle Size BaselineStellar Entry
# Bundle Size BaselinesAll Public Exports

> Last measured: 2026-06-23
> Last measured: 2026-08-29
> Bundler: tsup (esbuild) via `size-limit`

## Current Size

| Format | Size (gzip) | Budget |
| ---------------- | ----------- | ------ |
| ESM (`import *`) | TBD | 20 KB |
| CJS (`require`) | TBD | 20 KB |

> TBD — run `pnpm build && pnpm size` after installation to populate
> actual measurements, then update this table.

## Dependency Graph

Generate a visual treemap of the Stellar entry's dependency graph:
> Sizes are **minified and brotli-compressed**, include all bundled
> dependencies, and are measured by `size-limit` (SI units: 1 KB = 1000 B).

## Current Sizes and Budgets

Every budget is the measured baseline **+ 15% headroom**, rounded up.

| Entry | Format | Baseline | Budget (+15%) |
| ------------------ | ---------------- | --------- | ------------- |
| Root (`.`) | ESM (`import *`) | 31.32 KB | 36.1 KB |
| Root (`.`) | CJS (`require`) | 138.79 KB | 159.7 KB |
| `./chains/evm` | ESM (`import *`) | 23.83 KB | 27.5 KB |
| `./chains/evm` | CJS (`require`) | 126.79 KB | 145.9 KB |
| `./chains/solana` | ESM (`import *`) | 17.15 KB | 19.8 KB |
| `./chains/solana` | CJS (`require`) | 25.89 KB | 29.8 KB |
| `./chains/ckb` | ESM (`import *`) | 20.52 KB | 23.6 KB |
| `./chains/ckb` | CJS (`require`) | 128.76 KB | 148.1 KB |
| `./vault` | ESM (`import *`) | 1.93 KB | 2.3 KB |
| `./vault` | CJS (`require`) | 2.07 KB | 2.4 KB |
| `./chains/stellar` | ESM (`import *`) | 26.48 KB | 30.5 KB |
| `./chains/stellar` | CJS (`require`) | 34.29 KB | 39.5 KB |

> Stellar note: the original 20 KB-per-format budget predated any actual
> measurement (the baseline had never been populated). The current Stellar
> bundle exceeds 20 KB, so its budget was re-baselined on 2026-08-29 using
> the same baseline + 15% rule as the other entries. Entry paths and options
> are unchanged.

## Checking Sizes (CI gate)

`pnpm size` checks **every** entry in the `size-limit` array of
`package.json` and exits non-zero if any budget is exceeded. CI runs it on
every PR that touches `src/` (see the `bundle-size` job in
`.github/workflows/ci.yml`).

```bash
ANALYZE=true pnpm build
# produces stats/ folder with metafile data
npx esbuild-visualizer --metadata stats/metafile-stellar.json --open
pnpm build # size-limit measures dist/ output, so build first
pnpm size
```

> `esbuild-visualizer` is an optional dev tool — install it globally or
> via `npx` when you need to inspect the graph.

## Measurement Commands
## Measuring / Debugging

### esbuild (tsup) — via size-limit (CI gate)
Machine-readable output (exact byte counts):

```bash
pnpm build
pnpm size
./node_modules/.bin/size-limit --json
```

### Vite-style bundling — standalone esbuild
Generate a visual treemap of an entry's dependency graph:

```bash
pnpm measure:vite
ANALYZE=true pnpm build
# produces stats/ folder with metafile data
npx esbuild-visualizer --metadata stats/metafile-stellar.json --open
```

Output written to `stats/vite-measurement.json`.
> `esbuild-visualizer` is an optional dev tool — install it globally or
> via `npx` when you need to inspect the graph.

## Budget Policy

The Stellar entry budget is **20 KB gzipped** for each format (ESM, CJS).

- If a PR increases the Stellar bundle beyond the budget, CI will fail.
- Reviewers should verify no non-Stellar code was introduced into
`src/chains/stellar/` by checking imports.
- To adjust the budget, update the `size-limit` array in `package.json`.
- Each entry's budget is its measured baseline + 15% headroom (see table).
- If a PR increases any bundle beyond its budget, CI fails.
- Reviewers should verify no cross-chain code was introduced (e.g. nothing
from `evm/`, `solana/`, `ckb/`, or `agent/` leaking into
`src/chains/stellar/`) by checking imports.
- To adjust a budget, update the `size-limit` array in `package.json` and
this table together, and note the reason in the PR description.

## Known Optimizations

Expand Down
62 changes: 60 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,19 +59,75 @@
"test:fuzz": "FC_RUNS=100000 vitest run test/chains/stellar/properties.test.ts",
"test:leak": "vitest run test/leaks/scan-leak.test.ts",
"test:heap-leak": "node --expose-gc ./node_modules/vitest/vitest.mjs run test/leaks/heap-snapshot.test.ts --pool=threads",
"size": "size-limit",
"api:check": "api-extractor run --config api-extractor.json && api-extractor run --config api-extractor-evm.json && api-extractor run --config api-extractor-stellar.json && api-extractor run --config api-extractor-solana.json && api-extractor run --config api-extractor-ckb.json && api-extractor run --config api-extractor-vault.json"
},
"size-limit": [
{
"name": "Root ESM (import *)",
"path": "dist/index.js",
"import": "*",
"limit": "36.1 KB"
},
{
"name": "Root CJS (require)",
"path": "dist/index.cjs",
"limit": "159.7 KB"
},
{
"name": "EVM ESM (import *)",
"path": "dist/chains/evm/index.js",
"import": "*",
"limit": "27.5 KB"
},
{
"name": "EVM CJS (require)",
"path": "dist/chains/evm/index.cjs",
"limit": "145.9 KB"
},
{
"name": "Solana ESM (import *)",
"path": "dist/chains/solana/index.js",
"import": "*",
"limit": "19.8 KB"
},
{
"name": "Solana CJS (require)",
"path": "dist/chains/solana/index.cjs",
"limit": "29.8 KB"
},
{
"name": "CKB ESM (import *)",
"path": "dist/chains/ckb/index.js",
"import": "*",
"limit": "23.6 KB"
},
{
"name": "CKB CJS (require)",
"path": "dist/chains/ckb/index.cjs",
"limit": "148.1 KB"
},
{
"name": "Vault ESM (import *)",
"path": "dist/vault/index.js",
"import": "*",
"limit": "2.3 KB"
},
{
"name": "Vault CJS (require)",
"path": "dist/vault/index.cjs",
"limit": "2.4 KB"
},
{
"name": "Stellar ESM (import *)",
"path": "dist/chains/stellar/index.js",
"import": "*",
"limit": "20 KB"
"limit": "30.5 KB"
},
{
"name": "Stellar CJS (require)",
"path": "dist/chains/stellar/index.cjs",
"limit": "20 KB"
"limit": "39.5 KB"
}
],
"dependencies": {
Expand Down Expand Up @@ -99,13 +155,15 @@
"@commitlint/config-conventional": "^19.6.0",
"@microsoft/api-extractor": "^7.58.12",
"@size-limit/esbuild": "^11.0.0",
"@size-limit/file": "^11.2.0",
"@solana/web3.js": "^1.98.4",
"@stellar/stellar-sdk": "^13.1.0",
"@types/node": "^20.19.43",
"fake-indexeddb": "^6.2.5",
"fast-check": "^4.8.0",
"husky": "^9.1.0",
"prettier": "^3.4.0",
"size-limit": "^11.0.0",
"tinybench": "^2.9.0",
"tsup": "^8.4.0",
"typedoc": "^0.28.19",
Expand Down
29 changes: 22 additions & 7 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading