Recent Trend

Vite & Vue powered static site generator
Zulip server - powerful open source team chat
If Google News had a Python library
Revive unavailable songs for Netease Cloud Music
YApi 是一个可本地部署的、打通前后端及QA的、可视化的接口管理平台
The plugin-driven server agent for collecting & reporting metrics.
All materials for the Cassandra Workshop Series in a single place
A beautiful Redis GUI ?
Collection of Summer 2021 tech internships!
Cubit is a lightweight state management solution. It is a subset of the bloc package that does not rely on events and instead uses methods to emit new states.
Native-ESM powered web dev build tool. It's fast.
An Electron boilerplate including TypeScript, React, Jest and ESLint.
A modified browser that helps in responsive web development.
Build Mobile, Desktop and WebAssembly apps with C# and XAML. Today. Open source and professionally supported.
React components for faster and easier web development. Build your own design system, or start with Material Design.
Welcome to the Bot Framework samples repository. Here you will find task-focused samples in C#, JavaScript and TypeScript to help you get started with the Bot Framework SDK!
OpenPCDet Toolbox for LiDAR-based 3D Object Detection.
A simplified Jira clone built with Angular 9 and Akita
The ultimate snippets collection for VS Code
Based on a true story
Simple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with zero library dependencies.

? React Hooks for forms validation (Web + React Native)
Node Version Manager - POSIX-compliant bash script to manage multiple active node.js versions
开放式跨端跨框架解决方案,支持使用 React/Vue/Nerv 等框架来开发微信/京东/百度/支付宝/字节跳动/ QQ 小程序/H5 等应用。
A GUI frontend for @werman's Pulse Audio real-time noise suppression plugin
Updates to this repository will continue to arrive until the number of links reaches 10000 links & 10000 pdf files .Learn Ethical Hacking and penetration testing .hundreds of ethical hacking & penetra
Blazing fast hexapod robot simulator with React and Plotly.
C++ game engine focusing on modern rendering techniques and performance.
Silice is an open source language that simplifies writing algorithms fully exploiting FPGA architectures.
Python training for business analysts and traders
Official tensorflow implementation for CVPR2020 paper “Learning to Cartoonize Using White-box Cartoon Representations”
Ultimate Go study guide
This is a fun, new monospaced font that includes programming ligatures and is designed to enhance the modern look and feel of the Windows Terminal.
Rolling Rhino; convert Ubuntu into a rolling release as seen on YouTube
A repo for the pre-course work at home exercises
Learn python3 in one picture.
? TensorflowTTS: Real-Time State-of-the-art Speech Synthesis for Tensorflow 2
Drench yourself in Deep Learning, Reinforcement Learning, Machine Learning, Computer Vision, and NLP by learning from these exciting lectures!!
Matplotlib styles for scientific plotting
A pendant to warn you when you touch your face
A collection of all my Flutter Challenges
To-do list & time tracker for programmers & other digital workers with Jira, Github and Gitlab integration
Instant messaging server; backend in Go; iOS, Android, web, command line clients; chatbots
Graph Neural Networks with Keras and Tensorflow 2.
The near-instant build tool for modern web apps.
Books for machine learning, deep learning, math, NLP, CV, RL, etc
? List of awesome university courses for learning Computer Science!
Distributed scheduled job framework
? 互联网 Java 工程师进阶知识完全扫盲:涵盖高并发、分布式、高可用、微服务、海量数据处理等领域知识,后端同学必看,前端同学也可学习
PlayStation 2 DVD Player Exploit
Store SSH keys in the Secure Enclave
Learning Convolutional Neural Networks with Interactive Visualization.
阿里巴巴 MySQL binlog 增量订阅&消费组件
Open Source Computer Vision Library
Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance -- up to 40 times faster. If you need smashing performance, get yourself some Gin.
LeetCode Solutions: A Record of My Problem Solving Journey.( leetcode题解,记录自己的leetcode解题之路。)
? Building a federated alternative to reddit in rust
egui: Immediate mode GUI written in Rust, made for WASM
Open screens/snackbars/dialogs/bottomSheets without context, manage states and inject dependencies easily with Get.
beego is an open-source, high-performance web framework for the Go programming language.
A lightweight and ultra-fast tool for building observability pipelines
BBT - Bug Bounty Tools
Example code for HTML, CSS, and Javascript for Web Developers Coursera Course
? HonKit is building beautiful books using Markdown - Fork of GitBook
Display and control your Android device
Build forms in React, without the tears ?
A sandbox tower defense game
ARCore Depth Lab is a set of Depth API samples that provides assets using depth for advanced geometry-aware features in AR interaction and rendering. (UIST 2020)
Virtual-machine Translation Intermediate Language
Free online textbook of Jupyter notebooks for Computational Linear Algebra course
PyTorch implementation of FastSurferCNN
Solar2D Game Engine main repository (ex Corona SDK)
《On Java 8》中文版,又名《Java编程思想》 第5版
A collection of all the data i could extract from 1 billion leaked credentials from internet.
Minimal distributed configuration management in bash
California COVID Assessment Tool
CLI tool for Angular
? fgprof is a sampling Go profiler that allows you to analyze On-CPU as well as Off-CPU (e.g. I/O) time together.
Terraform AWS provider
Finally, a "back to top" button that behaves like a real elevator.
A toolkit for developing high-performance HTTP reverse proxy applications.
One framework. Mobile & desktop.
Data science Python notebooks: Deep learning (TensorFlow, Theano, Caffe, Keras), scikit-learn, Kaggle, big data (Spark, Hadoop MapReduce, HDFS), matplotlib, pandas, NumPy, SciPy, Python essentials, AW
Learn the skills required to sysadmin a remote Linux server from the commandline.
A Patch for GIMP 2.10+ for Photoshop Users
Distributed SQL database in Rust, written as a learning project
A cheat sheet that contains common enumeration and attack methods for Windows Active Directory.
Fluent System Icons is a set of mobile platform icons from Microsoft
The PHP Interpreter
A list of Free Software network services and web applications which can be hosted locally. Selfhosting is the process of hosting and managing applications instead of renting from Software-as-a-Service
? Open source machine learning framework to automate text- and voice-based conversations: NLU, dialogue management, connect to Slack, Facebook, and more - Create chatbots and voice assistants
Composable transformations of Python+NumPy programs: differentiate, vectorize, JIT to GPU/TPU, and more
A curated awesome list of lists of interview questions. Feel free to contribute! ?
Windows system utilities to maximize productivity
Build a ReactJS App workshop
This cheasheet is aimed at the CTF Players and Beginners to help them understand the fundamentals of Privilege Escalation with examples.
Highly cited and useful papers related to machine learning, deep learning, AI, game theory, reinforcement learning
The Ruby Programming Language [mirror]
? The missing package manager for macOS (or Linux)
[CVPR2020] Adversarial Latent Autoencoders
? A UI Design Language and React UI library
High performance Spigot fork that aims to fix gameplay and mechanics inconsistencies
Learn OpenCV : C++ and Python Examples
A utility-first CSS framework for rapid UI development.
An extremely fast JavaScript bundler and minifier
⚛️ Hooks for fetching, caching and updating asynchronous data in React
[CVPR 2020] 3D Photography using Context-aware Layered Depth Inpainting
Nginx UI allows you to access and modify the nginx configurations files without cli.
《史上最简单的Spring Cloud教程源码》
Learning operating system development using Linux kernel and Raspberry Pi
A traffic simulation game exploring how small changes to roads affect cyclists, transit users, pedestrians, and drivers.
Apache Spark - A unified analytics engine for large-scale data processing
Open-source IoT Platform - Device management, data collection, processing and visualization.
For better displaying html files and course material use this link
▶️ 跨平台桌面端视频资源播放器.简洁无广告.免费高颜值. ?
Modern HTTP benchmarking tool
傲娇钉宫,鞭写鞭骂 - 钉宫理惠 vscode-rainbow-fart 扩展语音包
Resources for Blazor, a .NET web framework using C#/Razor and HTML that runs in the browser with WebAssembly.
Smart NFC & ink-Display Card
Read all about it on GrumpyGamer:

A very minimal but elegant emacs (I think)

TeachYourselfCS 的中文翻译 | A Chinese translation of TeachYourselfCS
Tsunami is a general purpose network security scanner with an extensible plugin system for detecting high severity vulnerabilities with high confidence.

spring boot demo 是一个用来深度学习并实战 spring boot 的项目,目前总共包含 65 个集成demo,已经完成 53 个。 该项目已成功集成 actuator(监控)、admin(可视化监控)、logback(日志)、aopLog(通过AOP记录web请求日志)、统一异常处理(json级别和页面级别)、freemarker(模板引擎)、thymeleaf(模板引擎)、Be
Code Sample of Book "Effective Python: 59 Specific Ways to Write Better Pyton" by Brett Slatkin
VK driver for the Raspberry Pi (Broadcom Videocore IV)
Face Depixelizer based on "PULSE: Self-Supervised Photo Upsampling via Latent Space Exploration of Generative Models" repository.
告别枯燥,60 秒学会一个 Python 小例子
AI and Machine Learning with Kubeflow, Amazon EKS, and SageMaker
DeDRM tools for ebooks
A complete computer science study plan to become a software engineer.
Novel Coronavirus (COVID-19) Cases, provided by JHU CSSE
Original Apollo 11 Guidance Computer (AGC) source code for the command and lunar modules.
Empowering everyone to build reliable and efficient software.
Command-line program to download videos from and other video sites
Arduino core for the ESP32

