A lightweight and flexible task scheduling library for JavaScript & TypeScript. Provides precise control over interval and one-time task execution with advanced features like task expiration, conditional execution, and comprehensive task management.
- 🚀 Lightweight: Minimal bundle size with zero external dependencies
- ⚡ High Performance: Optimized task scheduling with efficient timer management
- đź”§ Flexible: Support for both interval and one-time tasks
- 🛡️ Type Safe: Full TypeScript support with comprehensive type definitions
- 🎯 Precise Control: Start times, expiration dates, and conditional execution
- đź§ą Memory Safe: Automatic cleanup and task removal
- 📦 Tree Shakeable: ES modules with tree-shaking support
- ⚛️ React Optimized: Custom hooks with automatic state management
- 🔄 Reactive State: Tasks automatically update React state
- đź§ą Auto Cleanup: Automatic cleanup on component unmount
npm install schedi
# or
yarn add schedi
# or
pnpm add schedi// Vanilla JavaScript/TypeScript
import { IntervalTaskRunner, OneTimeTaskRunner } from "schedi/vanilla";
// React
import { useIntervalTaskRunner, useOneTimeTaskRunner } from "schedi/react";// Import everything from the main package
import { IntervalTaskRunner, useIntervalTaskRunner } from "schedi";import { IntervalTaskRunner, OneTimeTaskRunner } from "schedi/vanilla";
const intervalRunner = new IntervalTaskRunner();
const oneTimeRunner = new OneTimeTaskRunner();
// Add interval task
intervalRunner.addTask({
interval: 1000, // 1 second
callback: () => console.log("Interval task executed"),
name: "my-interval-task",
startAt: Date.now(),
});
// Add one-time task
oneTimeRunner.addTask({
callback: () => console.log("One-time task executed"),
name: "my-one-time-task",
startAt: Date.now() + 5000, // 5 seconds from now
});
// Start the interval runner
intervalRunner.start();import { useIntervalTaskRunner, useOneTimeTaskRunner } from "schedi/react";
function MyComponent() {
const intervalRunner = useIntervalTaskRunner();
const oneTimeRunner = useOneTimeTaskRunner();
// Add an interval task
const addIntervalTask = () => {
intervalRunner.addTask({
interval: 1000, // 1 second
callback: () => console.log("Interval task executed"),
name: "my-interval-task",
startAt: Date.now(),
});
};
// Add a one-time task
const addOneTimeTask = () => {
oneTimeRunner.addTask({
callback: () => console.log("One-time task executed"),
name: "my-one-time-task",
startAt: Date.now() + 5000, // 5 seconds from now
});
};
return (
<div>
<button onClick={addIntervalTask}>Add Interval Task</button>
<button onClick={addOneTimeTask}>Add One-Time Task</button>
<p>Active interval tasks: {intervalRunner.tasks.length}</p>
<p>Active one-time tasks: {oneTimeRunner.tasks.length}</p>
</div>
);
}Manages tasks that execute at regular intervals.
const runner = new IntervalTaskRunner(tasks?, config?);| Method | Description | Parameters | Returns |
|---|---|---|---|
addTask(config) |
Add a new interval task | IIntervalTaskCreatePayload |
IIntervalTask |
removeTask(id) |
Remove task by ID | string |
void |
updateTask(id, data) |
Update existing task | string, Partial<IIntervalTaskCreatePayload> |
IIntervalTask | undefined |
getTask(id) |
Get task by ID | string |
IIntervalTask | undefined |
getTasks() |
Get all tasks | - | IIntervalTask[] |
clear() |
Remove all tasks | - | void |
start() |
Start executing tasks | - | () => void (stop function) |
Manages tasks that execute once after a delay.
const runner = new OneTimeTaskRunner(tasks?, config?);| Method | Description | Parameters | Returns |
|---|---|---|---|
addTask(config) |
Add a new one-time task | IOneTimeTaskCreatePayload |
IOneTimeTask |
removeTask(id) |
Remove task by ID | string |
void |
updateTask(id, data) |
Update existing task | string, Partial<IOneTimeTaskCreatePayload> |
IOneTimeTask | undefined |
getTask(id) |
Get task by ID | string |
IOneTimeTask | undefined |
getTasks() |
Get all tasks | - | IOneTimeTask[] |
clear() |
Remove all tasks | - | void |
start() |
Start executing tasks | - | () => void (stop function) |
Manages tasks that execute at regular intervals with React state integration.
const {
tasks, // Array of active tasks (reactive)
addTask, // Add a new interval task
removeTask, // Remove a task by ID
updateTask, // Update an existing task
getTask, // Get a task by ID
clearRunner, // Remove all tasks
startRunner, // Start executing tasks
} = useIntervalTaskRunner(config?);Manages tasks that execute once after a delay with React state integration.
const {
tasks, // Array of active tasks (reactive)
addTask, // Add a new one-time task
removeTask, // Remove a task by ID
updateTask, // Update an existing task
getTask, // Get a task by ID
clearRunner, // Remove all tasks
} = useOneTimeTaskRunner(config?);interface IIntervalTaskCreatePayload<T = unknown> {
interval: number; // Interval in milliseconds
callback: () => T; // Function to execute
name: string; // Task identifier
startAt: number; // Start time (timestamp)
enabled?: boolean; // Whether task is enabled (default: true)
expireAt?: number; // Expiration time (timestamp, default: Infinity)
}interface IOneTimeTaskCreatePayload<T = unknown> {
callback: () => T; // Function to execute
name: string; // Task identifier
startAt: number; // Start time (timestamp)
enabled?: boolean; // Whether task is enabled (default: true)
expireAt?: number; // Expiration time (timestamp, default: Infinity)
onRemove?: (task: IOneTimeTask<T>) => void; // Cleanup callback
}// Task that only runs during business hours
runner.addTask({
interval: 60000, // Every minute
callback: () => console.log("Business hour check"),
name: "business-check",
startAt: Date.now(),
enabled: () => {
const hour = new Date().getHours();
return hour >= 9 && hour <= 17; // 9 AM to 5 PM
},
});// Task that expires after 1 hour
runner.addTask({
interval: 30000, // Every 30 seconds
callback: () => console.log("Temporary task"),
name: "temporary-task",
startAt: Date.now(),
expireAt: Date.now() + 60 * 60 * 1000, // 1 hour from now
});// Schedule a task to start in the future
runner.addTask({
interval: 1000,
callback: () => console.log("Future task"),
name: "future-task",
startAt: Date.now() + 5 * 60 * 1000, // 5 minutes from now
});Full support for async functions as callbacks:
const fetchData = async () => {
try {
const response = await fetch("/api/data");
const data = await response.json();
console.log("Data fetched:", data);
} catch (error) {
console.error("Failed to fetch data:", error);
}
};
runner.addTask({
interval: 5000,
callback: fetchData,
name: "data-fetcher",
startAt: Date.now(),
});function AdvancedScheduler() {
const { tasks, addTask, removeTask, updateTask } = useIntervalTaskRunner();
const [selectedTask, setSelectedTask] = useState<string | null>(null);
const pauseTask = (taskId: string) => {
updateTask(taskId, { enabled: false });
};
const resumeTask = (taskId: string) => {
updateTask(taskId, { enabled: true });
};
return (
<div>
<h3>Task Manager</h3>
{tasks.map((task) => (
<div key={task.id}>
<span>{task.name}</span>
<button onClick={() => pauseTask(task.id)}>Pause</button>
<button onClick={() => resumeTask(task.id)}>Resume</button>
<button onClick={() => removeTask(task.id)}>Remove</button>
</div>
))}
</div>
);
}Full TypeScript support with comprehensive type definitions:
import type {
IIntervalTask,
IOneTimeTask,
IIntervalTaskCreatePayload,
IOneTimeTaskCreatePayload,
IIntervalTaskRunnerConfig,
IOneTimeTaskRunnerConfig,
} from "schedi";
// Type-safe task creation
const task: IIntervalTask<string> = runner.addTask({
interval: 1000,
callback: () => "Hello World",
name: "typed-task",
startAt: Date.now(),
});- Memory Management: Tasks are automatically cleaned up when expired or removed
- Timer Optimization: Uses native
setTimeoutandsetIntervalfor optimal performance - Batch Operations: Multiple task operations are optimized for efficiency
- Tree Shaking: Only import what you need to minimize bundle size
- React Optimizations: Automatic memoization and minimal re-renders
- Modern browsers with ES2015+ support
- React 18+ (for React hooks)
- Node.js 14+ (with appropriate polyfills for
setTimeout/setInterval)
# Install dependencies
pnpm install
# Build the package
pnpm build
# Run tests
pnpm test
# Lint code
pnpm lintMIT License - see LICENSE file for details.
Contributions are welcome! Please read our contributing guidelines and submit pull requests to our repository.
See CHANGELOG.md for a list of changes and version history.