or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

tessl/npm-react-countup

A configurable React component wrapper around CountUp.js for animated number counting effects

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/react-countup@6.5.x

To install, run

npx @tessl/cli install tessl/npm-react-countup@6.5.0

0

# React CountUp

1

2

React CountUp is a configurable React component wrapper around CountUp.js that provides animated number counting effects. It offers both declarative component usage and imperative hook-based control with full TypeScript support.

3

4

## Package Information

5

6

- **Package Name**: react-countup

7

- **Package Type**: npm

8

- **Language**: TypeScript

9

- **Installation**: `npm install react-countup`

10

11

## Core Imports

12

13

```typescript

14

import CountUp, { useCountUp, type CountUpProps } from "react-countup";

15

```

16

17

For CommonJS:

18

19

```javascript

20

const CountUp = require("react-countup").default;

21

const { useCountUp } = require("react-countup");

22

```

23

24

## Basic Usage

25

26

```typescript

27

import React from "react";

28

import CountUp from "react-countup";

29

30

// Simple declarative usage

31

function App() {

32

return (

33

<div>

34

<CountUp end={100} duration={2} />

35

</div>

36

);

37

}

38

39

// With custom formatting

40

function FormattedCounter() {

41

return (

42

<CountUp

43

start={0}

44

end={1234567}

45

duration={3}

46

separator=","

47

prefix="$"

48

suffix=" USD"

49

decimals={2}

50

/>

51

);

52

}

53

```

54

55

## Architecture

56

57

React CountUp is built around three key components:

58

59

- **CountUp Component**: Declarative React component supporting both standard rendering and render prop patterns

60

- **useCountUp Hook**: Imperative hook providing programmatic control over animations with lifecycle management

61

- **CountUp.js Integration**: Leverages the underlying CountUp.js library with React-specific optimizations and SSR compatibility

62

63

## Capabilities

64

65

### CountUp Component

66

67

React component wrapper providing declarative animated counting with extensive customization options and render prop support.

68

69

```typescript { .api }

70

/**

71

* React component for animated number counting

72

*/

73

declare const CountUp: React.FC<CountUpProps>;

74

75

interface CountUpProps extends CommonProps, CallbackProps {

76

/** CSS class name for the container element */

77

className?: string;

78

/** Force redraw on every prop change */

79

redraw?: boolean;

80

/** Render prop function for custom rendering */

81

children?: (props: RenderCounterProps) => React.ReactNode;

82

/** Inline styles for the container element */

83

style?: React.CSSProperties;

84

/** Preserve current value when updating end value */

85

preserveValue?: boolean;

86

/** Additional props for the container span element */

87

containerProps?: React.ComponentPropsWithoutRef<'span'>;

88

}

89

90

interface RenderCounterProps extends CountUpApi {

91

/** Ref to attach to custom render element */

92

countUpRef: React.RefObject<HTMLElement>;

93

}

94

```

95

96

**Usage Examples:**

97

98

```typescript

99

import React from "react";

100

import CountUp from "react-countup";

101

102

// Standard usage

103

<CountUp end={100} duration={2} />

104

105

// With render prop for custom styling

106

<CountUp end={100} duration={2}>

107

{({ countUpRef, start, reset }) => (

108

<div>

109

<span ref={countUpRef} className="big-number" />

110

<button onClick={start}>Start</button>

111

<button onClick={reset}>Reset</button>

112

</div>

113

)}

114

</CountUp>

115

116

// With event callbacks

117

<CountUp

118

end={100}

119

duration={2}

120

onEnd={({ reset, start }) => console.log("Animation completed!")}

121

onStart={() => console.log("Animation started!")}

122

/>

123

```

124

125

### useCountUp Hook

126

127

Hook providing imperative control over CountUp animations with lifecycle management and programmatic API access.

128

129

```typescript { .api }

130

/**

131

* Hook for imperative CountUp control

132

* @param props Configuration options for the counter

133

* @returns API object with control methods

134

*/

135

function useCountUp(props: UseCountUpProps): CountUpApi;

136

137

interface UseCountUpProps extends CommonProps, CallbackProps {

138

/** Target element reference (string selector or React ref) */

139

ref: string | React.RefObject<HTMLElement>;

140

/** Whether to reinitialize when props change */

141

enableReinitialize?: boolean;

142

}

143

144

interface CountUpApi {

145

/** Start or restart the animation */

146

start: () => void;

147

/** Pause or resume the animation */

148

pauseResume: () => void;

149

/** Reset the counter to start value */

150

reset: () => void;

151

/** Update the end value and animate to it */

152

update: (newEnd: string | number) => void;

153

/** Get the underlying CountUp.js instance */

154

getCountUp: (recreate?: boolean) => CountUpInstance;

155

}

156

```

