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
7 changes: 7 additions & 0 deletions .github/badges/core-size.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"schemaVersion": 1,
"label": "bundle size",
"message": "385 B gzip",
"color": "brightgreen",
"cacheSeconds": 3600
}
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,15 @@

Zero runtime, zero React re-renders, and a simple developer experience. <small>Say goodbye to context and prop-drilling.</small>

<a href="https://bundlephobia.com/package/@react-zero-ui/core@0.2.6" target="_blank" rel="noopener noreferrer"><img src="https://badgen.net/bundlephobia/minzip/@react-zero-ui/core@0.2.6" alt="bundle size" /></a> <a href="https://www.npmjs.com/package/@austinserb/react-zero-ui" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/npm/v/@react-zero-ui/core" alt="npm version" /></a> <a href="https://opensource.org/licenses/MIT" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT" /></a> ![CI](https://github.com/react-zero-ui/core/actions/workflows/ci.yml/badge.svg?branch=main)

[See the proof](/docs/demo.md) [Quick Start](#quick-start) [API Reference](/docs/api-reference.md) [Usage Examples](/docs/usage-examples.md) [Migration Guide](/docs/migration-guide.md) [FAQ](/docs/faq.md) [Contributing](#contributing)
<a href="https://github.com/react-zero-ui/core/blob/main/docs/size.md" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/react-zero-ui/core/main/.github/badges/core-size.json" alt="bundle size" /></a> <a href="https://www.npmjs.com/package/@react-zero-ui/core" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/npm/v/@react-zero-ui/core" alt="npm version" /></a> <a href="https://opensource.org/licenses/MIT" target="_blank" rel="noopener noreferrer"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT" /></a> ![CI](https://github.com/react-zero-ui/core/actions/workflows/ci.yml/badge.svg?branch=main)

[See the proof](/docs/demo.md) &nbsp;|&nbsp;
[Quick Start](#quick-start) &nbsp;|&nbsp;
[API Reference](/docs/api-reference.md) &nbsp;|&nbsp;
[Usage Examples](/docs/usage-examples.md) &nbsp;|&nbsp;
[Migration Guide](/docs/migration-guide.md) &nbsp;|&nbsp;
[FAQ](/docs/faq.md) &nbsp;|&nbsp;
[Contributing](#contributing)

</div>

Expand Down
29 changes: 29 additions & 0 deletions docs/size.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Bundle Size Proof

This repo measures bundle size from the built `@react-zero-ui/core` entry.

## Command

```bash
pnpm build
pnpm size
pnpm size:badge
```

The `size` script in [`package.json`](../package.json) runs:

```bash
npx esbuild ./packages/core/dist/index.js --bundle --minify --format=esm --external:react --define:process.env.NODE_ENV='"production"' | gzip -c | wc -c
```

That produces the gzipped byte count used for the README badge.

## Badge File

Run `pnpm size:badge` after a build when you want to refresh the badge JSON.

That writes:

- [`core-size.json`](../.github/badges/core-size.json)

The README badge reads from that committed file through a Shields endpoint.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@
"prepack:core": "pnpm -F @react-zero-ui/core pack --pack-destination ./dist",
"reset": "git clean -fdx && pnpm install --frozen-lockfile && pnpm prepack:core && pnpm i-tarball",
"size": "npx esbuild ./packages/core/dist/index.js --bundle --minify --format=esm --external:react --define:process.env.NODE_ENV='\"production\"' | gzip -c | wc -c",
"size:badge": "node scripts/write-size-badge.mjs",
"size:experimental-runtime": "sh -c 'out=$(mktemp); npx esbuild ./packages/core/dist/experimental/runtime.js --bundle --minify --format=esm --external:react --define:process.env.NODE_ENV=\"production\" > \"$out\" && cat \"$out\" && printf \"\\nExperimental runtime size: %s bytes\\n\" \"$(gzip -c \"$out\" | wc -c | tr -d \" \")\"'",
"test": "eslint . && cd packages/core && pnpm test:all && pnpm smoke",
"test:cli": "cd packages/core && pnpm test:cli",
"test:integration": "cd packages/core && pnpm test:integration",
Expand Down
34 changes: 34 additions & 0 deletions scripts/write-size-badge.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { execSync } from "node:child_process";
import fs from "node:fs";
import path from "node:path";

const outputPath = path.resolve(".github/badges/core-size.json");
const rawBytes = execSync("pnpm size", { encoding: "utf8" }).trim();
const match = rawBytes.match(/(\d+)\s*$/);
const bytes = match ? Number.parseInt(match[1], 10) : Number.NaN;

if (!Number.isFinite(bytes)) {
throw new Error(`Expected pnpm size to return an integer byte count, got: ${rawBytes}`);
}

const formatBytes = (value) => {
if (value < 1024) return `${value} B gzip`;
if (value < 1024 * 1024) return `${(value / 1024).toFixed(1).replace(/\\.0$/, "")} kB gzip`;
return `${(value / (1024 * 1024)).toFixed(1).replace(/\\.0$/, "")} MB gzip`;
};

const color = bytes < 512 ? "brightgreen" : bytes < 1024 ? "green" : bytes < 2048 ? "yellowgreen" : "yellow";

const badge = {
schemaVersion: 1,
label: "bundle size",
message: formatBytes(bytes),
color,
cacheSeconds: 3600,
};

fs.mkdirSync(path.dirname(outputPath), { recursive: true });
fs.writeFileSync(outputPath, `${JSON.stringify(badge, null, 2)}\n`);

console.log(`Wrote ${outputPath}`);
console.log(JSON.stringify(badge));
Loading