Quick Start
This guide walks you through installing Critical Path and setting up an end-to-end task management workflow with SQLite storage and Next.js / SvelteKit.
1. Installation
Install the core engine and client SDK:
# Using pnpmpnpm add @critical-path/core @critical-path/client
# Using npmnpm install @critical-path/core @critical-path/client
# Using yarnyarn add @critical-path/core @critical-path/clientDepending on your UI stack, install the companion framework package:
# For React / Next.jspnpm add @critical-path/react @critical-path/server
# For Svelte / SvelteKitpnpm add @critical-path/svelte @critical-path/server2. Initialize the Backend Route Handler
Critical Path uses the standard Web Fetch API (Request → Response), making it universally compatible with modern meta-frameworks.
Next.js App Router
Create a catch-all route at app/api/critical-path/[...path]/route.ts:
import { createNextHandler } from '@critical-path/server';import { SQLiteStore } from '@critical-path/core';
// Initialize the storage adapter (file or :memory:)const store = new SQLiteStore({ filename: 'critical-path.db' });
// Create the universal HTTP handlerconst handler = createNextHandler({ store });
export { handler as GET, handler as POST, handler as PUT, handler as PATCH, handler as DELETE, handler as OPTIONS,};SvelteKit
Create a catch-all server endpoint at src/routes/api/critical-path/[...path]/+server.ts:
import { createSvelteKitHandler } from '@critical-path/server';import { SQLiteStore } from '@critical-path/core';
const store = new SQLiteStore({ filename: 'critical-path.db' });const handler = createSvelteKitHandler({ store });
export const GET = handler;export const POST = handler;export const PUT = handler;export const PATCH = handler;export const DELETE = handler;export const OPTIONS = handler;3. Render Frontend State
React Component
Wrap your app or dashboard view with CriticalPathProvider and consume tasks:
import React from 'react';import { CriticalPathProvider, useTasks, useProjects } from '@critical-path/react';
function TaskList({ projectId }: { projectId: string }) { const { tasks, loading, error, createTask, updateTaskStatus } = useTasks({ projectId });
if (loading) return <div>Loading tasks...</div>; if (error) return <div>Error: {error.message}</div>;
return ( <div className="space-y-4"> <button onClick={() => createTask({ title: 'New Feature Task', priority: 'high' })} className="px-4 py-2 bg-blue-600 text-white rounded" > + Add Task </button>
<ul className="divide-y divide-gray-200"> {tasks.map((task) => ( <li key={task.id} className="py-2 flex justify-between items-center"> <span className={task.status === 'done' ? 'line-through text-gray-400' : ''}> {task.title} </span> <button onClick={() => updateTaskStatus(task.id, task.status === 'done' ? 'todo' : 'done')} className="text-xs px-2 py-1 border rounded" > Toggle </button> </li> ))} </ul> </div> );}
export default function App() { return ( <CriticalPathProvider baseUrl="/api/critical-path"> <main className="p-8 max-w-2xl mx-auto"> <h1 className="text-2xl font-bold mb-4">Project Tasks</h1> <TaskList projectId="project-1" /> </main> </CriticalPathProvider> );}4. Compute the Critical Path Programmatically
You can also use the engine directly without HTTP handlers:
import { CriticalPathEngine, InMemoryStore } from '@critical-path/core';
const engine = new CriticalPathEngine({ store: new InMemoryStore(),});
// Create projectconst project = await engine.createProject({ name: 'Website Redesign' });
// Add tasks with dependenciesconst t1 = await engine.createTask({ projectId: project.id, title: 'Wireframes', estimatedHours: 8, status: 'todo', priority: 'high',});
const t2 = await engine.createTask({ projectId: project.id, title: 'Backend API', estimatedHours: 16, status: 'todo', priority: 'high',});
// Link t2 -> depends on t1await engine.addDependency({ projectId: project.id, sourceTaskId: t1.id, targetTaskId: t2.id, type: 'finish_to_start',});
// Compute the critical pathconst analysis = await engine.calculateCriticalPath(project.id);console.log('Total Duration:', analysis.totalDurationHours);console.log('Critical Tasks:', analysis.criticalTaskIds);Congratulations! You are now running Critical Path in your application. Check out the Data Model Guide to learn about the underlying schemas.