La interfaz está localizada; las descripciones y documentos de las Skills se traducen automáticamente con IA a su idioma. El código, los comandos, rutas y términos técnicos se mantienen en el original, y prevalece el documento del autor.
Explorar Skills
Diseño y creatividad · SKILL.md

magicui

magicui

Adds animated React components (marquee, number ticker, shimmer button, confetti, globe, animated beam) to landing pages with Magic UI, a copy-the-source library built on Tailwind CSS and shadcn/ui. Use when asked to add animated UI components, build an impressive landing page hero, create particle or meteor backgrounds, text animations, number counters, sh…

Independent GitHub snapshot · Automated classification · Original documentation governs

Tterminalskills / skillsApache-2.0

Documentación de la Skill

GitHub

name: magicui description: >- Adds animated React components (marquee, number ticker, shimmer button, confetti, globe, animated beam) to landing pages with Magic UI, a copy-the-source library built on Tailwind CSS and shadcn/ui. Use when asked to add animated UI components, build an impressive landing page hero, create particle or meteor backgrounds, text animations, number counters, shimmer buttons, or other visual effects in React. license: Apache-2.0 compatibility: "React 18 or 19, Tailwind CSS (v4 recommended), a shadcn/ui project (components.json), Node.js 18+" metadata: author: terminal-skills version: "1.1.0" category: design tags: ["magicui", "react", "animations", "ui-components", "tailwind"] repository: https://github.com/magicuidesign/magicui use-cases: - "Add a particle/confetti effect to a landing page hero section" - "Create an animated number counter for displaying stats" - "Build a shimmer button with gradient animation for CTAs" - "Add a scrolling marquee for logos or testimonials" - "Create sparkle text for highlighting key phrases" agents: [claude-code, openai-codex, gemini-cli, cursor]

Magic UI

Overview

Magic UI is a collection of animated React components for landing pages, built on Tailwind CSS and the motion animation library. It is distributed as a shadcn registry: one command copies a component's source into your project, so you own the code and can edit it freely. There is no runtime package to depend on.

Key traits:

  • Installed with the shadcn CLI through the @magicui registry namespace
  • Components are copied to components/ui/ (the path set by the ui alias in components.json)
  • Named exports (import { Marquee } from "@/components/ui/marquee"), TypeScript first
  • Animation keyframes live in your global CSS; the CLI adds them for you

The old magicui-cli npm package was last published in July 2024 and is no longer maintained. Do not use it; the commands below replace it.

Instructions

Prerequisites

The project needs shadcn/ui initialised (a components.json file) and Tailwind CSS:

npx shadcn@latest init

The @magicui namespace is known to the shadcn CLI, so no registry entry has to be added to components.json.

Install components

npx shadcn@latest add @magicui/marquee
npx shadcn@latest add @magicui/number-ticker @magicui/shimmer-button   # several at once
npx shadcn@latest view @magicui/globe                                  # inspect source and dependencies first

The CLI installs the component's dependencies (for example motion, canvas-confetti, cobe) and writes any @theme inline keyframes into your CSS file. To list what exists, read https://magicui.design/llms.txt or browse https://magicui.design/docs/components.

Component usage

Imports come from @/components/ui/<name> and are named exports. Props below are from the current documentation.

Marquee — infinite ticker (reverse, pauseOnHover, vertical, repeat, default 4). Set speed with the CSS variables --duration and --gap:

import { Marquee } from "@/components/ui/marquee";

<Marquee pauseOnHover className="[--duration:20s]">
  {["Vercel", "Stripe", "Linear", "Notion", "Figma"].map((name) => (
    <span key={name} className="mx-8 text-xl font-semibold text-muted-foreground">{name}</span>
  ))}
</Marquee>

NumberTicker — counts when it scrolls into view (value, startValue, direction, delay, decimalPlaces):

import { NumberTicker } from "@/components/ui/number-ticker";

<NumberTicker value={10000} className="text-5xl font-bold" />
<NumberTicker value={99.9} decimalPlaces={1} className="text-5xl font-bold" />

ShimmerButton — props shimmerColor, shimmerSize (default 0.05em), shimmerDuration (default 3s), borderRadius, background:

