Library / SDK
shuding/react-wrap-balancer avatar
shuding/react-wrap-balancer

react-wrap-balancer: A React Component for Balanced Title Wrapping

Simple React Component That Makes Titles More Readable

4,211 stars62 forksHTMLMIT

At a glance

What is it?
React Wrap Balancer is a small MIT-licensed component that rebalances headline line breaks at runtime. It suits marketing pages and article titles, and it is the wrong tool for long body copy or very old browsers.
Who is it for?
Adopt react-wrap-balancer for short display text: hero headlines, card titles, article headings, anywhere a single orphaned word on the last line looks wrong. Skip it for paragraphs and long-form body copy, since the component targets titles and the rebalance work is per element.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly HTML, according to GitHub's language statistics.

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

Editorial analysis

The orphaned-word problem react-wrap-balancer targets

Typography has a name for a last line holding one short word: a widow, or in looser usage a ragged line. On a wide viewport a two-word headline can break as one word per line; on a narrow one it can leave a preposition alone on line two. CSS gives you no control over which words land where, because the line-breaking algorithm is greedy and fast, not balanced. React Wrap Balancer exists to close that gap. The README frames the goal plainly: it "improves the wrapping to avoid situations like single word in the last line, makes the content more 'balanced'." The intended input is display text, not prose. The component's own name says titles. If you are looking for a way to fix paragraph justification, this is not that library, and the README does not claim otherwise.

How the balancing runs inside a React tree

The mechanism is a client-side re-measure loop. You wrap text in <Balancer>, which renders a wrapper element (a span by default, or whatever you pass to the as prop). The component then measures how the text lays out and rewrites the line breaks to spread words more evenly. Because it measures rendered geometry, it depends on ResizeObserver, and the README names that dependency directly: "Cross-browser compatibility issues are mainly due to the fact that lib uses the ResizeObserver API." That single sentence explains the whole browser support table. It also explains the re-render cost: every resize event can trigger new measurement and new output.

The ratio prop controls how aggressively the result is balanced, from 0 to 1, defaulting to 1. preferNative defaults to true, which means the component steps aside and lets native CSS text balancing handle the job when the browser supports it. That is a sensible default in 2026, but it also means two different code paths can produce your headline depending on the visitor's browser, and the README does not describe how closely the two agree. The Provider component is the other half of the design. Wrapping the app in <Provider> lets multiple <Balancer> instances share one rebalance routine, which the README says reduces HTML size. Without it, each instance carries its own logic. On a page with a dozen balanced headings, that difference is worth taking seriously.

Installing react-wrap-balancer and balancing a first headline

The package is published on npm. The README gives one install command:

bash
npm i react-wrap-balancer

After that, import the default export and wrap the text you want balanced. The README's example puts it inside an h1:

jsx
import Balancer from 'react-wrap-balancer'

function Title() {
  return (
    <h1>
      <Balancer>My Awesome Title</Balancer>
    </h1>
  )
}

Render that component in a browser and resize the window. The line breaks inside the h1 should shift so the words distribute more evenly across lines instead of leaving one word stranded. If nothing changes, check the browser version against the support table first, then confirm ResizeObserver is available.

When more than one balanced element appears on the page, the README recommends wrapping the app in Provider:

jsx
import { Provider } from 'react-wrap-balancer'

function App() {
  return (
    <Provider>
      <MyApp/>
    </Provider>
  )
}

This is optional, and the README says it reduces HTML size by letting the instances share the rebalance logic. If you use a strict Content Security Policy, note the nonce prop: the component injects an inline script, and nonce is the documented way to allowlist it.

Where react-wrap-balancer stops being the right tool

Three limits are visible in the repository itself. First, the browser floor. The README's desktop table starts at Chrome 64, Edge 79, Safari 13.1, Firefox 69 and Opera 51, with no support for IE; the mobile table starts at Chrome 64, Safari 13.4, Firefox 69, Opera 47 and Android WebView 64. Below those versions the README tells you to add a ResizeObserver polyfill or upgrade the browser. If your audience includes embedded webviews or kiosk software pinned to an old engine, that is a real constraint, not a footnote.

Second, the component is aimed at titles. The README's own description is "Simple React component that makes titles more readable." Nothing in the documentation suggests it is intended for paragraphs, and running a measure-and-rewrite loop over long body text would be the wrong use of the design.

