Skip to content

Per-component imports in oks-ui: what they really save, measured

Published · Updated · Last reviewed · by Omkar Sahu

A dark code editor window with a per-component import highlighted, and a tick below it.
ShareXLinkedIn
On this page
  1. The short answer
  2. How we measured
  3. JavaScript: no difference
  4. CSS: where per-component imports pay off
  5. What we recommend now
  6. Measure your own app

A component library should cost you only the components you use. We wanted to know whether oks-ui does, so we measured it: the published package, two bundlers, three versions. The answer was not what this post used to say.

Correction. An earlier version of this post said that importing from oks-ui ships the whole library, and that per-component imports cut this website's JavaScript by about a fifth. After re-measuring on 7 October 2026, that is not true: both import styles produce the same JavaScript, in 1.2.2, 1.3.2 and 1.4.1. The CSS difference is real, and it is described below. We have also removed the figures that were quoted for this website's own bundle, because we could not reproduce them. The numbers in this post replace the old ones.

The short answer

  • JavaScript: the same either way. import { Button } from "oks-ui" and from "oks-ui/button" give the same bundle in esbuild and in Rollup.
  • CSS: this is where the choice matters. The single stylesheet is 56.2 KB gzipped however few components you use. Per-component stylesheets start at 11.7 KB for a Button, and in our test set they stayed below the single sheet until about 19 components.
  • Your mix matters more than your count. Six components carry more than 100 KB of CSS each. Using one of them moves the numbers a lot.

How we measured

Everything below was measured on the published npm package, not on the source:

  • oks-ui 1.4.1, with 1.2.2 and 1.3.2 for the comparison over time, installed from npm.
  • JavaScript: esbuild 0.28.2, and Rollup through Vite in library mode. React and React DOM were left external, so the numbers are oks-ui's own code. Minified, then gzipped at level 9.
  • A small entry file imports the components and logs them, so nothing is removed as unused.
  • CSS: the stylesheets as shipped in the package, joined together and gzipped at level 9. We measured CSS separately, because bundlers treat stylesheets as side effects and never remove unused ones.
  • Not measured: webpack, Turbopack, real page weights, or how long a page takes to render.
Advertisement

JavaScript: no difference

For a Button alone, the two import styles gave files within two bytes of each other. For Button, Modal and Table together they were identical.

What you import (oks-ui 1.4.1, esbuild)Minified (KB)Gzip (KB)
Button, from oks-ui/button14.55.7
Button, from oks-ui14.55.7
Button, Modal and Table, from their own paths151.541.3
Button, Modal and Table, from oks-ui151.541.3
The whole library (import * as ui)535.2164.6

Rollup, through Vite's library mode, gave different absolute sizes (253.5 KB minified and 51.5 KB gzipped for the three components), but again the two import styles matched to within about a hundred bytes of gzip.

This works because the package declares that only its CSS files and one styles file have side effects (the sideEffects field in its package.json). A bundler is then free to drop every export you do not use.

The library itself has grown. The whole library, minified, by version:

oks-ui versionMinified (KB)Gzip (KB)
1.2.2409.2121.5
1.3.2409.3121.7
1.4.1535.2164.6

That is about 31 percent more JavaScript between 1.3.2 and 1.4.1, as TreeView, Rating and a much larger TextEditor arrived. The cost of a Button did not change in any of the three versions.

The earlier version of this post gave "around 770 KB" for the whole library. We could not reproduce that number in any version. The closest figures are 409 KB in 1.2.2 and 535 KB today.

CSS: where per-component imports pay off

oks-ui/styles.css is not a stylesheet of its own. It is three imports: tokens (30.3 KB), utilities (29.8 KB) and components (362.7 KB). Together that is 422.7 KB raw, 56.2 KB gzipped, or 42.7 KB with Brotli, whether you use one component or all 38.

Each component also has its own stylesheet. These are not slices of the big one: a component's sheet includes the styles of the components it is built from. Button's sheet starts with the Tooltip's rules, and the sheets for Table, Chart, TextEditor and Rating each repeat Button's rules. Add all 38 per-component sheets together and you get 1.28 MB raw, about 3.5 times the single components sheet.

So the saving depends on what you use. Here is the CSS for a growing set of common components, each row with tokens.css and utilities.css included (about 60 KB raw and 7.7 KB gzipped together; utilities are optional):

Components usedAddedRaw (KB)Gzip (KB)
1Button80.311.7
2Alert86.912.5
3Badge95.013.3
5Avatar, Modal127.216.3
8Tabs, Tooltip, Dropdown154.418.4
10Table, Toast330.938.3
12Progress, Accordion337.339.2
15Drawer, Pagination, Breadcrumbs357.741.4
19Card, FormFieldSet, Chip, Loader534.560.1
All 38, through styles.css422.756.2
A line chart of CSS size in kilobytes, gzipped, rising from 11.7 at one component to 60.1 at nineteen, crossing a dashed line at 56.2 that marks the single stylesheet.

CSS gzipped, by number of components used, against the single styles.css (dashed). Measured on oks-ui 1.4.1.

The jump at ten components is Table: its sheet alone is 167 KB raw. The line crosses the single sheet at nineteen, after FormFieldSet joins. The sizes of the individual sheets explain the shape:

A table of stylesheet sizes by component: TextEditor 213.5 KB raw, Chart 186.3, Table 167.2, SteppedForm 161.1, Rating 159.9, then Button 20.3, Modal 12.9 and Alert 6.6.

The five largest per-component stylesheets, then three small ones. Sizes in kilobytes.

Twenty-five of the 38 sheets are under 10 KB. Six are over 100 KB: FormFieldSet, Rating, SteppedForm, Table, Chart and TextEditor.

What we recommend now

  1. Import JavaScript however reads best. oks-ui and oks-ui/button cost the same.
  2. If your app uses a handful of small components, import each component's stylesheet. That is the 12 to 19 KB case, against 56 KB.
  3. If you use Table, Chart, TextEditor, SteppedForm, Rating or FormFieldSet together with many other components, measure both ways. In our set the single sheet was the smaller one from about nineteen components.
  4. Load tokens.css once, at the root of your app. Both approaches need it.

Measure your own app

The script below measures the JavaScript for whatever imports you put in it. Run it with node in a project that has oks-ui and esbuild installed.

import { build } from "esbuild";
import { gzipSync } from "node:zlib";

const cases = {
  "Button, own path": `import { Button } from "oks-ui/button"; console.log(Button);`,
  "Button, main entry": `import { Button } from "oks-ui"; console.log(Button);`,
};

for (const [name, code] of Object.entries(cases)) {
  const result = await build({
    stdin: { contents: code, resolveDir: process.cwd(), loader: "js" },
    bundle: true,
    minify: true,
    write: false,
    format: "esm",
    external: ["react", "react-dom", "react/jsx-runtime"],
    loader: { ".css": "empty" },
    logLevel: "silent",
  });
  const bytes = result.outputFiles[0].contents;
  console.log(name.padEnd(22), bytes.length, "bytes,", gzipSync(bytes, { level: 9 }).length, "gzip");
}

For CSS, join the .css files you import from node_modules/oks-ui/dist and gzip them together, or read the size of the CSS in your build output. See both import styles in the installation guide.

Advertisement

Omkar Sahu

I'm a front-end engineer based in Hyderabad, India, with more than 17 years of professional experience. I spent 12 years as a senior front-end developer, designing and building websites, and I have worked as a full-stack developer since 2022. I created oks-ui, a React component library with no runtime dependencies, and I write and maintain this site.

More about Omkar Sahu · All posts

Was this post helpful?

ShareXLinkedIn