import { ShimmerButton } from "@/components/ui/shimmer-button";

<ShimmerButton shimmerColor="#ffffff" background="linear-gradient(135deg, #6366f1, #8b5cf6)" className="px-8 py-3">
  Start free trial
</ShimmerButton>

SparklesText — the text is passed as children, not a text prop (sparklesCount, colors={{ first, second }}):

import { SparklesText } from "@/components/ui/sparkles-text";

<h1 className="text-6xl font-bold">Build <SparklesText colors={{ first: "#6366f1", second: "#ec4899" }}>faster</SparklesText> with AI</h1>

Ripple (mainCircleSize, mainCircleOpacity, numCircles) and Meteors (number, angle, minDuration, maxDuration) are backgrounds: put them in a relative overflow-hidden parent and raise your content with z-10:

import { Ripple } from "@/components/ui/ripple";
import { Meteors } from "@/components/ui/meteors";

<div className="relative flex h-96 items-center justify-center overflow-hidden rounded-2xl border">
  <Ripple mainCircleSize={200} numCircles={8} />
  <Meteors number={20} />
  <p className="z-10 text-4xl font-bold">Connect everything</p>
</div>

Confetti — a canvas component controlled by a ref, not a hook. Add manualstart so it does not fire on mount, then call fire():

"use client";
import { useRef } from "react";
import { Confetti, type ConfettiRef } from "@/components/ui/confetti";

export function CheckoutDone() {
  const confettiRef = useRef<ConfettiRef>(null);
  return (
    <div className="relative">
      <Confetti ref={confettiRef} manualstart className="pointer-events-none absolute inset-0 size-full" />
      <button onClick={() => confettiRef.current?.fire({ particleCount: 100, spread: 70 })}>
        Complete purchase
      </button>
    </div>
  );
}

AnimatedBeam — draws a moving line between two elements; needs three refs (containerRef, fromRef, toRef) and a relative container, plus optional curvature, duration, reverse, gradientStartColor, gradientStopColor:

"use client";
import { useRef } from "react";
import { AnimatedBeam } from "@/components/ui/animated-beam";

export function BeamDemo() {
  const containerRef = useRef<HTMLDivElement>(null);
  const fromRef = useRef<HTMLDivElement>(null);
  const toRef = useRef<HTMLDivElement>(null);
  return (
    <div ref={containerRef} className="relative flex h-64 items-center justify-between p-10">
      <div ref={fromRef} className="size-12 rounded-full bg-blue-500" />
      <div ref={toRef} className="size-12 rounded-full bg-purple-500" />
      <AnimatedBeam containerRef={containerRef} fromRef={fromRef} toRef={toRef} />
    </div>
  );
}

Text effects — BlurIn no longer exists. Use TextAnimate (animation="blurInUp", by="word" | "character" | "line" | "text") or BlurFade (delay, duration, direction, inView):

import { TextAnimate } from "@/components/ui/text-animate";
import { BlurFade } from "@/components/ui/blur-fade";

<TextAnimate as="h1" animation="blurInUp" by="word" className="text-5xl font-bold">
  The future of development
</TextAnimate>
<BlurFade delay={0.25} inView><p>Fades in when scrolled into view</p></BlurFade>

Globe (config takes COBE options; the CLI installs cobe and motion) and Particles (quantity, color, size, staticity) take only a sized container:

import { Globe } from "@/components/ui/globe";

<div className="relative mx-auto size-[500px]"><Globe /></div>

Components that exist today

animated-beam, animated-circular-progress-bar, animated-gradient-text, animated-grid-pattern, animated-list, animated-shiny-text, animated-theme-toggler, aurora-text, avatar-circles, bento-grid, blur-fade, border-beam, code-comparison, confetti, cool-mode, dock, dot-pattern, file-tree, flickering-grid, globe, grid-pattern, hero-video-dialog, highlighter, hyper-text, icon-cloud, interactive-hover-button, iphone, light-rays, magic-card, marquee, meteors, morphing-text, neon-gradient-card, number-ticker, orbiting-circles, particles, pointer, progressive-blur, pulsating-button, rainbow-button, retro-grid, ripple, safari, scroll-based-velocity, scroll-progress, shimmer-button, shine-border, shiny-button, smooth-cursor, sparkles-text, spinning-text, terminal, text-animate, text-reveal, typing-animation, video-text, warp-background, word-rotate.

