React Bits, or animation without writing animation
React Bits is a set of over a hundred and sixty animated React components you copy into your project rather than install as a dependency. It holds text effects, backgrounds, transitions, cursor reactions, and elements triggered on scroll.
The approach is familiar from other modern kits: there is no single package holding the whole library, there is code that becomes part of your project. You can change it, simplify it, or throw half of it away without waiting for a release from the author.
The use case is narrower than the component count suggests. This is not a kit for building applications but for building an impression. Forms, tables, and dialogs live elsewhere; here are the things meant to catch attention.
Four variants per component
An unusual and practical arrangement: every component exists in four versions covering combinations of JavaScript with TypeScript and plain styles with utility classes.
That means you need not rewrite a component into your toolset or pull a styling system you do not use into the project. You pick the variant matching what you already have.
npx shadcn@latest add @react-bits/BlurText-TS-TW
npx jsrepo@latest add github/davidhaz/react-bits BlurText-TS-TWThe variant sits in the item name: TS-TW is TypeScript with utility classes, and the other three are TS-CSS, JS-TW, and JS-CSS. Both installation routes fetch files into your project along with that component's dependencies, and every component page carries a ready command to copy.
Look into the fetched code right away, since that is the whole point of this approach. A hundred line component, half of which handles a case you do not need, becomes your code after trimming rather than somebody else's dependency to maintain.
There is a second side to this, worth knowing before adding the twentieth component. Fixes and improvements the author makes do not reach you automatically, since there is no dependency to update.
With a few components that is no problem; with twenty it pays to record somewhere where they came from and at what version.
{
"BlurText": {
"source": "@react-bits/BlurText-TS-TW",
"fetched": "2026-08-04",
"changed": ["removed per word variant", "duration 400ms instead of 800ms"]
}
}A file holding such a record next to the copied components costs a minute on every addition, and answers a question that becomes unanswerable after six months: is this file somebody else's code with a small fix, or entirely yours by now.
A licence with a caveat
Here something the project's material usually mentions in passing deserves stating, since it carries legal weight.
The project is released under the MIT licence with a Commons Clause condition attached. The licence file names it outright and forbids selling, sublicensing, or redistributing the components themselves, alone, in a bundle, or ported to another technology. In practice that means you can use the components in commercial projects, in products, and for clients, while you cannot sell the component set itself as a product.
For the same reason this is not an open source licence under the classic definition, which admits no restriction on how you may earn from the software. The code is public and free of charge, yet calling it open without qualification departs from what the licence file says.
For the overwhelming majority of uses that is no restriction. It becomes one if you are building your own component kit for sale, or a template whose value is precisely this collection.
Check that distinction in the original licence text before using it in a product you resell, since clauses of this kind get interpreted differently and a summary is not something to rely on.
The performance cost
Animations look good on a showcase page and carry a cost worth knowing before you add a fifth effect to one page.
The first item is shipped code size. The components use animation libraries, with each pulling what it needs, so adding three effects from three families can add more to the bundle than the rest of the interface combined.
The second is browser work. Effects operating on a canvas, particles, or a background image run in the render loop, occupying the processor for as long as the element is visible. On a development machine that is invisible; on a three year old phone it is not.
The third is the effect on page quality measures. An element animating layout rather than only opacity and transform triggers layout recalculation, which worsens the visual stability the browser measures and search results reflect.
A practical rule solving most of this: animate opacity and transforms rather than width, height, or position. The browser handles the former separately, without recomputing page layout.
Respect the reduced motion setting a user can enable in their system too. Checking it in code is three lines, and for some people animation causes real discomfort.
@media (prefers-reduced-motion: reduce) {
.animated { animation: none; transition: none; }
}What the collection holds
Breaking the contents into categories pays off, since it determines whether the tool suits your project at all.
Text effects are the largest and most useful group: letters appearing in sequence, blur clearing on entering view, text scattering and reassembling, numbers counting to a target value. These reach product pages most often and are the easiest to use in moderation.
Backgrounds and decorative layers cover moving gradients, grids, particles, and effects reacting to the cursor. They look the most striking and cost the most, since they run continuously for as long as they are visible.
Cursor reactions include elements drawn towards the pointer, sparks on click, a trail following movement. Small, cheap, and surprisingly effective at conveying polish.
Transitions and scroll triggered elements reveal content as you move down the page. Take particular care here, since content hidden until scrolled can be a problem for search engines and for people using screen readers.
The last category is purely decorative: cards with depth effects, images with transitions, elements in three dimensions. Striking and the heaviest, so one per page usually suffices.
If what you want from that last category is a real scene with a model, lighting, and materials rather than a depth effect on a flat card, that is a job for a different tool. Spline lets you assemble such a scene visually in the browser and export it to React, though you pay with several megabytes in the bundle and GPU work for as long as the scene stays visible.
How to use this in moderation
A collection of a hundred effects tempts you to use twenty, and that is the most common route to a page that loads in four seconds and tires after ten.
The rule that works in practice runs: one strong effect per screen. A hero section can have a moving background or an animated heading, not both. A second section can have scroll reveal, provided the first did not.
The second rule concerns duration. An animation longer than roughly half a second stops being decoration and becomes waiting. Default values in collections like this are often tuned for a showcase page, where the effect should draw attention, rather than for a real page somebody wants to move through.
The third concerns content visible immediately. A heading appearing with a delay looks good and leaves the page empty for the first second. For the most important sentence on the page, dropping the effect beats delaying the message.
Check too how the page looks with JavaScript disabled or before it runs. If content is invisible then, you lose it both in search and for people on slow connections. An element should be visible by default, with animation merely introducing it.
React Bits against the alternatives
| Option | Strength | Weakness | Pick it when |
|---|---|---|---|
| React Bits | Many effects, four variants, code lives with you | Narrow scope, a licence caveat | A marketing page, portfolio, showcase |
| Magic UI | Similar scope, consistent visual style | Fewer technology variants | A project already on utility classes |
| Motion | Full control, builds any animation | You write every effect yourself | Unusual animations and transitions |
| shadcn/ui | Functional components for building apps | Almost no decorative effects | A dashboard, forms, an application |
The last row is not competition but a complement, worth remembering when planning. A typical project uses one kit for the functional layer and another for the decorative one, since the first has no effects and the second no forms.
Choosing between the first and third rows comes down to how many effects you need and how much they should be yours. A ready collection saves days of work on common effects. An animation library gives full freedom at the cost of time and requires understanding how animation works.
When this is not the right choice
Worth saying plainly, since the temptation to add effects is strong and not every project gains from them.
An admin panel, an internal tool, and an application used daily by the same people lose from animation. An effect impressive on first viewing is, on the fiftieth that day, purely a delay between a click and a result.
A mobile web application rarely gains either, since processor cost there translates directly into battery drain and scrolling smoothness.
A site whose main job is delivering information quickly gains from having no effects. Documentation, a knowledge base, and a support page work better when content appears immediately.
The places where this works well are specific: a product home page, a portfolio, an event page, a new feature showcase. In all of those a user arrives once, briefly, and first impressions genuinely matter.
Server side rendering
Animated components need attention in applications rendering pages on the server, since some of them reach for objects available only in a browser.
The symptom is always the same: the application works locally in development mode and breaks during the build or on the first production request. The cause is a reference to the browser window, the document, or a visibility observer during server rendering, where none of those exist.
The fix is simple and consists of loading the component on the client side only, skipping server rendering.
import dynamic from 'next/dynamic'
const BlurText = dynamic(() => import('@/components/BlurText'), {
ssr: false,
loading: () => <span className="opacity-0">{title}</span>
})The placeholder given in the second option matters more than it looks. Without it the component's place is empty until it loads, so the page layout jumps the moment it appears. An element of the same size at zero opacity reserves the space and removes the jump.
The second matter is a mismatch between what the server rendered and what the browser drew after starting. A component beginning at zero opacity on the server and changing it on the client produces a console warning and sometimes a visible flicker.
const [mounted, setMounted] = useState(false)
useEffect(() => setMounted(true), [])
if (!mounted) return <span>{title}</span>
return <BlurText text={title} />That pattern renders plain text on the server and the animated version only after startup in the browser. The content therefore reaches the markup the server sends, and the mismatch warning disappears, because both sides render the same thing initially.
The third is the cost for search engines. An element loaded only on the client will not appear in the markup the server sends, so content inside such a component is invisible to search.
Checking takes one command and needs no tooling.
curl -s https://mysite.com | grep -o "Your heading"Empty output means the text is produced only in the browser. The practical conclusion: load decorative effects on the client, and keep content meant to be indexed outside them.
Common mistakes
The first is adding several effects from different families on one page. Each pulls its own dependencies, so the bundle grows faster than the component count suggests.
The second is animating properties affecting page layout. Opacity and transforms are cheap; width and position force layout recomputation.
The third is skipping the reduced motion setting. Three lines of code, and for some users a real difference in comfort.
The fourth is testing only on a development machine. Effects running smoothly on a powerful machine can stall scrolling on a phone a few years old.
The fifth is treating this as a kit for building applications. It is a decorative layer, and forms and tables need something else.
The sixth is overlooking the licence caveat in a product you resell. Ordinary commercial use is fine; selling the component collection itself is not.
The seventh is forgetting where copied code came from. Without a note on the source and version, six months later nobody can tell a component pulled in from outside from one written by the team.
FAQ
Is React Bits free?
The code is public, free of charge, and usable commercially. The licence, though, is MIT with a Commons Clause condition, which forbids selling or redistributing the components themselves and thereby puts the project outside the classic definition of open source. For a product whose value is this collection, read the original licence text.
Is it a dependency or copied code?
Copied code. The command line tool fetches files into your project, where they become your code. There is no single package holding the whole library and no updates arriving automatically.
Does it work with any toolset?
Every component exists in four variants covering JavaScript and TypeScript along with plain styles and utility classes. You pick the one matching your project, so you need not pull in a styling system you do not use.
Do the animations hurt performance?
They can, and it deserves controlling. Animate opacity and transforms rather than layout affecting properties, limit the number of effects per page, and test on a weaker phone rather than only on a development machine.
Will it replace shadcn/ui or a similar kit?
No, it is a different layer. shadcn/ui provides functional components for building applications; here are decorative effects. A typical project uses both at once, each for something different.
The components and documentation sit on the project site, and the code in the GitHub repository.