user-event

Simulates the full sequence of real browser events so Testing Library tests behave the way an actual user does.

Library
npm
v14.6.8
2,335 stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
80 /100 Excellent
Development Activity 72
Maintenance 80
Community 68
Maturity 60
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
83 /100 Excellent
Architecture 85
Code Quality 90
Innovation 75
Learning Curve 80

user-event is the companion library to @testing-library/dom (and by extension React Testing Library, Vue Testing Library, and the rest of the Testing Library family) for firing events the way a real user would trigger them, rather than the single low-level DOM event that fireEvent dispatches. Clicking a checkbox with user-event doesn’t just fire a click event — it walks through pointer-down, focus, pointer-up, and click, updating the element’s state along the way, the same as clicking it in a browser would.

The library is built around two layers: a stateful setup() session that tracks keyboard modifier and pointer button state across calls (so pressing {Shift>} in one keyboard() call stays held for the next), and a set of convenience methods (click, type, tab, hover, selectOptions, upload, clipboard.paste, and more) built on top of that shared state. Internally it models keyboard and pointer interaction as explicit System state machines fed by a small event-dispatch layer, so every convenience method ultimately resolves to the same primitive event sequence a browser would produce.

What You Get

  • A stateful userEvent.setup() session API that shares keyboard/pointer state across multiple interaction calls in a single test
  • High-level convenience methods — click, dblClick, tripleClick, hover, unhover, tab — for common interactions
  • A keyboard() API with a small DSL ({Shift>}, {Enter}, [KeyA]) for precise key-by-key and modifier-aware typing
  • A low-level pointer() API for scripting multi-step pointer/touch/pen interaction sequences (press, move, release)
  • Clipboard integration (copy, cut, paste) backed by a stubbed clipboard so paste-driven UI logic can be tested
  • Form-focused utilities: type, clear, upload, selectOptions, deselectOptions for exercising inputs, file pickers, and <select> elements

Common Use Cases

  • Typing into a form field character-by-character to trigger the same onChange/onKeyDown handlers a real keystroke would
  • Testing keyboard-only navigation flows (tab() through focusable elements) for accessibility coverage
  • Simulating drag-style or multi-step pointer interactions (press-move-release) for custom UI widgets
  • Verifying clipboard-driven features by scripting copy/paste against a stubbed clipboard
  • Uploading files to an <input type="file"> in tests without touching the real filesystem dialog

Under The Hood

Architecture

A setup() call produces a shared Instance object holding config, a System state machine, and the userEventApi method map; every convenience method is wrapped through a level-tracking async wrapper before it dispatches events via a dedicated event layer, so calls made against one session compose consistently. Keyboard and pointer state live as separate System sub-machines that convenience methods, the keyboard DSL, and the pointer API all read and mutate, which is what lets sequential calls on one instance behave like a continuous user session rather than isolated one-off actions.

Tech Stack

Written entirely in TypeScript and built with an esbuild-based pipeline (via the shared kcd-scripts toolchain), targeting CJS output. Tests run under Jest with a jsdom environment, configured through the same shared tooling. The package’s only runtime dependency is a peer dependency on @testing-library/dom — everything else in its dependency list is build or test tooling.

Code Quality

The test suite mirrors the source tree section-for-section (clipboard, convenience, document, event, keyboard, pointer, setup, system, utility), backed by shared test helpers for rendering fixtures and capturing dispatched events. Path aliases keep test imports pointed at source and helpers directly. Linting runs through a shared flat ESLint config augmented with project-specific custom rules, and CI runs a typecheck pass ahead of the test suite, indicating a strict, enforced quality bar.

API Design The central ergonomic choice is offering both a one-off direct call (userEvent.click(el)) and a stateful session (userEvent.setup() then user.click(el)) from the same method surface, so simple tests stay terse while multi-step interactions can share keyboard/pointer state. A compact keyboard description syntax (holding modifiers, naming specific physical keys) lets a single string argument express what would otherwise require several imperative press/release calls.

Used by 116 apps in this directory

TypeScript
92%
Other

OpenHands

AI Code Assistants · AI Development

91,695

The self-hosted developer control center for running AI coding agents — locally, in Docker, on VMs, or across cloud backends — with automation workflows for GitHub, Slack, and more.

View details
91
Repo Health
82
Technical
67
Dependency
Built with
TypeScript 92%
Updated 1 weeks ago
Go
36%

OpenPanel

Devops · Hosting Control Panel

764

Docker-powered web hosting control panel that gives every user a fully isolated environment with dedicated web server, database, and networking — VPS-grade security on shared hardware.

View details
87
Repo Health
75
Technical
63
Dependency
Built with
Go 36%
HTML 30%
TypeScript 24%
Updated 1 weeks ago
TypeScript
93%
MIT

OpenReel Video

Video Editors

5,442

A browser-based, GPU-accelerated video editor with multi-track timelines, color grading, and 4K export — no uploads, no installs, no watermarks.

View details
72
Repo Health
80
Technical
71
Dependency
Built with
TypeScript 93%
Updated 1 weeks ago
TypeScript
82%
MIT

OpenScreen

Design Tools · Note Taking · Productivity

39,920

Free, open-source screen recorder with zooms, annotations, and system audio capture

View details
62
Repo Health
85
Technical
78
Dependency
Built with
TypeScript 82%
Updated 1 weeks ago
JavaScript
90%
Other

OpenSign

Digital Signiture

7,163

Self-host a full-featured DocuSign alternative with unlimited e-signatures, multi-signer workflows, and cryptographic PDF signing.

View details
83
Repo Health
61
Technical
69
Dependency
Built with
JavaScript 90%
Updated 1 weeks ago
TypeScript
96%
MIT

Orca

AI Agents · AI Code Assistants

104,104

An open-source Agent Development Environment that orchestrates fleets of parallel AI coding agents — Claude Code, Codex, Gemini and more — each running in its own isolated git worktree.

View details
84
Repo Health
85
Technical
74
Dependency
Built with
TypeScript 96%
Updated 6 days ago
Python
68%
Apache 2.0

otari

AI Development · Developer Tools

733

A self-hosted, OpenAI-compatible LLM gateway that puts one endpoint in front of 40+ providers, with virtual API keys, per-user budgets enforced before spend, and full usage tracking.

View details
82
Repo Health
88
Technical
74
Dependency
Built with
Python 68%
TypeScript 31%
Updated 1 weeks ago
JavaScript
64%
AGPL 3.0

overleaf

Collaboration · Productivity

18,266

Open-source, real-time collaborative LaTeX editor with sandboxed compilation and full TeXLive support for self-hosted academic and research teams.

View details
84
Repo Health
80
Technical
59
Dependency
Built with
JavaScript 64%
TypeScript 30%
Updated 1 months ago
Go
93%
MIT

Plandex

AI Code Assistants

15,777

An open-source, terminal-based AI coding agent built for large tasks and real codebases — with its own version control for plans, a 2M-token effective context window, and self-hosted or cloud deployment.

View details
50
Repo Health
70
Technical
67
Dependency
Built with
Go 93%
Updated 1 years ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers