use-simple-debounce Simple, dependency-free debouncing
import { useDebounce } from 'use-simple-debounce';
function SearchComponent() {
const debounced = useDebounce();
const handleSearch = (query: string) => {
debounced(() => performSearch(query), 300);
};
return (
<input
type="text"
onChange={e => handleSearch(e.target.value)}
placeholder="Search..."
/>
);
}import { useDebounce } from 'use-simple-debounce';
function SearchComponent() {
const debounced = useDebounce();
const handleSearch = (query: string) => {
debounced(() => performSearch(query), 300);
};
return (
<input
type="text"
onChange={e => handleSearch(e.target.value)}
placeholder="Search..."
/>
);
}<template>
<input v-model="query" @input="handleInputChange" placeholder="Search..." />
</template>
<script setup>
import { ref } from 'vue';
import { useDebounce } from 'use-simple-debounce/vue';
const query = ref('');
const debounced = useDebounce();
const handleInputChange = () => {
debounced(() => performSearch(query.value), 300);
};
</script><template>
<input v-model="query" @input="handleInputChange" placeholder="Search..." />
</template>
<script setup>
import { ref } from 'vue';
import { useDebounce } from 'use-simple-debounce/vue';
const query = ref('');
const debounced = useDebounce();
const handleInputChange = () => {
debounced(() => performSearch(query.value), 300);
};
</script>import { createDebounce } from 'use-simple-debounce/solid';
function SearchComponent() {
const debounced = createDebounce();
const handleSearch = (query: string) => {
debounced(() => performSearch(query), 300);
};
return (
<input
type="text"
onInput={e => handleSearch(e.target.value)}
placeholder="Search..."
/>
);
}import { createDebounce } from 'use-simple-debounce/solid';
function SearchComponent() {
const debounced = createDebounce();
const handleSearch = (query: string) => {
debounced(() => performSearch(query), 300);
};
return (
<input
type="text"
onInput={e => handleSearch(e.target.value)}
placeholder="Search..."
/>
);
}<script>
import { createDebounce } from 'use-simple-debounce/svelte';
let query = '';
const debounced = createDebounce();
function handleInputChange(event) {
const value = event.target.value;
debounced(() => performSearch(value), 300);
}
</script>
<input bind:value={query} on:input={handleInputChange} placeholder="Search..." /><script>
import { createDebounce } from 'use-simple-debounce/svelte';
let query = '';
const debounced = createDebounce();
function handleInputChange(event) {
const value = event.target.value;
debounced(() => performSearch(value), 300);
}
</script>
<input bind:value={query} on:input={handleInputChange} placeholder="Search..." /><script>
import { createDebounce } from 'use-simple-debounce/svelte';
let query = $state('');
const debounced = createDebounce();
function handleInputChange(event) {
const value = event.target.value;
debounced(() => performSearch(value), 300);
}
</script>
<input bind:value={query} oninput={handleInputChange} placeholder="Search..." /><script>
import { createDebounce } from 'use-simple-debounce/svelte';
let query = $state('');
const debounced = createDebounce();
function handleInputChange(event) {
const value = event.target.value;
debounced(() => performSearch(value), 300);
}
</script>
<input bind:value={query} oninput={handleInputChange} placeholder="Search..." />import { useDebounce } from 'use-simple-debounce/vanilla';
const debounced = useDebounce();
function handleSearch(query) {
debounced(() => performSearch(query), 300);
}
const input = document.querySelector('input');
input.addEventListener('input', e => handleSearch(e.target.value));import { useDebounce } from 'use-simple-debounce/vanilla';
const debounced = useDebounce();
function handleSearch(query) {
debounced(() => performSearch(query), 300);
}
const input = document.querySelector('input');
input.addEventListener('input', e => handleSearch(e.target.value));A lightweight debounce utility for React, Solid, Svelte, Vue, and vanilla JavaScript. Zero dependencies, TypeScript support, and async function handling.
Zero dependencies
TypeScript support
Async function support
Inner Workings
Curious about how it works under the hood? Here's the complete source code for each framework implementation.
import { useRef, useEffect } from 'react';
export function useDebounce() {
const timeout = useRef<ReturnType<typeof setTimeout> | null>(null);
useEffect(() => {
return () => {
if (timeout.current) {
clearTimeout(timeout.current);
}
};
}, []);
return (fn: () => void, delay: number = 300) => {
if (timeout.current) {
clearTimeout(timeout.current);
}
timeout.current = setTimeout(() => {
fn();
timeout.current = null;
}, delay);
};
}import { useRef, useEffect } from 'react';
export function useDebounce() {
const timeout = useRef<ReturnType<typeof setTimeout> | null>(null);
useEffect(() => {
return () => {
if (timeout.current) {
clearTimeout(timeout.current);
}
};
}, []);
return (fn: () => void, delay: number = 300) => {
if (timeout.current) {
clearTimeout(timeout.current);
}
timeout.current = setTimeout(() => {
fn();
timeout.current = null;
}, delay);
};
}import { ref, onUnmounted } from 'vue';
export function useDebounce() {
const timeout = ref<ReturnType<typeof setTimeout> | null>(null);
onUnmounted(() => {
if (timeout.value) {
clearTimeout(timeout.value);
}
});
return (fn: () => void, delay: number = 300) => {
if (timeout.value) {
clearTimeout(timeout.value);
}
timeout.value = setTimeout(() => {
fn();
timeout.value = null;
}, delay);
};
}import { ref, onUnmounted } from 'vue';
export function useDebounce() {
const timeout = ref<ReturnType<typeof setTimeout> | null>(null);
onUnmounted(() => {
if (timeout.value) {
clearTimeout(timeout.value);
}
});
return (fn: () => void, delay: number = 300) => {
if (timeout.value) {
clearTimeout(timeout.value);
}
timeout.value = setTimeout(() => {
fn();
timeout.value = null;
}, delay);
};
}import { onCleanup } from 'solid-js';
export function createDebounce() {
let timeout: ReturnType<typeof setTimeout> | null = null;
onCleanup(() => {
if (timeout) {
clearTimeout(timeout);
}
});
return (fn: () => void, delay: number = 300) => {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
fn();
timeout = null;
}, delay);
};
}import { onCleanup } from 'solid-js';
export function createDebounce() {
let timeout: ReturnType<typeof setTimeout> | null = null;
onCleanup(() => {
if (timeout) {
clearTimeout(timeout);
}
});
return (fn: () => void, delay: number = 300) => {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
fn();
timeout = null;
}, delay);
};
}import { onDestroy } from 'svelte';
export function createDebounce() {
let timeout: ReturnType<typeof setTimeout> | null = null;
onDestroy(() => {
if (timeout) {
clearTimeout(timeout);
}
});
return (fn: () => void, delay: number = 300) => {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
fn();
timeout = null;
}, delay);
};
}import { onDestroy } from 'svelte';
export function createDebounce() {
let timeout: ReturnType<typeof setTimeout> | null = null;
onDestroy(() => {
if (timeout) {
clearTimeout(timeout);
}
});
return (fn: () => void, delay: number = 300) => {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
fn();
timeout = null;
}, delay);
};
}export function useDebounce() {
let timeoutId: ReturnType<typeof setTimeout> | undefined;
return (fn: () => void, delay: number = 300): (() => void) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn(), delay);
return () => {
clearTimeout(timeoutId);
};
};
}export function useDebounce() {
let timeoutId: ReturnType<typeof setTimeout> | undefined;
return (fn: () => void, delay: number = 300): (() => void) => {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn(), delay);
return () => {
clearTimeout(timeoutId);
};
};
}