An open source re-implementation of Diablo 2
Extremely fast non-cryptographic hash algorithm
A collective list of free APIs for use in software and web development.
This is a repo which documents real bugs in real software to illustrate trends, learn how to prevent or find them more quickly.
Kubernetes Goat is "Vulnerable by Design" Kubernetes Cluster.
Curated list of project-based tutorials
一个在你编程时疯狂称赞你的 VSCode 扩展插件 | An VSCode extension that keeps giving you compliment while you are coding, it will checks the keywords of code to play suitable sounds.

Combination of multiple linters to install as a GitHub Action
Open Source / i18n / Cross Platform Contact Tracing App by exposure notification framework.

A list of GOG Galaxy 2.0 integrations and upcoming features
InputStream based Netflix plugin for Kodi
GoPlus - The Go+ language for data science
Pokémon Save File Editor
Detectron2 is FAIR's next-generation platform for object detection and segmentation.
The Central Kubernetes Management Platform For Any Infrastructure
End-to-End Encryption for Zoom Meetings



一个涵盖六个专栏:Spring Boot 2.X、Spring Cloud、Spring Cloud Alibaba、Dubbo、分布式消息队列、分布式事务的仓库。希望胖友小手一抖,右上角来个 Star,感恩 1024
A beautiful, fully open-source, tunneling service - written in pure PHP
NOTE: Please report here only issues related to the python API. Issues and general feedback regarding the Galaxy Client 2.0 shall be sent via Galaxy Client menu
一套涵盖大部分核心组件使用的Spring Cloud教程,包括Spring Cloud Alibaba及分布式事务Seata,基于Spring Cloud Greenwich及SpringBoot 2.1.7。20篇文章,篇篇精华,30个Demo,涵盖大部分应用场景。

Self-Supervised Learning Toolbox and Benchmark
A scriptable scratchpad for developers. In slow yet steady progress.
PARL A high-performance distributed training framework for Reinforcement Learning
React Hooks Library
Open source documentation of Microsoft Azure
Lens - The Kubernetes IDE

The AWS Cloud Development Kit is a framework for defining cloud infrastructure in code
multi_task_NLP is a utility toolkit enabling NLP developers to easily train and infer a single model for multiple tasks.
Python - 100天从新手到大师
A tool for refactoring code related to feature flag APIs
Davinci is a DVsaaS (Data Visualization as a Service) Platform
StyleGAN2 - Official TensorFlow Implementation
[mirror] Home of the website
BYOB (Build Your Own Botnet)
Native iOS app using the exposure notification framework from Apple.

Corona-Warn-App website
Documentation for the Microsoft Graph REST API
The source for REST API specifications for Microsoft Azure.

Elegant HTTP Networking in Swift
Declarative continuous deployment for Kubernetes.
Date & Time pickers, built with ❤️ for @material-ui/core
An open source, portable, easy to use, readable and flexible SSL library
A library for generating fake data such as names, addresses, and phone numbers.
A simple baseline for one-shot multi-object tracking
700+ Pure CSS, SVG & Figma UI Icons Available in SVG Sprite, styled-components, NPM & API
Arm Mbed OS is a platform operating system designed for the internet of things
Testcontainers is a Java library that supports JUnit tests, providing lightweight, throwaway instances of common databases, Selenium web browsers, or anything else that can run in a Docker container.
Core integrations of the Datadog Agent
Backend implementation of the verification process
A tool for secrets management, encryption as a service, and privileged access management
The files from the United States government on 9/11, released by wiki leaks.
PULSE: Self-Supervised Photo Upsampling via Latent Space Exploration of Generative Models
JSON for Modern C++
High-Resolution 3D Human Digitization from A Single Image.
Android terminal and Linux environment - packages repository.
Tools to set up a quick macOS VM in QEMU, accelerated by KVM.

An ebook reader application supporting PDF, DjVu, EPUB, FB2 and many more formats, running on Cervantes, Kindle, Kobo, PocketBook and Android devices
Social network for developers, built on the MERN stack
Install Linux from a running Windows system, without need for a live USB.
Backend implementation for the Apple/Google exposure notification API.
OpenCore bootloader
GPT-3: Language Models are Few-Shot Learners
Native Android app using the Apple/Google exposure notification API.
An advanced Twitter scraping & OSINT tool written in Python that doesn't use Twitter's API, allowing you to scrape a user's followers, following, Tweets and more while evading most API limitations.


ESP8266 core for Arduino
Flash OS images to SD cards & USB drives, safely and easily.
⏬ Dumb downloader that scrapes the web
An enterprise-class UI components based on Ant Design and Vue.
The fastai deep learning library, plus lessons and tutorials
Collection of 8000+ publicly available IPTV channels from all over the world
The ultimate collection of scripts for YouTube-DL.
A secure JavaScript and TypeScript runtime
nodejsscan is a static security code scanner for Node.js applications.
Lean's OpenWrt source
Source code for the book "Violent Python" by TJ O'Connor. The code has been fully converted to Python 3, reformatted to comply with PEP8 standards and refactored to eliminate issues involving the impl
A delightful networking framework for iOS, macOS, watchOS, and tvOS.
Microsoft Quantum Development Kit Samples

Open source audio annotation tool for humans™
Source code for the book "Black Hat Python" by Justin Seitz. The code has been fully converted to Python 3, reformatted to comply with PEP8 standards and refactored to eliminate issues of dependency r
A long list of (advanced) JavaScript questions, and their explanations ✨
Code for a dynamic multilevel Bayesian model to predict US presidential elections. Written in R and Stan.
A modular framework for vision & language multimodal research from Facebook AI Research (FAIR)
A payment application to demonstrate real-world usage of Cypress testing methods, patterns, and workflows.

Build machine learning APIs
Haskell-style functional programming language running on Erlang VM.

PowerShell script for automation of routine tasks done after fresh installations of Windows 10 / Server 2016 / Server 2019
Node library to automate Chromium, Firefox and WebKit with a single API
程序员如何优雅的挣零花钱,2.0版,升级为小书了。Most of this not work outside China , so no English translate
A library that provides an embeddable, persistent key-value store for fast storage.
CVE-2020-0796 Remote Code Execution POC is an open source base building game inspired by factorio! Available on web & desktop
Eclipse Theia is a cloud & desktop IDE framework implemented in TypeScript.
CVPR 2020 论文开源项目合集
mall项目是一套电商系统,包括前台商城系统及后台管理系统,基于SpringBoot+MyBatis实现,采用Docker容器化部署。 前台商城系统包含首页门户、商品推荐、商品搜索、商品展示、购物车、订单流程、会员中心、客户服务、帮助中心等模块。 后台管理系统包含商品管理、订单管理、会员管理、促销管理、运营管理、内容管理、统计报表、财务管理、权限管理、设置等模块。
Xamarin.Forms Official Home
Atari 8 bit computers, NES and SMS game consoles on your TV with nothing more than a ESP32 and a sense of nostalgia
手把手撕LeetCode题目,扒各种算法套路的裤子。English version supported! Crack LeetCode, not only how, but also why.
Hide secrets with invisible characters in plain text securely using passwords
Open-source self-hosted email marketing. Manage your own newsletters at a fraction of the cost.

This repository holds the content submitted to Files added to the tutorials/ will appear at
"More than just a rewrite of Windows Explorer"
Gravity Programming Language
A full-stack framework for Laravel that takes the pain out of building dynamic UIs.

Full ASP.NET Core 3.1 application with DDD, CQRS and Event Sourcing concepts
Hummingbird compiles trained ML models into tensor computation for faster inference.
Procedurally generated Chinese landscape painting.
Vulnerability checker for Callstranger (CVE-2020-12695)
UtahFS is an encrypted storage system that provides a user-friendly FUSE drive backed by cloud storage.

Bringing Characters to Life with Computer Brains in Unity
YOLOv5 in PyTorch > ONNX > CoreML > iOS
Fast, easy and reliable testing for anything that runs in a browser.

Googletest - Google Testing and Mocking Framework
Google Cloud Client Libraries for Go.
Stay Awake is a simple app that keeps your computer from going to sleep.
The fastest wiki and knowledge base for growing teams. Beautiful, feature rich, and markdown compatible.
PHP Static Analysis Tool - discover bugs in your code without running it!
Docker images for .NET Core and the .NET Core Tools.
CryptoSwift is a growing collection of standard and secure cryptographic algorithms implemented in Swift