Removed or renamed: blur-in (use text-animate or blur-fade), word-fade-in, word-pull-up, letter-pullup, flip-text, wavy-text, vanish-input, ticker (use marquee).

Examples

Example 1: Hero section with a marquee of customer logos

User request: "Make the landing page hero animated: a ripple behind the headline, a shimmer CTA, and a scrolling row of customer names under it."

npx shadcn@latest add @magicui/ripple @magicui/shimmer-button @magicui/marquee @magicui/text-animate
// app/page.tsx
import { Ripple } from "@/components/ui/ripple";
import { ShimmerButton } from "@/components/ui/shimmer-button";
import { Marquee } from "@/components/ui/marquee";
import { TextAnimate } from "@/components/ui/text-animate";

export default function LandingPage() {
  return (
    <main>
      <section className="relative flex h-screen flex-col items-center justify-center overflow-hidden text-center">
        <Ripple mainCircleSize={300} numCircles={6} />
        <TextAnimate as="h1" animation="blurInUp" by="word" className="z-10 text-6xl font-bold">
          Ship faster than ever
        </TextAnimate>
        <p className="z-10 mt-4 text-xl text-muted-foreground">From idea to production in a day</p>
        <ShimmerButton className="z-10 mt-8">Start for free</ShimmerButton>
      </section>
      <Marquee pauseOnHover className="py-12 [--duration:30s]">
        {["Northwind", "Globex", "Initech", "Umbrella", "Hooli"].map((name) => (
          <span key={name} className="mx-12 text-lg text-muted-foreground">{name}</span>
        ))}
      </Marquee>
    </main>
  );
}

Result: components/ui/ gains ripple.tsx, shimmer-button.tsx, marquee.tsx, text-animate.tsx; motion is added to package.json; the headline fades in word by word while the logos scroll and pause on hover.

Example 2: Stats row that counts up

User request: "Show three stats that count up when the user scrolls to them."

npx shadcn@latest add @magicui/number-ticker
import { NumberTicker } from "@/components/ui/number-ticker";

export function StatsSection() {
  return (
    <div className="grid grid-cols-3 gap-8 text-center">
      <div><NumberTicker value={50000} className="text-5xl font-bold" /><p>Active users</p></div>
      <div><NumberTicker value={99.9} decimalPlaces={1} className="text-5xl font-bold" /><span className="text-5xl font-bold">%</span><p>Uptime</p></div>
      <div><NumberTicker value={42} className="text-5xl font-bold" /><span className="text-5xl font-bold">+</span><p>Countries</p></div>
    </div>
  );
}

Result: each number counts from 0 to its value once, when it enters the viewport. Number formatting is fixed to en-US (50,000).

Guidelines

  • Use npx shadcn@latest add @magicui/<name>, never magicui-cli, and never copy code from old blog posts: names such as blur-in and import styles such as import Marquee from (default export) are outdated.
  • Components that use hooks, refs or browser APIs are client components. In the Next.js App Router, add "use client" to the file that renders them (the copied components already have it).
  • cn not found: shadcn's init creates lib/utils.ts; if it is missing, install clsx and tailwind-merge and add it.
  • Animation does nothing: check that the keyframes were added to your global CSS (@theme inline { --animate-... } for Tailwind v4, tailwind.config keyframes for v3) and that the CSS file is imported in the root layout.
  • Background effects (Ripple, Meteors, Particles, BorderBeam) are absolutely positioned: give the parent relative overflow-hidden and an explicit height.
  • Respect users who prefer reduced motion and keep heavy effects (Globe, Particles, Meteors) to one or two per page; they run continuously and cost CPU on phones.
  • Because the source is copied into your repo, updates are not automatic: re-run npx shadcn@latest add @magicui/<name> --overwrite to pull a newer version, then review the diff against your edits.
  • Do not use Magic UI for dense application screens or accessible form controls; it targets marketing pages. For plain buttons, dialogs and inputs use shadcn/ui itself.
Skills guardadas