157

158

**Usage Examples:**

159

160

```typescript

161

import React, { useRef } from "react";

162

import { useCountUp } from "react-countup";

163

164

function CustomCounter() {

165

const countUpRef = useRef<HTMLSpanElement>(null);

166

167

const { start, reset, update, pauseResume } = useCountUp({

168

ref: countUpRef,

169

end: 100,

170

duration: 2,

171

startOnMount: false,

172

});

173

174

return (

175

<div>

176

<span ref={countUpRef} />

177

<button onClick={start}>Start</button>

178

<button onClick={pauseResume}>Pause/Resume</button>

179

<button onClick={reset}>Reset</button>

180

<button onClick={() => update(200)}>Update to 200</button>

181

</div>

182

);

183

}

184

185

// With string selector

186

function SelectorCounter() {

187

useCountUp({

188

ref: 'counter-element',

189

end: 100,

190

duration: 2,

191

});

192

193

return <div id="counter-element" />;

194

}

195

```

196

197

## Common Configuration

198

199

### Core Props Interface

200

201

Shared configuration options available to both component and hook.

202

203

```typescript { .api }

204

interface CommonProps extends CountUpInstanceProps {

205

/** Whether to start animation on mount */

206

startOnMount?: boolean;

207

/** Delay before starting animation (in seconds) */

208

delay?: number | null;

209

}

210

211

interface CountUpInstanceProps extends CountUpOptions {

212

/** Number of decimal places to display */

213

decimals?: number;

214

/** The target end value */

215

end: number;

216

/** The starting value */

217

start?: number;

218

/** Whether to use easing animation */

219

useEasing?: boolean;

220

}

221

```

222

223

### Event Callbacks

224

225

Complete event callback system for animation lifecycle management.

226

227

```typescript { .api }

228

interface CallbackProps {

229

/** Called when animation ends */

230

onEnd?: OnEndCallback;

231

/** Called when animation starts */

232

onStart?: OnStartCallback;

233

/** Called when animation is paused/resumed */

234

onPauseResume?: OnPauseResumeCallback;

235

/** Called when counter is reset */

236

onReset?: OnResetCallback;

237

/** Called when end value is updated */

238

onUpdate?: OnUpdateCallback;

239

}

240

241

type OnEndCallback = (args: OnEndArgs) => void;

242

type OnStartCallback = (args: OnStartArgs) => void;

243

type OnPauseResumeCallback = (args: OnPauseResumeArgs) => void;

244

type OnResetCallback = (args: OnResetArgs) => void;

245

type OnUpdateCallback = (args: OnUpdateArgs) => void;

246

247

interface OnEndArgs {

248

pauseResume: () => void;

249

reset: () => void;

250

start: () => void;

251

update: (newEnd: string | number) => void;

252

}

253

254

interface OnStartArgs {

255

pauseResume: () => void;

256

reset: () => void;

257

update: (newEnd: string | number) => void;

258

}

259

260

interface OnPauseResumeArgs {

261

reset: () => void;

262

start: () => void;

263

update: (newEnd: string | number) => void;

264

}

265

266

interface OnResetArgs {

267

pauseResume: () => void;

268

start: () => void;

269

update: (newEnd: string | number) => void;

270

}

271

272

interface OnUpdateArgs {

273

pauseResume: () => void;

274

reset: () => void;

275

start: () => void;

276

}

277

```

278

279

### CountUp.js Configuration Options

280

281

All configuration options from the underlying CountUp.js library are supported:

282

283