The ultimate Free Open Source Solution for team communications.
A uniform interface to run deep learning models from multiple frameworks
n³ The missing terminal file manager for X.
The Docker toolset to pack, ship, store, and deliver content
Seamless REST/GraphQL API mocking library for browser and Node.
ShowDoc is a tool greatly applicable for an IT team to share documents online一个非常适合IT团队的在线API文档、技术文档工具
Device code for the Meshtastic ski/hike/fly/customizable open GPS radio

A Ruby static code analyzer and formatter, based on the community Ruby style guide.
A Collection of application ideas which can be used to improve your coding skills.
fsociety Hacking Tools Pack – A Penetration Testing Framework
Documentation for ASP.NET Core
binary releases of VS Code without MS branding/telemetry/licensing
The Incredible PyTorch: a curated list of tutorials, papers, projects, communities and more relating to PyTorch.
Firebase iOS SDK
A guide to writing a DNS Server from scratch in Rust
A dynamic infrastructure toolkit for red teamers and bug bounty hunters!
Super-project for modularized Boost
Bootstrap post-collapse technology
A new type of shell
A series of Jupyter notebooks that walk you through the fundamentals of Machine Learning and Deep Learning in Python using Scikit-Learn, Keras and TensorFlow 2.
A very simple toon lit shader example, for you to learn writing custom lit shader in Unity URP
How I'm learning to build secure systems
SpringBoot 相关漏洞学习资料,利用方法和技巧合集,黑盒安全评估 checklist
A curated list of insanely awesome libraries, packages and resources for Quants (Quantitative Finance)
A Markdown Editor for the 21st century.
My Python Examples
Azure RTOS ThreadX is an advanced real-time operating system (RTOS) designed specifically for deeply embedded applications.
Open Source real-time strategy game engine for early Westwood games such as Command & Conquer: Red Alert written in C# using SDL and OpenGL. Runs on Windows, Linux, *BSD and Mac OS X.
Python Data Science Handbook: full text in Jupyter Notebooks
Deepfakes Software For All
tic-tac-toe in a single call to printf
Notebooks based on financial machine learning.
Nomad is an easy-to-use, flexible, and performant workload orchestrator that can deploy a mix of microservice, batch, containerized, and non-containerized applications. Nomad is easy to operate and sc
All Algorithms implemented in Python
simplest possible native GUI for inspecting JSON objects with jq
Create beautiful diagrams just by typing mathematical notation in plain text.
TensorFlow Tutorial and Examples for Beginners (support TF v1 & v2)
JetBrains license servers 2020-2021 IntelliJ WebStorm PyCharm PhpStorm 05 May 2020 works; yo ho ho from Ukraine!
All Algorithms implemented in C++
Avatars for Zoom, Skype and other video-conferencing apps.
All Algorithms implemented in Java
Advanced table plugin
Repository containing evidence of police brutality during the 2020 George Floyd protests

Lightning Fast, Ultra Relevant, and Typo-Tolerant Search Engine
Reset your IDE eval information.
Mac in Docker! Run near native OSX-KVM in Docker! X11 Forwarding!