Third, the measurement approach is inherently client-side. The README documents a nonce prop for inline script injection, which tells you the balancing happens in the browser, not at build time. Pages that must render final markup without client scripts, or that treat any inline script as a policy violation, will need the nonce path or a different solution.

The last push on the repository was on 2026-03-25, and the newest release listed is 1.1.1 from 2024-05-25. Treat the release as the stable target.

react-wrap-balancer against native text-wrap: balance

The most direct alternative is not another npm package. It is the CSS property the project itself points to. The README credits the CSS Text Level 4 proposal for text-wrap: balance and links the draft. If your support matrix is modern enough, one line of CSS does the job with no JavaScript, no ResizeObserver dependency, no inline script and no nonce to configure. That is a smaller surface area than any component can offer.

The difference in approach matters. Native text-wrap: balance is applied by the browser during layout, so there is no measurement pass and no hydration concern. react-wrap-balancer rebalances in JavaScript after render, which is why it works on browsers that predate the CSS property, and why preferNative defaults to true: when the browser can do it natively, the component gets out of the way. If you already target browsers that support the property, you may not need the package at all. If you support a range of engines, the component is the compatibility layer. The README also credits Adobe's balance-text, NYT's text-balancer and Daniel Aleksandersen's write-up as inspirations, so the technique has a longer lineage than this one package.

Licence and maintenance cost of adopting this component

The package is MIT licensed, stated in package.json and in the README's closing line. MIT permits commercial use, modification and redistribution provided the copyright notice and permission notice are retained. That is the usual reading; if your organisation has specific compliance requirements, route it through whoever handles licensing rather than treating this paragraph as advice.

The dependency footprint is small. React is a peer dependency, declared as ">=16.8.0 || ^17.0.0 || ^18", so the package does not bundle its own React. The devDependencies listed in package.json (tsup, turbo, TypeScript, types) are build tooling and do not ship to consumers. The published files field contains only dist.

Upgrade cost is mostly about the browser floor and the CSS fallback. The support table in the README is tied to ResizeObserver availability, so raising or lowering that floor is a documentation change as much as a code change. The last push was on 2026-03-25 while the newest release is 1.1.1 from 2024-05-25, so the gap between HEAD and the published version is something to check before you assume a fix has shipped.

Editorial conclusion

Adopt react-wrap-balancer for short display text: hero headlines, card titles, article headings, anywhere a single orphaned word on the last line looks wrong. Skip it for paragraphs and long-form body copy, since the component targets titles and the rebalance work is per element. Skip it too if you must support browsers below the table in the README (Chrome 64, Safari 13.1 desktop, Safari 13.4 mobile, Firefox 69) unless you add a ResizeObserver polyfill. Before shipping, verify three things on a real page: that the rendered HTML does not bloat when many <Balancer> instances exist without a shared <Provider>, that your Content Security Policy allows the inline script the component injects unless you pass a nonce, and that the default preferNative behaviour is what you want when a browser already supports CSS text-wrap: balance. The repository's last push was on 2026-03-25, and the newest release listed is 1.1.1 from 2024-05-25, so pin the version you install rather than tracking the branch.

Frequently asked questions

What is a React component wrapper like Balancer?

In this library, the wrapper is the element <Balancer> renders around your text, a span by default or the tag you pass to the as prop. It measures that text and rewrites the line breaks so the lines look more balanced.

Does react-wrap-balancer still use props?

Yes. The README documents as, ratio, preferNative and nonce as props on <Balancer>, with ratio ranging from 0 to 1 and preferNative defaulting to true.

How do I install react-wrap-balancer?

The README gives a single command, npm i react-wrap-balancer, then you import the default export and wrap your title text in <Balancer>. If you use several instances, the README recommends also wrapping the app in <Provider>.

Which browsers does react-wrap-balancer support?

The README lists Chrome 64, Edge 79, Safari 13.1, Firefox 69 and Opera 51 on desktop, with no IE support, and Chrome 64, Safari 13.4, Firefox 69, Opera 47 and Android WebView 64 on mobile. Older versions need a ResizeObserver polyfill or an upgrade.

What does the nonce prop on react-wrap-balancer do?

The README describes nonce as the attribute that allowlists the inline script injection performed by the component, which matters if your site enforces a Content Security Policy.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. shuding/react-wrap-balancer on GitHub
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/shuding-react-wrap-balancer.svg)](https://hysenlabs.com/projects/shuding-react-wrap-balancer)