use-simple-debounce Simple, dependency-free debouncing v.3.0.0 | Looking for v2?
import { useDebounce } from 'use-simple-debounce';
function SearchComponent() {
const debouncedSearch = useDebounce((query: string) => performSearch(query), 300);
const handleSearch = (query: string) => {
// Optional: cleanup is handled by the library
const cancel = debouncedSearch(query);
};
return (
<input
type="text"
onChange={e => handleSearch(e.target.value)}
placeholder="Search..."
/>
);
}import { useDebounce } from 'use-simple-debounce';
function SearchComponent() {
const debouncedSearch = useDebounce((query: string) => performSearch(query), 300);
const handleSearch = (query: string) => {
// Optional: cleanup is handled by the library
const cancel = debouncedSearch(query);
};
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 debouncedSearch = useDebounce((query: string) => performSearch(query), 300);
const handleInputChange = () => {
// Optional: cleanup is handled by the library
const cancel = debouncedSearch(query.value);
};
</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 debouncedSearch = useDebounce((query: string) => performSearch(query), 300);
const handleInputChange = () => {
// Optional: cleanup is handled by the library
const cancel = debouncedSearch(query.value);
};
</script>import { createDebounce } from 'use-simple-debounce/solid';
function SearchComponent() {
const debouncedSearch = createDebounce((query: string) => performSearch(query), 300);
const handleSearch = (query: string) => {
// Optional: cleanup is handled by the library
const cancel = debouncedSearch(query);
};
return (
<input
type="text"
onInput={e => handleSearch(e.target.value)}
placeholder="Search..."
/>
);
}import { createDebounce } from 'use-simple-debounce/solid';
function SearchComponent() {
const debouncedSearch = createDebounce((query: string) => performSearch(query), 300);
const handleSearch = (query: string) => {
// Optional: cleanup is handled by the library
const cancel = debouncedSearch(query);
};
return (
<input
type="text"
onInput={e => handleSearch(e.target.value)}
placeholder="Search..."
/>
);
}<script>
import { createDebounce } from 'use-simple-debounce/svelte';
let query = '';
const debouncedSearch = createDebounce((value) => performSearch(value), 300);
function handleInputChange(event) {
const value = event.target.value;
// Optional: cleanup is handled by the library
const cancel = debouncedSearch(value);
}
</script>
<input bind:value={query} on:input={handleInputChange} placeholder="Search..." /><script>
import { createDebounce } from 'use-simple-debounce/svelte';
let query = '';
const debouncedSearch = createDebounce((value) => performSearch(value), 300);
function handleInputChange(event) {
const value = event.target.value;
// Optional: cleanup is handled by the library
const cancel = debouncedSearch(value);
}
</script>
<input bind:value={query} on:input={handleInputChange} placeholder="Search..." /><script>
import { createDebounce } from 'use-simple-debounce/svelte';
let query = $state('');
const debouncedSearch = createDebounce((value) => performSearch(value), 300);
function handleInputChange(event) {
const value = event.target.value;
// Optional: cleanup is handled by the library
const cancel = debouncedSearch(value);
}
</script>
<input bind:value={query} oninput={handleInputChange} placeholder="Search..." /><script>
import { createDebounce } from 'use-simple-debounce/svelte';
let query = $state('');
const debouncedSearch = createDebounce((value) => performSearch(value), 300);
function handleInputChange(event) {
const value = event.target.value;
// Optional: cleanup is handled by the library
const cancel = debouncedSearch(value);
}
</script>
<input bind:value={query} oninput={handleInputChange} placeholder="Search..." />import { debounce } from 'use-simple-debounce/vanilla';
const debouncedSearch = debounce((query) => performSearch(query), 300);
function handleSearch(query) {
// Cleanup (if needed) should be executed manually - no automatic cleanup
// Example: cancel()
const cancel = debouncedSearch(query);
}
const input = document.querySelector('input');
input.addEventListener('input', e => handleSearch(e.target.value));import { debounce } from 'use-simple-debounce/vanilla';
const debouncedSearch = debounce((query) => performSearch(query), 300);
function handleSearch(query) {
// Cleanup (if needed) should be executed manually - no automatic cleanup
// Example: cancel()
const cancel = debouncedSearch(query);
}
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<F extends (...args: Parameters<F>) => ReturnType<F>>(
func: F,
wait: number = 300
): (...args: Parameters<F>) => () => void {
const timeout = useRef<ReturnType<typeof setTimeout> | null>(null);
useEffect(() => {
return () => {
if (timeout.current) {
clearTimeout(timeout.current);
timeout.current = null;
}
};
}, []);
return (...args: Parameters<F>) => {
if (timeout.current) {
clearTimeout(timeout.current);
}
timeout.current = setTimeout(() => {
func(...args);
}, wait);
return () => {
if (timeout.current) {
clearTimeout(timeout.current);
timeout.current = null;
}
};
};
}import { useRef, useEffect } from 'react';
export function useDebounce<F extends (...args: Parameters<F>) => ReturnType<F>>(
func: F,
wait: number = 300
): (...args: Parameters<F>) => () => void {
const timeout = useRef<ReturnType<typeof setTimeout> | null>(null);
useEffect(() => {
return () => {
if (timeout.current) {
clearTimeout(timeout.current);
timeout.current = null;
}
};
}, []);
return (...args: Parameters<F>) => {
if (timeout.current) {
clearTimeout(timeout.current);
}
timeout.current = setTimeout(() => {
func(...args);
}, wait);
return () => {
if (timeout.current) {
clearTimeout(timeout.current);
timeout.current = null;
}
};
};
}import { ref, onUnmounted } from 'vue';
export function useDebounce<F extends (...args: Parameters<F>) => ReturnType<F>>(
func: F,
wait: number = 300
): (...args: Parameters<F>) => () => void {
const timeout = ref<ReturnType<typeof setTimeout> | null>(null);
onUnmounted(() => {
if (timeout.value) {
clearTimeout(timeout.value);
timeout.value = null;
}
});
return (...args: Parameters<F>) => {
if (timeout.value) {
clearTimeout(timeout.value);
}
timeout.value = setTimeout(() => {
func(...args);
}, wait);
return () => {
if (timeout.value) {
clearTimeout(timeout.value);
timeout.value = null;
}
};
};
}import { ref, onUnmounted } from 'vue';
export function useDebounce<F extends (...args: Parameters<F>) => ReturnType<F>>(
func: F,
wait: number = 300
): (...args: Parameters<F>) => () => void {
const timeout = ref<ReturnType<typeof setTimeout> | null>(null);
onUnmounted(() => {
if (timeout.value) {
clearTimeout(timeout.value);
timeout.value = null;
}
});
return (...args: Parameters<F>) => {
if (timeout.value) {
clearTimeout(timeout.value);
}
timeout.value = setTimeout(() => {
func(...args);
}, wait);
return () => {
if (timeout.value) {
clearTimeout(timeout.value);
timeout.value = null;
}
};
};
}import { onCleanup } from 'solid-js';
export function createDebounce<F extends (...args: Parameters<F>) => ReturnType<F>>(
func: F,
wait: number = 300
): (...args: Parameters<F>) => () => void {
let timeout: ReturnType<typeof setTimeout> | null = null;
onCleanup(() => {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
});
return (...args: Parameters<F>) => {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
func(...args);
}, wait);
return () => {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
};
};
}import { onCleanup } from 'solid-js';
export function createDebounce<F extends (...args: Parameters<F>) => ReturnType<F>>(
func: F,
wait: number = 300
): (...args: Parameters<F>) => () => void {
let timeout: ReturnType<typeof setTimeout> | null = null;
onCleanup(() => {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
});
return (...args: Parameters<F>) => {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
func(...args);
}, wait);
return () => {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
};
};
}import { onDestroy } from 'svelte';
export function createDebounce<F extends (...args: Parameters<F>) => ReturnType<F>>(
func: F,
wait: number = 300
): (...args: Parameters<F>) => () => void {
let timeout: ReturnType<typeof setTimeout> | null = null;
onDestroy(() => {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
});
return (...args: Parameters<F>) => {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
func(...args);
}, wait);
return () => {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
};
};
}import { onDestroy } from 'svelte';
export function createDebounce<F extends (...args: Parameters<F>) => ReturnType<F>>(
func: F,
wait: number = 300
): (...args: Parameters<F>) => () => void {
let timeout: ReturnType<typeof setTimeout> | null = null;
onDestroy(() => {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
});
return (...args: Parameters<F>) => {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
func(...args);
}, wait);
return () => {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
};
};
}export function debounce<F extends (...args: Parameters<F>) => ReturnType<F>>(
func: F,
wait: number
): (...args: Parameters<F>) => () => void {
let timeout: ReturnType<typeof setTimeout> | null = null;
return (...args: Parameters<F>) => {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
func(...args);
}, wait);
return () => {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
};
};
}export function debounce<F extends (...args: Parameters<F>) => ReturnType<F>>(
func: F,
wait: number
): (...args: Parameters<F>) => () => void {
let timeout: ReturnType<typeof setTimeout> | null = null;
return (...args: Parameters<F>) => {
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
func(...args);
}, wait);
return () => {
if (timeout) {
clearTimeout(timeout);
timeout = null;
}
};
};
}