Overview
CurvedArrow draws smart connector paths between two elements or coordinates. It supports multiple curve presets, obstacle routing, animated strokes, gradient styling, and precise arrow head layering so your diagrams and product UIs feel intentional and clear.
Installation
Install via your preferred package manager:
1# npm
2npx shadcn@canary add https://dsa.hncore.website/r/curved-arrow.json
3
4# bun
5bunx --bun shadcn@canary add https://dsa.hncore.website/r/curved-arrow.json
6
7# pnpm
8pnpx shadcn@canary add https://dsa.hncore.website/r/curved-arrow.json
Quick Start
Create two target refs and render CurvedArrow between them. It updates automatically when layout changes.
1import React, { useRef } from "react"
2import { CurvedArrow } from "curved-arrow-react"
3
4export default function Example() {
5 const startRef = useRef<HTMLDivElement>(null)
6 const endRef = useRef<HTMLDivElement>(null)
7
8 return (
9 <div className="relative h-80 bg-slate-50 rounded-lg">
10 <div ref={startRef} className="absolute top-6 left-6 w-20 h-12 bg-emerald-600 rounded text-white grid place-items-center">A</div>
11 <div ref={endRef} className="absolute bottom-6 right-6 w-20 h-12 bg-violet-600 rounded text-white grid place-items-center">B</div>
12
13 <CurvedArrow
14 startElement={startRef}
15 endElement={endRef}
16 curveType="elegant"
17 variant="glow"
18 animated
19 gradientFrom="#10b981"
20 gradientTo="#8b5cf6"
21 showEndArrow
22 endArrowShape="filled-triangle"
23 />
24 </div>
25 )
26}
Geometry & Curves
Choose a curve preset and optionally override direction and intensity. Use obstacles to automatically route around elements.
1// Choose curve presets or control intensity/direction
2<CurvedArrow
3 startElement={startRef}
4 endElement={endRef}
5 curveType="s-curve" // "smooth" | "dramatic" | "s-curve" | "wave" | "around-obstacle" | "shortest-path" | "zigzag" | "elegant"
6 curveDirection="auto" // "auto" | "up" | "down" | "left" | "right"
7 curveIntensity={0.6}
8/>
Visuals & Animation
Style the stroke, apply gradients, and enable animation. Most variants are designed to preserve clarity on light and dark backgrounds.
1// Animate and style with gradients, stroke width and variants
2<CurvedArrow
3 startElement={startRef}
4 endElement={endRef}
5 strokeWidth={3}
6 variant="neon" // "default" | "glow" | "subtle" | "bold" | "neon" | "fire" | "ice" | "electric" | "shadow" | "rainbow" | "cosmic"
7 animated
8 animationDuration="2.2s"
9 animationDirection="alternate"
10 gradientFrom="#06b6d4"
11 gradientTo="#f97316"
12/>
1.arrow-canvas {
2 /* Helps with crisp rendering on scaled canvases */
3 -webkit-font-smoothing: antialiased;
4 -moz-osx-font-smoothing: grayscale;
5}
Arrow Heads & Layering
Control start/end arrow heads, their sizes, shapes, and z-order relative to the connecting line and target nodes.
1// Place arrow heads precisely and choose their layering
2<CurvedArrow
3 startElement={startRef}
4 endElement={endRef}
5 showStartArrow
6 showEndArrow
7 startHeadLayer="under" // "over" | "under"
8 endHeadLayer="over"
9 startArrowShape="chevron"
10 endArrowShape="filled-triangle"
11 startArrowSize={10}
12 endArrowSize={14}
13/>
Patterns & Recipes
Use these patterns to speed up implementation.
1// Route around obstacles, heads stay above nodes
2<CurvedArrow
3 startElement={startRef}
4 endElement={endRef}
5 obstacleElements={[blockRef1, blockRef2]}
6 curveType="around-obstacle"
7 animated
8 showStartArrow
9 showEndArrow
10 startHeadLayer="over"
11 endHeadLayer="over"
12/>
1{
2 "curveType": "elegant",
3 "variant": "glow",
4 "animated": true,
5 "gradientFrom": "#10b981",
6 "gradientTo": "#8b5cf6",
7 "showEndArrow": true
8}
Performance
- Prefer refs over frequent coordinate recalculations in dynamic layouts.
- Batch DOM reads/writes; if animating positions, use requestAnimationFrame.
- Throttle resize/scroll listeners when observing many nodes.
- Use simpler variants (e.g., "subtle") where many arrows are on screen.
Accessibility
Ensure connected elements have descriptive labels. Maintain color contrast for strokes and heads. If arrows indicate flow, consider providing an ARIA description or textual summary.
FAQ
Does it require extra packages? No. It uses SVG and React only.
Can I use static coordinates? Yes. Pass startX/startY and endX/endY.
How do I avoid overlap with content? Use obstacleElements and head layering.