Works natively with Cursor. Add npx -y bare-ui-mcp to your MCP settings.

Hyper Text

A zero-dependency, ultra-lightweight text component that creates a hacker-style scrambling text effect on hover or load. Perfect for viral marketing pages and high-performance React applications.

Preview

BARE UI

Installation

Copy and paste the following code into your project.

tsx
"use client";

import React, { useState, useEffect, useRef } from "react";

export interface HyperTextProps extends React.HTMLAttributes<HTMLDivElement> {
  text: string;
  duration?: number;
  className?: string;
  animateOnLoad?: boolean;
}

const alphabets = "ABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");

const getRandomInt = (max: number) => Math.floor(Math.random() * max);

export const HyperText = ({
  text,
  duration = 800,
  className = "",
  animateOnLoad = true,
  ...props
}: HyperTextProps) => {
  const [displayText, setDisplayText] = useState<string[]>(text.split(""));
  const [trigger, setTrigger] = useState(animateOnLoad);
  const interations = useRef(0);
  const isFirstRender = useRef(true);

  const triggerAnimation = () => {
    interations.current = 0;
    setTrigger(true);
  };

  useEffect(() => {
    if (isFirstRender.current) {
      isFirstRender.current = false;
      if (!animateOnLoad) return;
    }
    const interval = setInterval(
      () => {
        if (!trigger) {
          clearInterval(interval);
          return;
        }

        if (interations.current < text.length) {
          setDisplayText((t) =>
            t.map((l, i) =>
              l === " "
                ? l
                : i <= interations.current
                  ? (text[i] as string)
                  : (alphabets[getRandomInt(26)] as string),
            ),
          );
          interations.current = interations.current + 0.1;
        } else {
          setTrigger(false);
          clearInterval(interval);
        }
      },
      duration / (text.length * 10),
    );
    return () => clearInterval(interval);
  }, [text, duration, trigger, animateOnLoad]);

  return (
    <div
      className={`bare-hyper-text ${className}`}
      onMouseEnter={triggerAnimation}
      {...props}
    >
      {displayText.map((letter, i) => (
        <span key={i} className="bare-hyper-text-letter">
          {letter}
        </span>
      ))}
    </div>
  );
};