A place for creators and users of password managers to collaborate on resources to make password management better.
A genetic algorithm toy project for drawing
An unidentifiable mechanism that helps you bypass GFW.
Python tool for grabbing text via screenshot
vue-admin-beautiful是一款绝佳的前端开发框架(基于vue/cli 4 最新版,同时支持电脑,手机,平板),长期更新维护,感谢您的star,我一直在努力 Vue admin beautiful is an excellent front-end development framework (supporting computers, mobile phones and tablet
An interactive deep learning book with code, math, and discussions.
A platform for building proxies to bypass network restrictions.
Reset Intellij IDEA, WebStorm, DataGrip, PhpStorm, CLion, PyCharm, RubyMine, GoLand and Rider evaluation (2019 / 2020 / Mac OS)
深度学习入门开源书,基于TensorFlow 2.0案例实战。Open source Deep Learning book, based on TensorFlow 2.0 framework.
The iconic SVG, font, and CSS toolkit
Run macOS on QEMU/KVM. With OpenCore Now! No free support is provided. Open PR(s) to fix problems.
Project overview, general documentation, and white papers.


Productive & portable programming language for high-performance, sparse & differentiable computing
DeepFaceLab is the leading software for creating deepfakes.
Personal Wiki for Vim
✅ The Node.js best practices list (June 2020)
A fast JSON parser/generator for Java.
Substrate: The platform for blockchain innovators
Web APIs for Django.
Collection of Technical Interview Questions solved with Go
End-to-End Object Detection with Transformers
Flutter仿微博客户端, 包含首页、视频、发现、消息(仿微博聊界面)及个人中心模块
Practical Python Programming (course by @dabeaz)


JavaScript LINK
⚛️ Hooks for fetching, caching and updating asynchronous data in React

React Query Header

Hooks for fetching, caching and updating asynchronous data in React



Join the discussion on Github

Enjoy this library? Try them all! React Table, React Form, React Charts

Quick Features

Core Issues and Solution ## The Challenge Tools for managing "global state" are plentiful these days, but most of these tools: - Mistake **server cache state** for **global state** - Force you to manage async data in a synchronous way - Duplicate unnecessary network operations - Use naive or over-engineered caching strategies - Are too basic to handle large-scale apps or - Are too complex or built for highly-opinionated systems like Redux, GraphQL, [insert proprietary tools], etc. - Do not provide tools for server mutations - Either do not provide easy access to the cache or do, but expose overpowered foot-gun APIs to the developer ## The Solution React Query exports a set of hooks that address these issues. Out of the box, React Query: - Separates your **server cache state** from your **global state** - Provides async aware APIs for reading and updating server state/cache - Dedupes both async and sync requests to async resources - Automatically caches data, invalidates and refetches stale data, and manages garbage collection of unused data - Scales easily as your application grows - Is based solely on Promises, making it highly unopinionated and interoperable with any data fetching strategy including REST, GraphQL and other transactional APIs - Provides an integrated promise-based mutation API - Opt-in Manual or Advance cache management Inspiration & Hat-Tipping
A big thanks to both [Draqula]( for inspiring a lot of React Query's original API and documentation and also [Vercel's SWR]( and its creators for inspiring even further customizations and examples. You all rock! How is this different from Vercel's SWR?
[Vercel's SWR]( is a great library, and is very similar in spirit and implementation to React Query with a few notable differences: - Automatic Cache Garbage Collection - React Query handles automatic cache purging for inactive queries and garbage collection. This can mean a much smaller memory footprint for apps that consume a lot of data or data that is changing often in a single session - `useMutation` - A dedicated hook for handling generic lifecycles around triggering mutations and handling their side-effects in applications. SWR does not ship with anything similar, and you may find yourself reimplementing most if not all of `useMutation`'s functionality in user-land. With this hook, you can extend the lifecycle of your mutations to reliably handle successful refetching strategies, failure rollbacks and error handling. - Prefetching - React Query ships with 1st class prefetching utilities which not only come in handy with non-suspenseful apps but also make fetch-as-you-render patterns possible with React Query. SWR does not come with similar utilities and relies on `` and/or manually fetching and updating the query cache - Query cancellation integration is baked into React Query. You can easily use this to wire up request cancellation in most popular fetching libraries, including but not limited to fetch and axios. - Query Key Generation - React Query uses query key generation, query variables, and implicit query grouping. The query key and variables that are passed to a query are less URL/Query-based by nature and much more flexible. All items supplied to the query key array are used to compute the unique key for a query (using a stable and deterministic sorting/hashing implementation). This means you can spend less time thinking about precise key matching, but more importantly, allows you to use partial query-key matching when refetching, updating, or removing queries in mass eg. you can refetch every query that starts with a `todos` in its key, regardless of variables, or you can target specific queries with (or without) variables, and even use functional filtering to select queries in most places. This architecture is much more robust and forgiving especially for larger apps.

Videos and Tutorials

Used By

These analytics are made available via the awesome Scarf package analytics library



This library is being built and maintained by me, @tannerlinsley and I am always in need of more support to keep projects like this afloat. If you would like to get premium support, add your logo or name on this README, or simply just contribute to my open source Sponsorship goal, visit my Github Sponsors page!

Diamond Sponsors

Get Your Logo Here!

Gold Sponsors

Get Your Logo Here!

Silver Sponsors

Bronze Sponsors



Become a Sponsor



$ npm i --save react-query
# or
$ yarn add react-query

React Query uses Scarf to collect anonymized installation analytics. These analytics help support the maintainers of this library. However, if you'd like to opt out, you can do so by setting scarfSettings.enabled = false in your project's package.json. Alternatively, you can set the environment variable SCARF_ANALYTICS=false before you install.

Defaults to keep in mind

Out of the box, React Query is configured with aggressive but sane defaults. Sometimes these defaults can catch new users off guard or make learning/debugging difficult if they are unknown by the user. Keep them in mind as you continue to learn and use React Query:


To make a new query, call the useQuery hook with at least:

import { useQuery } from 'react-query'

function App() {
  const info = useQuery('todos', fetchTodoList)

The unique key you provide is used internally for refetching, caching, deduping related queries.

The query info returned contains all information about the query and can be easily destructured and used in your component:

function Todos() {
  const { isLoading, isError, data, error } = useQuery('todos', fetchTodoList)

  if (isLoading) {
    return <span>Loading...</span>

  if (isError) {
    return <span>Error: {error.message}</span>

  // also status === 'success', but "else" logic works, too
  return (
      { => (
        <li key={}>{todo.title}</li>

If booleans aren't your thing, you can also use the status string to do the same:

function Todos() {
  const { status, data, error } = useQuery('todos', fetchTodoList)

  if (status === 'loading') {
    return <span>Loading...</span>

  if (status === 'error') {
    return <span>Error: {error.message}</span>

  // also status === 'success', but "else" logic works, too
  return (
      { => (
        <li key={}>{todo.title}</li>

Query Keys

At its core, React Query manages query caching for you based on query keys. Query keys can be as simple as a string, or as complex as an array or nested object of values. As long as the key is serializable, and unique to the query's data, you can use it!

If you're learning React Query still, we suggest starting with using strings and arrays with strings/numbers, then working your way up to using more complex query keys.

String-Only Query Keys

The simplest form of a key is actually not an array, but an individual string. When a string query key is passed, it is converted to an array internally with the string as the only item in the query key. This format is useful for:

// A list of todos
useQuery('todos', ...) // queryKey === ['todos']

// Something else, whatever!
useQuery('somethingSpecial', ...) // queryKey === ['somethingSpecial']

Array Keys

When a query needs more information to uniquely describe its data, you can use an array with a string and any number of serializable objects to describe it. This is useful for:

// An individual todo
useQuery(['todo', 5], ...)
// queryKey === ['todo', 5]

// And individual todo in a "preview" format
useQuery(['todo', 5, { preview: true }], ...)
// queryKey === ['todo', 5, { preview: 'true' } }]

// A list of todos that are "done"
useQuery(['todos', { type: 'done' }], ...)
// queryKey === ['todos', { type: 'done' }]

Query Keys are serialized deterministically!

This means that no matter the order of keys in objects, all of the following queries would result in the same final query key of ['todos', { page, status }]:

useQuery(['todos', { status, page }], ...)
useQuery(['todos', { page, status }], ...)
useQuery(['todos', { page, status, other: undefined }], ...)

The following query keys, however, are not equal. Array item order matters!

useQuery(['todos', status, page], ...)
useQuery(['todos', page, status], ...)
useQuery(['todos', undefined, page, status], ...)

Query Key Variables

To use external props, state, or variables in a query function, it's easiest to pass them as items in your array query keys! All query keys get passed through to your query function as parameters in the order they appear in the array key:

function Todos({ completed }) {
  const queryInfo = useQuery(['todos', { status, page }], fetchTodoList)

// Access the key, status and page variables in your query function!
function fetchTodoList(key, { status, page }) {
  return new Promise()
  // ...

If you send through more items in your query key, they will also be available in your query function:

function Todo({ todoId, preview }) {
  const queryInfo = useQuery(['todo', todoId, { preview }], fetchTodoById)

// Access status and page in your query function!
function fetchTodoById(key, todoId, { preview }) {
  return new Promise()
  // ...

Whenever a query's key changes, the query will automatically update. In the following example, a new query is created whenever todoId changes:

function Todo({ todoId }) {
  const queryInfo = useQuery(['todo', todoId], fetchTodo)

Using a Query Object instead of parameters

Anywhere the [queryKey, queryFn, config] signature is supported throughout React Query's API, you can also use an object to express the same configuration:

import { useQuery } from 'react-query'

  queryKey: ['todo', 7],
  queryFn: fetchTodos,
  config: {},

Parallel Queries

React Query is built to require no extra effort for making parallel queries. You don't need to do anything special! Just use React Query's hooks and handle all of the loading states and you're good to go!

Dependent Queries

Dependent (or serial) queries are queries that depend on previous ones to finish before they can execute. To do this, use the enabled option to tell a query when it is ready to turn on:

// Get the user
const { data: user } = useQuery(['user', email], getUserByEmail)

// Then get the user's projects
const { isIdle, data: projects } = useQuery(
    // `user` would be `null` at first (falsy),
    // so the query will not execute until the user exists
    enabled: user,

// isIdle will be `true` until `enabled` is true and the query begins to fetch. It will then go to the `isLoading` stage and hopefully the `isSuccess` stage :)

Caching & Invalidation

React Query caching is automatic out of the box. It uses a stale-while-revalidate in-memory caching strategy (popularized by HTTP RFC 5861) and a very robust query deduping strategy to always ensure a query's data is always readily available, only cached when it's needed, even if that query is used multiple times across your application and updated in the background when possible.

At a glance:

A more detailed example of the caching lifecycle Let's assume we are using the default `cacheTime` of **5 minutes** and the default `staleTime` of `0`. - A new instance of `useQuery('todos', fetchTodos)` mounts. - Since no other queries have been made with this query + variable combination, this query will show a hard loading state and make a network request to fetch the data. - It will then cache the data using `'todos'` and `fetchTodos` as the unique identifiers for that cache. - A stale invalidation is scheduled using the `staleTime` option as a delay (defaults to `0`, or immediately). - A second instance of `useQuery('todos', fetchTodos)` mounts elsewhere. - Because this exact data exist in the cache from the first instance of this query, that data is immediately returned from the cache. - Both instances of the `useQuery('todos', fetchTodos)` query are unmounted and no longer in use. - Since there are no more active instances to this query, a cache timeout is set using `cacheTime` to delete and garbage collect the query (defaults to **5 minutes**). - No more instances of `useQuery('todos', fetchTodos)` appear within **5 minutes**. - This query and its data are deleted and garbage collected.

Paginated Queries with usePaginatedQuery

Rendering paginated data is a very common UI pattern to avoid overloading bandwidth or even your UI. React Query exposes a usePaginatedQuery that is very similar to useQuery that helps with this very scenario.

Consider the following example where we would ideally want to increment a pageIndex (or cursor) for a query. If we were to use useQuery, it would technically work fine, but the UI would jump in and out of the success and loading states as different queries are created and destroyed for each page or cursor. By using usePaginatedQuery we get a few new things:

function Todos() {
  const [page, setPage] = React.useState(0)

  const fetchProjects = (key, page = 0) => fetch('/api/projects?page=' + page)

  const {
  } = usePaginatedQuery(['projects', page], fetchProjects)

  return (
      {isLoading ? (
      ) : isError ? (
        <div>Error: {error.message}</div>
      ) : (
        // `resolvedData` will either resolve to the latest page's data
        // or if fetching a new page, the last successful page's data
          { => (
            <p key={}>{}</p>
      <span>Current Page: {page + 1}</span>
        onClick={() => setPage(old => Math.max(old - 1, 0))}
        disabled={page === 0}
        Previous Page
      </button>{' '}
        onClick={() =>
          // Here, we use `latestData` so the Next Page
          // button isn't relying on potentially old data
          setPage(old => (!latestData || !latestData.hasMore ? old : old + 1))
        disabled={!latestData || !latestData.hasMore}
        Next Page
        // Since the last page's data potentially sticks around between page requests,
        // we can use `isFetching` to show a background loading
        // indicator since our `status === 'loading'` state won't be triggered
        isFetching ? <span> Loading...</span> : null
      }{' '}

Load-More & Infinite-Scroll with useInfiniteQuery

Rendering lists that can additively "load more" data onto an existing set of data or "infinite scroll" is also a very common UI pattern. React Query supports a useful version of useQuery called useInfiniteQuery for querying these types of lists.

When using useInfiniteQuery, you'll notice a few things are different:


Let's assume we have an API that returns pages of projects 3 at a time based on a cursor index along with a cursor that can be used to fetch the next group of projects

// { data: [...], nextCursor: 3}
// { data: [...], nextCursor: 6}
// { data: [...], nextCursor: 9}
// { data: [...] }

With this information, we can create a "Load More" UI by:

Note: It's very important you do not call fetchMore with arguments unless you want them to override the fetchMoreInfo data returned from the getFetchMore function. eg. Do not do this: <button onClick={fetchMore} /> as this would send the onClick event to the fetchMore function.

import { useInfiniteQuery } from 'react-query'

function Projects() {
  const fetchProjects = (key, cursor = 0) =>
    fetch('/api/projects?cursor=' + cursor)

  const {
  } = useInfiniteQuery('projects', fetchProjects, {
    getFetchMore: (lastGroup, allGroups) => lastGroup.nextCursor,

  return status === 'loading' ? (
  ) : status === 'error' ? (
    <p>Error: {error.message}</p>
  ) : (
      {, i) => (
        <React.Fragment key={i}>
          { => (
            <p key={}>{}</p>
          onClick={() => fetchMore()}
          disabled={!canFetchMore || isFetchingMore}
            ? 'Loading more...'
            : canFetchMore
            ? 'Load More'
            : 'Nothing more to load'}
      <div>{isFetching && !isFetchingMore ? 'Fetching...' : null}</div>

What happens when an infinite query needs to be refetched?

When an infinite query becomes stale and needs to be refetched, each group is fetched sequentially, starting from the first one. This ensures that even if the underlying data is mutated we're not using stale cursors and potentially getting duplicates or skipping records. If an infinite query's results are ever removed from the cache, the pagination restarts at the initial state with only the initial group being requested.

What if I need to pass custom information to my query function?

By default, the info returned from getFetchMore will be supplied to the query function, but in some cases, you may want to override this. You can pass custom variables to the fetchMore function which will override the default info like so:

function Projects() {
  const fetchProjects = (key, cursor = 0) =>
    fetch('/api/projects?cursor=' + cursor)

  const {
  } = useInfiniteQuery('projects', fetchProjects, {
    getFetchMore: (lastGroup, allGroups) => lastGroup.nextCursor,

  // Pass your own custom fetchMoreInfo
  const skipToCursor50 = () => fetchMore(50)

What if I want to infinitely load more data in reverse?

Sometimes you may not want to append infintely loaded data, but instead prepend it. If this is case, you can use fetchMore's previous option, eg.

fetchMore(previousPageVariables, { previous: true })

This will ensure the new data is prepended to the data array instead of appended.

Scroll Restoration

Out of the bx, "scroll restoration" for all queries (including paginated and infinite queries) Just Works™️ in React Query. The reason for this is that query results are cached and able to be retrieved synchronously when a query is rendered. As long as your queries are being cached long enough (the default time is 5 minutes)o and have not been garbage collected, scroll restoration will work out of the box all the time.

Disabling or Pausing a Query

If you ever want to disable a query from automatically running, you can use the enabled = false option.

When enabled is false:

function Todos() {
  const {
  } = useQuery('todos', fetchTodoList, {
    enabled: false,

  return (
      <button onClick={() => refetch()}>Fetch Todos</button>

      {isIdle ? (
        'Not ready...'
      ) : isLoading ? (
      ) : isError ? (
        <span>Error: {error.message}</span>
      ) : (
            { => (
              <li key={}>{todo.title}</li>
          <div>{isFetching ? 'Fetching...' : null}</div>


When a useQuery query fails (the query function throws an error), React Query will automatically retry the query if that query's request has not reached the max number of consecutive retries (defaults to 3) or a function is provided to determine if a retry is allowed.

You can configure retries both on a global level and an individual query level.

import { useQuery } from 'react-query'

// Make specific query retry a certain number of times
const queryInfo = useQuery(['todos', 1], fetchTodoListPage, {
  retry: 10, // Will retry failed requests 10 times before displaying an error

Retry Delay

By default, retries in React Query do not happen immediately after a request fails. As is standard, a back-off delay is gradually applied to each retry attempt.

The default retryDelay is set to double (starting at 1000ms) with each attempt, but not exceed 30 seconds:

// Configure for all queries
import { ReactQueryConfigProvider } from 'react-query'

const queryConfig = {
  queries: {
    retryDelay: attemptIndex => Math.min(1000 * 2 ** attemptIndex, 30000),

function App() {
  return (
    <ReactQueryConfigProvider config={queryConfig}>

Though it is not recommended, you can obviously override the retryDelay function/integer in both the Provider and individual query options. If set to an integer instead of a function the delay will always be the same amount of time:

const queryInfo = useQuery('todos', fetchTodoList, {
  retryDelay: 1000, // Will always wait 1000ms to retry, regardless of how many retries


If you're lucky enough, you may know enough about what your users will do to be able to prefetch the data they need before it's needed! If this is the case, you can use the prefetchQuery function to prefetch the results of a query to be placed into the cache:

import { queryCache } from 'react-query'

const prefetchTodos = async () => {
  const queryData = await queryCache.prefetchQuery('todos', () =>
  // The results of this query will be cached like a normal query

The next time a useQuery instance is used for a prefetched query, it will use the cached data! If no instances of useQuery appear for a prefetched query, it will be deleted and garbage collected after the time specified in cacheTime.

If a prefetched query is rendered after the staleTime for a prefetched query, it will still render, but will be automatically refetched in the background! Cool right?!

Manually Priming a Query

Alternatively, if you already have the data for your query synchronously available, you don't need to prefetch it. You can just use the Query Cache's setQueryData method to directly add or update a query's cached result.

import { queryCache } from 'react-query'

queryCache.setQueryData('todos', todos)

Initial Data

There may be times when you already have the initial data for a query synchronously available in your app. If and when this is the case, you can use the config.initialData option to set the initial data for a query and skip the first round of fetching!

When providing an initialData value that is anything other than undefined:

function Todos() {
  const queryInfo = useQuery('todos', () => fetch('/todos'), {
    initialData: initialTodos,

Initial Data Function

If the process for accessing a query's initial data is intensive or just not something you want to perform on every render, you can pass a function as the initialData value. This function will be executed only once when the query is initialized, saving you precious memory and CPU:

function Todos() {
  const queryInfo = useQuery('todos', () => fetch('/todos'), {
    initialData: () => {
      return getExpensiveTodos()

Initial Data from Cache

In some circumstances, you may be able to provide the initial data for a query from the cached result of another. A good example of this would be searching the cached data from a todos list query for an individual todo item, then using that as the initial data for your individual todo query:

function Todo({ todoId }) {
  const queryInfo = useQuery(['todo', todoId], () => fetch('/todos'), {
    initialData: () => {
      // Use a todo from the 'todos' query as the initial data for this todo query
      return queryCache.getQueryData('todos')?.find(d => === todoId)

Most of the time, this pattern works well, but if the source query you're using to look up the initial data from is old, you may not want to use the data at all and just fetch from the server. To make this decision easier, you can use the queryCache.getQuery method instead to get more information about the source query, including a query.state.updatedAt timestamp you can use to decide if the query is "fresh" enough for your needs:

function Todo({ todoId }) {
  const queryInfo = useQuery(['todo', todoId], () => fetch('/todos'), {
    initialData: () => {
      // Get the query object
      const query = queryCache.getQuery('todos')

      // If the query exists and has data that is no older than 10 seconds...
      if (query && - query.state.updatedAt <= 10 * 1000) {
        // return the individual todo
        return => === todoId)

      // Otherwise, return undefined and let it fetch!

SSR & Initial Data

When using SSR (server-side-rendering) with React Query there are a few things to note:

const queryInfo = useQuery('todos', fetchTodoList, {
  initialData: [{ id: 0, name: 'Implement SSR!' }],

// data === [{ id: 0, name: 'Implement SSR!'}]

Or, alternatively you can just destructure from undefined in your query results:

const { status, data = [{ id: 0, name: 'Implement SSR!' }], error } = useQuery(

The query's state will still reflect that it is stale and has not been fetched yet, and once mounted, it will continue as normal and request a fresh copy of the query result.

Suspense Mode

NOTE: Suspense mode for React Query is experimental, same as Suspense for data fetchign itself. These APIs WILL change and should not be used in production unless you lock both your React and React Query versions to patch-level versions that are compatible with each other.

React Query can also be used with React's new Suspense for Data Fetching API's. To enable this mode, you can set either the global or query level config's suspense option to true.

Global configuration:

// Configure for all queries
import { ReactQueryConfigProvider } from 'react-query'

const queryConfig = {
  suspense: true,

function App() {
  return (
    <ReactQueryConfigProvider config={queryConfig}>

Query configuration:

import { useQuery } from 'react-query'

// Enable for an individual query
useQuery(queryKey, queryFn, { suspense: true })

When using suspense mode, status states and error objects are not needed and are then replaced by usage of the React.Suspense component (including the use of the fallback prop and React error boundaries for catching errors). Please see the Suspense Example for more information on how to set up suspense mode.

In addition to queries behaving differently in suspense mode, mutations also behave a bit differently. By default, instead of supplying the error variable when a mutation fails, it will be thrown during the next render of the component it's used in and propagate to the nearest error boundary, similar to query errors. If you wish to disable this, you can set the useErrorBoundary option to false. If you wish that errors are not thrown at all, you can set the throwOnError option to false as well!

Fetch-on-render vs Fetch-as-you-render

Out of the box, React Query in suspense mode works really well as a Fetch-on-render solution with no additional configuration. However, if you want to take it to the next level and implement a Fetch-as-you-render model, we recommend implementing Prefetching on routing and/or user interactions events to initialize queries before they are needed.

Canceling Query Requests

By default, queries that become inactive before their promises are resolved are simply ignored instead of canceled. Why is this?

But don't worry! If your queries are high-bandwidth or potentially very expensive to download, React Query exposes a generic way to cancel query requests using a cancellation token or other related API. To integrate with this feature, attach a cancel function to the promise returned by your query that implements your request cancellation. When a query becomes out-of-date or inactive, this promise.cancel function will be called (if available):

Using axios:

import { CancelToken } from 'axios'

const query = useQuery('todos', () => {
  // Create a new CancelToken source for this request
  const source = CancelToken.source()

  const promise = axios.get('/todos', {
    // Pass the source token to your request
    cancelToken: source.token,

  // Cancel the request if React Query calls the `promise.cancel` method
  promise.cancel = () => {
    source.cancel('Query was cancelled by React Query')

  return promise

Using fetch:

const query = useQuery('todos', () => {
  // Create a new AbortController instance for this request
  const controller = new AbortController()
  // Get the abortController's signal
  const signal = controller.signal

  const promise = fetch('/todos', {
    method: 'get',
    // Pass the signal to your request

  // Cancel the request if React Query calls the `promise.cancel` method
  promise.cancel = controller.abort

  return promise


Unlike queries, mutations are typically used to create/update/delete data or perform server side-effects. For this purpose, React Query exports a useMutation hook.

Basic Mutations

Assuming the server implements a ping mutation, that returns "pong" string, here's an example of the most basic mutation:

const PingPong = () => {
  const [mutate, { status, data, error }] = useMutation(pingMutation)

  const onPing = async () => {
    try {
      const data = await mutate()
      // { ping: 'pong' }
    } catch {
      // Uh oh, something went wrong
  return <button onClick={onPing}>Ping</button>

Just as with useQuery you can also use booleans if you'd like:

const [
  { isIdle, isLoading, isError, isSuccess, data, error },
] = useMutation(pingMutation)

Mutations without variables are not that useful, so let's add some variables to closer match reality.

Mutation Variables

To pass variables to your mutate function, call mutate with an object.

// Notice how the fetcher function receives an object containing
// all possible variables
const createTodo = ({ title }) => {
  /* trigger an http request */

const CreateTodo = () => {
  const [title, setTitle] = useState('')
  const [mutate] = useMutation(createTodo)

  const onCreateTodo = async e => {
    // Prevent the form from refreshing the page

    try {
      await mutate({ title })
      // Todo was successfully created
    } catch (error) {
      // Uh oh, something went wrong

  return (
    <form onSubmit={onCreateTodo}>
        onChange={e => setTitle(}
      <br />
      <button type="submit">Create Todo</button>

Even with just variables, mutations aren't all that special, but when used with the onSuccess option, the Query Cache's invalidateQueries method and the Query Cache's setQueryData method, mutations become a very powerful tool.

Note that since version 1.1.0, the mutate function is no longer called synchronously so you cannot use it in an event callback. If you need to access the event in onSubmit you need to wrap mutate in another function. This is due to React event pooling.

// This will not work
const CreateTodo = () => {
  const [mutate] = useMutation(event => {
    fetch('/api', new FormData(

  return <form onSubmit={mutate}>...</form>

// This will work
const CreateTodo = () => {
  const [mutate] = useMutation(formData => {
    fetch('/api', formData)
  const onSubmit = event => {
    mutate(new FormData(

  return <form onSubmit={onSubmit}>...</form>

Invalidating and Refetching Queries

Waiting for queries to become stale before they are fetched again doesn't always work, especially when you know for a fact that a query needs to get refetched. For that purpose, the queryCache has an invalidateQueries method that lets you manually mark queries as stale and potentially refetch them too!

import { queryCache } from 'react-query'


Note: Where other libraries that use normalized caches would attempt to update local queries with the new data imperatively, React Query gives you the tools to avoid the manual labor that comes with maintaining normalized caches and instead prescribes invalidation, background-refetching and ultimately atomic updates.

When a query is invalidated with invalidateQueries, two things happen:

Query Matching with invalidateQueries

When using APIs like invalidateQueries and removeQueries (and others that support partial query matching), you can match multiple queries by their prefix, or get really specific and match an exact query.

In this example, we can use the todos prefix to invalidate any queries that start with todos in their query key:

import { queryCache, useQuery } from 'react-query'


// Both queries below will be invalidated
const todoListQuery = useQuery('todos', fetchTodoList)
const todoListQuery = useQuery(['todos', { page: 1 }], fetchTodoList)

You can even invalidate queries with specific variables by passing a more specific query key to the invalidateQueries method:

queryCache.invalidateQueries(['todos', { type: 'done' }])

// The query below will be invalidated
const todoListQuery = useQuery(['todos', { type: 'done' }], fetchTodoList)
// However, the following query below will NOT be invalidated
const todoListQuery = useQuery('todos', fetchTodoList)

The invalidateQueries API is very flexible, so even if you want to only invalidate todos queries that don't have any more variables or subkeys, you can pass an exact: true option to the invalidateQueries method:

queryCache.invalidateQueries('todos', { exact: true })

// The query below will be invalidated
const todoListQuery = useQuery(['todos'], fetchTodoList)
// However, the following query below will NOT be invalidated
const todoListQuery = useQuery(['todos', { type: 'done' }], fetchTodoList)

If you find yourself wanting even more granularity, you can pass a predicate function to the invalidateQueries method. This function will receive each query object from the queryCache and allow you to return true or false for whether you want to invalidate that query:

  query => query.queryKey[0] === 'todos' && query.queryKey[1]?.version >= 10

// The query below will be invalidated
const todoListQuery = useQuery(['todos', { version: 20 }], fetchTodoList)
// The query below will be invalidated
const todoListQuery = useQuery(['todos', { version: 10 }], fetchTodoList)
// However, the following query below will NOT be invalidated
const todoListQuery = useQuery(['todos', { version: 5 }], fetchTodoList)

Using Mutations to Invalidate Queries

Invalidating queries is only half the battle. Knowing when to invalidate them is the other half. Usually when a mutation in your app succeeds, it's VERY likely that there are related queries in your application that need to be invalidated and possibly refetched to account for the new changes from your mutation.

For example, assume we have a mutation to post a new todo:

const [mutate] = useMutation(postTodo)

When a successful postTodo mutation happens, we likely want all todos queries to get invalidated and possibly refetched to show the new todo item. To do this, you can use useMutation's onSuccess options and the queryCache's invalidateQueries function:

import { useMutation, queryCache } from 'react-query'

// When this mutation succeeds, invalidate any queries with the `todos` or `reminders` query key
const [mutate] = useMutation(addTodo, {
  onSuccess: () => {

You can wire up your invalidations to happen using any of the following side-effect callbacks:

const [mutate] = useMutation(addTodo, {
  onError: () => {
    // An error happened!
  onSuccess: () => {
    // Boom baby!
  onSettled: () => {
    // Error or success... doesn't matter!

The promise returned by mutate() can be helpful as well for performing more granualar control flow in your app, and if you prefer that that promise only resolves after the onSuccess or onSettled callbacks, you can return a promise in either!:

const [mutate] = useMutation(addTodo, {
  onSuccess: async () => {
    console.log("I'm first!")
  onSettled: async () => {
    console.log("I'm second!")

const run = async () => {
  try {
    await mutate(todo)
    console.log("I'm third!")
  } catch {}

You might find that you want to add additional side-effects to some of the useMutation lifecycle at the time of calling mutate. To do that, you can provide any of the same callback options to the mutate function after your mutation variable. Supported option overrides include:

const [mutate] = useMutation(addTodo, {
  onSuccess: (data, mutationVariables) => {
    // I will fire first
  onSettled: (data, error, mutationVariables) => {
    // I will fire first
  onError: (error, mutationVariables) => {
    // I will fire first

mutate(todo, {
  onSuccess: (data, mutationVariables) => {
    // I will fire second!
  onSettled: (data, error, mutationVariables) => {
    // I will fire second!
  onError: (error, mutationVariables) => {
    // I will fire second!
  throwOnError: true,

Query Updates from Mutations

When dealing with mutations that update objects on the server, it's common for the new object to be automatically returned in the response of the mutation. Instead of refetching any queries for that item and wasting a network call for data we already have, we can take advantage of the object returned by the mutation function and update the existing query with the new data immediately using the Query Cache's setQueryData method:

const [mutate] = useMutation(editTodo, {
  onSuccess: data => queryCache.setQueryData(['todo', { id: 5 }], data),

  id: 5,
  name: 'Do the laundry',

// The query below will be updated with the response from the
// successful mutation
const { status, data, error } = useQuery(['todo', { id: 5 }], fetchTodoByID)

You might want to tight the onSuccess logic into a reusable mutation, for that you can create a custom hook like this:

const useMutateTodo = () => {
  return useMutate(editTodo, {
    // Notice the second argument is the variables object that the `mutate` function receives
    onSuccess: (data, variables) => {
      queryCache.setQueryData(['todo', { id: }], data)

Resetting Mutation State

It's sometimes the case that you need to clear the error or data of a mutation request. To do this, you can use the reset function to handle this:

const CreateTodo = () => {
  const [title, setTitle] = useState('')
  const [mutate, { error, reset }] = useMutation(createTodo)

  const onCreateTodo = async e => {
    await mutate({ title })

  return (
    <form onSubmit={onCreateTodo}>
      {error && <h5 onClick={() => reset()}>{error}</h5>}
        onChange={e => setTitle(}
      <br />
      <button type="submit">Create Todo</button>

Manually or Optimistically Setting Query Data

In rare circumstances, you may want to manually update a query's response with a custom value. To do this, you can again use the Query Cache's setQueryData method:

It's important to understand that when you manually or optimistically update a query's data value, the potential that you display out-of-sync data to your users is very high. It's recommended that you only do this if you plan to refetch the query very soon or perform a mutation to "commit" your manual changes (and also roll back your eager update if the refetch or mutation fails).

// Full replacement
queryCache.setQueryData(['todo', { id: 5 }], newTodo)

// or functional update
queryCache.setQueryData(['todo', { id: 5 }], previous => ({
  type: 'done',

Optimistic Updates with Automatic Rollback for Failed Mutations

When you optimistically update your state before performing a mutation, there is a non-zero chance that the mutation will fail. In most cases, you can just trigger a refetch for your optimistic queries to revert them to their true server state. In some circumstances though, refetching may not work correctly and the mutation error could represent some type of server issue that won't make it possible to refetch. In this event, you can instead choose to rollback your update.

To do this, useMutation's onMutate handler option allows you to return a value that will later be passed to both onError and onSettled handlers as the last argument. In most cases, it is most useful to pass a rollback function.

Updating a list of todos when adding a new todo

useMutation(updateTodo, {
  // When mutate is called:
  onMutate: newTodo => {
    // Cancel any outgoing refetches (so they don't overwrite our optimistic update)

    // Snapshot the previous value
    const previousTodos = queryCache.getQueryData('todos')

    // Optimistically update to the new value
    queryCache.setQueryData('todos', old => [...old, newTodo])

    // Return the snapshotted value
    return () => queryCache.setQueryData('todos', previousTodos)
  // If the mutation fails, use the value returned from onMutate to roll back
  onError: (err, newTodo, rollback) => rollback(),
  // Always refetch after error or success:
  onSettled: () => {

Updating a single todo

useMutation(updateTodo, {
  // When mutate is called:
  onMutate: newTodo => {
    // Cancel any outgoing refetches (so they don't overwrite our optimistic update)

    // Snapshot the previous value
    const previousTodo = queryCache.getQueryData(['todos',], newTodo)

    // Optimistically update to the new value
    queryCache.setQueryData(['todos',], newTodo)

    // Return a rollback function
    return () => queryCache.setQueryData(['todos',], previousTodo)
  // If the mutation fails, use the rollback function we returned above
  onError: (err, newTodo, rollback) => rollback(),
  // Always refetch after error or success:
  onSettled: () => {

You can also use the onSettled function in place of the separate onError and onSuccess handlers if you wish:

useMutation(updateTodo, {
  // ...
  onSettled: (newTodo, error, variables, rollback) => {
    if (error) {

Displaying Background Fetching Loading States

A query's status === 'loading' state is sufficient enough to show the initial hard-loading state for a query, but sometimes you may want to display an additional indicator that a query is refetching in the background. To do this, queries also supply you with an isFetching boolean that you can use to show that it's in a fetching state, regardless of the state of the status variable:

function Todos() {
  const { status, data: todos, error, isFetching } = useQuery(

  return status === 'loading' ? (
  ) : status === 'error' ? (
    <span>Error: {error.message}</span>
  ) : (
      {isFetching ? <div>Refreshing...</div> : null}

        { => (
          <Todo todo={todo} />

Displaying Global Background Fetching Loading State

In addition to individual query loading states, if you would like to show a global loading indicator when any queries are fetching (including in the background), you can use the useIsFetching hook:

import { useIsFetching } from 'react-query'

function GlobalLoadingIndicator() {
  const isFetching = useIsFetching()

  return isFetching ? (
    <div>Queries are fetching in the background...</div>
  ) : null

Window-Focus Refetching

If a user leaves your application and returns to stale data, you may want to trigger an update in the background to update any stale queries. Thankfully, React Query does this automatically for you, but if you choose to disable it, you can use the ReactQueryConfigProvider's refetchOnWindowFocus option to disable it:

const queryConfig = { queries: { refetchOnWindowFocus: false } }

function App() {
  return (
    <ReactQueryConfigProvider config={queryConfig}>

Custom Window Focus Event

In rare circumstances, you may want to manage your own window focus events that trigger React Query to revalidate. To do this, React Query provides a setFocusHandler function that supplies you the callback that should be fired when the window is focused and allows you to set up your own events. When calling setFocusHandler, the previously set handler is removed (which in most cases will be the default handler) and your new handler is used instead. For example, this is the default handler:

setFocusHandler(handleFocus => {
  // Listen to visibillitychange and focus
  if (typeof window !== 'undefined' && window.addEventListener) {
    window.addEventListener('visibilitychange', handleFocus, false)
    window.addEventListener('focus', handleFocus, false)

  return () => {
    // Be sure to unsubscribe if a new handler is set
    window.removeEventListener('visibilitychange', handleFocus)
    window.removeEventListener('focus', handleFocus)

Ignoring Iframe Focus Events

A great use-case for replacing the focus handler is that of iframe events. Iframes present problems with detecting window focus by both double-firing events and also firing false-positive events when focusing or using iframes within your app. If you experience this, you should use an event handler that ignores these events as much as possible. I recommend this one! It can be set up in the following way:

import { setFocusHandler } from 'react-query'
import onWindowFocus from './onWindowFocus' // The gist above

setFocusHandler(onWindowFocus) // Boom!

Custom Query Key Serializers (Super-duper Advanced)

WARNING: This is a very advanced feature. There be dragons here. Do not change the Query Key Serializer unless you know what you are doing and are fine with encountering edge cases in React Query's API

Show Me The Dragons! If you absolutely despise the default query key implementation, then please file an issue in this repo first. If you still believe you need something different, then you can choose to replace the default query key serializer with your own by using the `ReactQueryConfigProvider` hook's `queryKeySerializerFn` option: ```js const queryConfig = { queryKeySerializerFn: queryKey => { // Your custom logic here... // Make sure object keys are sorted and all values are // serializable const queryFnArgs = getQueryArgs(queryKey) // Hash the query key args to get a string const queryHash = hash(queryFnArgs) // Return both the queryHash and normalizedQueryHash as a tuple return [queryHash, queryFnArgs] }, } function App() { return ( ... ) } ``` - `userQueryKey: any` - This is the queryKey passed in `useQuery` and all other public methods and utilities exported by React Query. - It may be a string or an array of serializable values - If a string is passed, it must be wrapped in an array when returned as the `queryFnArgs` - `queryHash: string` - This must be a unique `string` representing the entire query key. - It must be stable and deterministic and should not change if things like the order of variables are changed or shuffled. - `queryFnArgs: Array` - This array will be spread into the query function arguments and should be the same format as the queryKey but be deterministically stable and should not change structure if the variables of the query stay the same, but change order within array position. > An additional `stableStringify` utility is also exported to help with stringifying objects to have sorted keys. ### URL Query Key Serializer Example The example below shows how to build your own serializer for use with URLs and use it with React Query: ```js import { ReactQueryConfigProvider, stableStringify } from 'react-query' function urlQueryKeySerializer(queryKey) { // Deconstruct the url let [url, params = ''] = queryKey.split('?') // Remove trailing slashes from the url to make an ID url = url.replace(/\/{1,}$/, '') // Build the searchQuery object params.split('&').filter(Boolean) // If there are search params, return a different key if (Object.keys(params).length) { let searchQuery = {} params.forEach(param => { const [key, value] = param.split('=') searchQuery[key] = value }) // Use stableStringify to turn searchQuery into a stable string const searchQueryHash = stableStringify(searchQuery) // Get the stable json object for the normalized key searchQuery = JSON.parse(searchQueryHash) return [`${url}_${searchQueryHash}`, [url, searchQuery]] } return [url, [url]] } const queryConfig = { queryKeySerializerFn: urlQueryKeySerializer, } function App() { return ( ... ) } // Heck, you can even make your own custom useQueryHook! function useUrlQuery(url, options) { return useQuery(url, (url, params) => axios .get(url, { params, }) .then(res => ) } // Use it in your app! function Todos() { const todosQuery = useUrlQuery(`/todos`) } function FilteredTodos({ status = 'pending' }) { const todosQuery = useUrlQuery(`/todos?status=pending`) } function Todo({ id }) { const todoQuery = useUrlQuery(`/todos/${id}`) } refetchQuery('/todos') refetchQuery('/todos?status=pending') refetchQuery('/todos/5') ``` ### Function Query Key Serializer Example The example below shows how to you build your own functional serializer and use it with React Query: ```js import { ReactQueryConfigProvider, stableStringify } from 'react-query' // A map to keep track of our function pointers const functionSerializerMap = new Map() function functionQueryKeySerializer(queryKey) { if (!queryKey) { return [] } let queryFn = queryKey let variables if (Array.isArray(queryKey)) { queryFn = queryKey[0] variables = queryKey[1] } // Get or create an ID for the function pointer const queryGroupId = functionSerializerMap.get(queryFn) || (() => { const id = functionSerializerMap.set(queryFn, id) return id })() const variablesIsObject = isObject(variables) const variablesHash = variablesIsObject ? stableStringify(variables) : '' const queryHash = `${queryGroupId}_${variablesHash}` return [queryHash, queryGroupId, variablesHash, variables] } const queryConfig = { queryKeySerializerFn: functionQueryKeySerializer, } function App() { return ( ... ) } // Heck, you can even make your own custom useQueryHook! function useFunctionQuery(functionTuple, options) { const [queryFn, variables] = Array.isArray(functionTuple) ? functionTuple : [functionTuple] return useQuery(functionTuple, queryFn, options) } // Use it in your app! function Todos() { const todosQuery = useFunctionQuery(getTodos) } function FilteredTodos({ status = 'pending' }) { const todosQuery = useFunctionQuery([getTodos, { status }]) } function Todo({ id }) { const todoQuery = useFunctionQuery([getTodo, { id }]) } refetchQuery(getTodos) refetchQuery([getTodos, { type: 'pending' }]) refetchQuery([getTodo, { id: 5 }]) ```

React Query Devtools

React query has dedicated devtools! Visit the React Query Devtools Github Repo for information on how to install and use them!

To see a demo, check out the Sandbox example!

React Query Header



const {
} = useQuery(queryKey, queryFn, {

// or using the object syntax

const queryInfo = useQuery({




const {
  data = undefined,
} = usePaginatedQuery(queryKey, queryFn, options)


The options for usePaginatedQuery are identical to the useQuery hook


The returned properties for usePaginatedQuery are identical to the useQuery hook, with the addition of the following:


const queryFn = (...queryKey, fetchMoreVariable) // => Promise

const {
} = useInfiniteQuery(queryKey, queryFn, {
  getFetchMore: (lastPage, allPages) => fetchMoreVariable


The options for usePaginatedQuery are identical to the useQuery hook with the addition of the following:


The returned properties for usePaginatedQuery are identical to the useQuery hook, with the addition of the following:


const [
  { status, isIdle, isLoading, isSuccess, isError, data, error, reset },
] = useMutation(mutationFn, {

const promise = mutate(variables, {




The queryCache instance is the backbone of React Query that manages all of the state, caching, lifecycle and magic of every query. It supports relatively unrestricted, but safe, access to manipulate query's as you need. Its available properties and methods are:


prefetchQuery is an asynchronous function that can be used to fetch and cache a query response before it is needed or rendered with useQuery and friends.

The difference between using prefetchQuery and setQueryData is that prefetchQuery is async and will ensure that duplicate requests for this query are not created with useQuery instances for the same query are rendered while the data is fetching.

const data = await queryCache.prefetchQuery(queryKey, queryFn)

For convenience in syntax, you can also pass optional query variables to prefetchQuery just like you can useQuery:

const data = await queryCache.prefetchQuery(queryKey, queryFn, config)

To pass options like force or throwOnError, use the fourth options object:

const data = await queryCache.prefetchQuery(queryKey, queryFn, config, {
  force: true,
  throwOnError: true,


The options for prefetchQuery are exactly the same as those of useQuery with the exception of the last options object:



getQueryData is a synchronous function that can be used to get an existing query's cached data. If the query does not exist, undefined will be returned.

import { queryCache } from 'react-query'

const data = queryCache.getQueryData(queryKey)




setQueryData is a synchronous function that can be used to immediately update a query's cached data. If the query does not exist, it will be created and immediately be marked as stale. If the query is not utilized by a query hook in the default cacheTime of 5 minutes, the query will be garbage collected.

The difference between using setQueryData and prefetchQuery is that setQueryData is sync and assumes that you already synchronously have the data available. If you need to fetch the data asynchronously, it's suggested that you either refetch the query key or use prefetchQuery to handle the asynchronous fetch.

import { queryCache } from 'react-query'

queryCache.setQueryData(queryKey, updater, config)


Using an updater value

setQueryData(queryKey, newData)

Using an updater function

For convenience in syntax, you can also pass an updater function which receives the current data value and returns the new one:

setQueryData(queryKey, oldData => newData)


The invalidateQueries method can be used to invalidate and refetch single or multiple queries in the cache based on their query keys or any other functionally accessible property/state of the query. By default, all matching queries are immediately marked as stale and active queries are refetched in the background. If you don't want active queries to refetch, and simply be marked as stale, you can use the refetchActive: false option.

import { queryCache } from 'react-query'

const queries = queryCache.invalidateQueries(inclusiveQueryKeyOrPredicateFn, {



This function returns a promise that will resolve when all of the queries are done being refetched. By default, it will not throw an error if any of those queries refetches fail, but this can be configured by setting the throwOnError option to true


The cancelQueries method can be used to cancel outgoing queries based on their query keys or any other functionally accessible property/state of the query.

This is most useful when performing optimistic updates since you will likely need to cancel any outgoing query refetches so they don't clobber your optimistic update when they resolve.

import { queryCache } from 'react-query'

const queries = queryCache.cancelQueries(queryKeyOrPredicateFn, {



This function does not return anything


The removeQueries method can be used to remove queries from the cache based on their query keys or any other functionally accessible property/state of the query.

import { queryCache } from 'react-query'

const queries = queryCache.removeQueries(queryKeyOrPredicateFn, {



This function does not return anything


getQuery is a slightly more advanced synchronous function that can be used to get an existing query object from the cache. This object not only contains all the state for the query, but all of the instances, and underlying guts of the query as well. If the query does not exist, undefined will be returned.

Note: This is not typically needed for most applications, but can come in handy when needing more information about a query in rare scenarios (eg. Looking at the query.state.updatedAt timestamp to decide whether a query is fresh enough to be used as an initial value)

import { queryCache } from 'react-query'

const query = queryCache.getQuery(queryKey)




getQueries is even more advanced synchronous function that can be used to get existing query objects from the cache that partially match query key. If queries do not exist, empty array will be returned.

Note: This is not typically needed for most applications, but can come in handy when needing more information about a query in rare scenarios

import { queryCache } from 'react-query'

const queries = queryCache.getQueries(queryKey)




This isFetching property is an integer representing how many queries, if any, in the cache are currently fetching (including background-fetching, loading new pages, or loading more infinite query results)

import { queryCache } from 'react-query'

if (queryCache.isFetching) {
  console.log('At least one query is fetching!')

React Query also exports a handy useIsFetching hook that will let you subscribe to this state in your components without creating a manual subscription to the query cache.


The subscribe method can be used to subscribe to the query cache as a whole and be informed of safe/known updates to the cache like query states changing or queries being updated, added or removed

import { queryCache } from 'react-query'

const callback = cache => {}

const unsubscribe = queryCache.subscribe(callback)




The clear method can be used to clear the queryCache entirely and start fresh.

import { queryCache } from 'react-query'




The useQueryCache hook returns the current queryCache instance.

import { useQueryCache } from 'react-query'

const queryCache = useQueryCache()

If you are using the ReactQueryCacheProvider to set a custom cache, you cannot simply import { queryCache } any more. This hook will ensure you're getting the correct instance.


useIsFetching is an optional hook that returns the number of the queries that your application is loading or fetching in the background (useful for app-wide loading indicators).

import { useIsFetching } from 'react-query'

const isFetching = useIsFetching()



ReactQueryConfigProvider is an optional provider component and can be used to define defaults for all instances of useQuery within it's sub-tree:

import { ReactQueryConfigProvider } from 'react-query'

const queryConfig = {
  shared: {
    suspense: false,
    queryKeySerializerFn: defaultQueryKeySerializerFn,
  queries: {
    enabled: true,
    retry: 3,
    retryDelay: attemptIndex => Math.min(1000 * 2 ** attemptIndex, 30000),
    staleTime: 0,
    cacheTime: 5 * 60 * 1000,
    refetchOnWindowFocus: true,
    refetchInterval: false,
    queryFnParamsFilter: identity,
    refetchOnMount: true,
    isDataEqual: deepEqual,
    onError: noop,
    onSuccess: noop,
    onSettled: noop,
    useErrorBoundary: false, // falls back to suspense
  mutations: {
    throwOnError: false,
    onMutate: noop,
    onError: noop,
    onSuccess: noop,
    onSettled: noop,
    useErrorBoundary: false, // falls back to suspense

function App() {
  return (
    <ReactQueryConfigProvider config={queryConfig}>



ReactQueryCacheProvider is an optional provider component for explicitly setting the query cache used by React Query. This is useful for creating component-level caches that are not completely global, as well as making truly isolated unit tests.

import { ReactQueryCacheProvider, makeQueryCache } from 'react-query'

const queryCache = makeQueryCache()

function App() {
  return (
    <ReactQueryCacheProvider queryCache={queryCache}>



setConsole is an optional utility function that allows you to replace the console interface used to log errors. By default, the window.console object is used. If no global console object is found in the environment, nothing will be logged.

import { setConsole } from 'react-query'
import { printLog, printWarn, printError } from 'custom-logger'

  log: printLog,
  warn: printWarn,
  error: printError,


Contributors ✨

Thanks goes to these wonderful people (emoji key):

Tanner Linsley

? ? ? ? ?

Andrew Cherniavskii

? ?

Thibaut Tiberghien


Rohit Garg




This project follows the all-contributors specification. Contributions of any kind welcome!