```typescript { .api }

284

interface CountUpOptions {

285

/** Decimal character */

286

decimal?: string;

287

/** Thousands separator character */

288

separator?: string;

289

/** Text prepended to result */

290

prefix?: string;

291

/** Text appended to result */

292

suffix?: string;

293

/** Animation duration in seconds */

294

duration?: number;

295

/** Whether to use easing animation */

296

useEasing?: boolean;

297

/** Whether to use thousands separator grouping */

298

useGrouping?: boolean;

299

/** Whether to use Indian number separators */

300

useIndianSeparators?: boolean;

301

/** Custom easing function */

302

easingFn?: (t: number, b: number, c: number, d: number) => number;

303

/** Custom formatting function */

304

formattingFn?: (value: number) => string;

305

/** Custom numerals array */

306

numerals?: string[];

307

/** Whether to enable scroll spy functionality */

308

enableScrollSpy?: boolean;

309

/** Scroll spy delay in milliseconds */

310

scrollSpyDelay?: number;

311

/** Whether scroll spy should trigger only once */

312

scrollSpyOnce?: boolean;

313

/** CountUp.js plugin */

314

plugin?: any;

315

}

316

317

/** CountUp.js instance returned by getCountUp method */

318

interface CountUpInstance {

319

/** Start the animation */

320

start(callback?: () => void): void;

321

/** Pause or resume the animation */

322

pauseResume(): void;

323

/** Reset to start value */

324

reset(): void;

325

/** Update to new end value */

326

update(newEnd: number | string): void;

327

/** Get formatted value at current state */

328

formattingFn(value: number): string;

329

}

330

```

331

332

## Default Values

333

334

The useCountUp hook provides sensible defaults for all configuration options:

335

336

```typescript

337

const DEFAULTS = {

338

decimal: '.',

339

separator: ',',

340

delay: null,

341

prefix: '',

342

suffix: '',

343

duration: 2,

344

start: 0,

345

decimals: 0,

346

startOnMount: true,

347

enableReinitialize: true,

348

useEasing: true,

349

useGrouping: true,

350

useIndianSeparators: false,

351

};

352

```

353

354

## Advanced Usage Patterns

355

356

### Conditional Animations

357

358

```typescript

359

import React, { useState } from "react";

360

import CountUp from "react-countup";

361

362

function ConditionalCounter() {

363

const [shouldAnimate, setShouldAnimate] = useState(false);

364

365

return (

366

<div>

367

{shouldAnimate && (

368

<CountUp

369

end={100}

370

duration={2}

371

onEnd={() => setShouldAnimate(false)}

372

/>

373

)}

374

<button onClick={() => setShouldAnimate(true)}>

375

Start Animation

376

</button>

377

</div>

378

);

379

}

380

```

381

382

### Multiple Counters with Synchronization

383

384

```typescript

385

import React, { useRef } from "react";

386

import { useCountUp } from "react-countup";

387

388

function SynchronizedCounters() {

389

const ref1 = useRef<HTMLSpanElement>(null);

390

const ref2 = useRef<HTMLSpanElement>(null);

391

392

const counter1 = useCountUp({

393

ref: ref1,

394

end: 100,

395

duration: 2,

396

startOnMount: false,

397

});

398

399

const counter2 = useCountUp({

400

ref: ref2,

401

end: 200,

402

duration: 2,

403

startOnMount: false,

404

});

405

406

const startBoth = () => {

407

counter1.start();

408

counter2.start();

409

};

410

411

return (

412

<div>

413

<span ref={ref1} /> | <span ref={ref2} />

414

<button onClick={startBoth}>Start Both</button>

415

</div>

416

);

417

}

418

```

419

420

### Custom Formatting with Callbacks

421

422

```typescript

423

import CountUp from "react-countup";

424

425

function CustomFormattedCounter() {

426

return (

427

<CountUp

428

end={1234567.89}

429

decimals={2}

430

duration={3}

431

formattingFn={(value) => {

432

// Custom currency formatting

433

return new Intl.NumberFormat('en-US', {

434

style: 'currency',

435

currency: 'USD'

436

}).format(value);

437

}}

438

/>

439

);

440

}

441

```

442

443

## Error Handling

444

445

The library handles common error scenarios:

446

447

- **Missing DOM element**: When using render props, the library logs a warning if `countUpRef` is not attached to a DOM element

448

- **Invalid values**: Non-numeric end values are handled gracefully by CountUp.js

449

- **SSR compatibility**: Uses `useIsomorphicLayoutEffect` to prevent hydration mismatches

450

451

## TypeScript Support

452

453

React CountUp provides complete TypeScript definitions with:

454

455

- Full type safety for all props and callback parameters

456

- Generic type preservation where applicable

457

- Comprehensive interface definitions for all API surfaces

458

- Integration with React's built-in types (CSSProperties, RefObject, etc.)

459

460

## Dependencies

461

462

- **Runtime**: countup.js ^2.8.0

463

- **Peer Dependencies**: react >= 16.3.0

464

- **No additional runtime dependencies**