npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

chronagraph

v0.0.5

Published

A lightweight, TypeScript-based framework for building graph-based workflows and AI agents

Downloads

5

Readme

ChronaGraph

The Simple, Intuitive Graph Framework for AI & Workflow Orchestration (LangGraph alternative)

Build AI Agents & Workflows Without the Complexity

ChronaGraph is a lightweight, TypeScript-based framework for building graph-based workflows and AI agents. Inspired by LangGraph, but with a focus on simplicity, speed, and ease of use.

🚀 Why ChronaGraph?

Type-Safe API – Built with TypeScript for robust, error-free workflows
State Management – Built-in memory and state handling across nodes
Checkpointing – Save and resume workflow states with FileCheckpointer
Event System – Rich event callbacks for monitoring workflow execution
Conditional Routing – Dynamic edge conditions for complex flows
Error Handling – Robust error management and workflow status tracking

⚡ Installation

Install ChronaGraph via npm:

npm install chronagraph

🔧 Quick Start

Here's a practical example of building an activity recommendation system using ChronaGraph:

import { StateGraph } from "chronagraph";
import { FileCheckpointer } from "chronagraph/checkpointers";
import { GraphMemory, NodeImplementation } from "chronagraph/types";
import fs from "fs/promises";
import path from "path";

export const ACTIVITIES = [
  { type: "outdoor", budget: "low", name: "Walking" },
  { type: "outdoor", budget: "medium", name: "Climbing" },
  { type: "outdoor", budget: "high", name: "Skiing" },
  { type: "indoor", budget: "low", name: "Gym" },
  { type: "indoor", budget: "medium", name: "Yoga" },
  { type: "indoor", budget: "high", name: "Pilates" },
];

// Define activity types
interface Activity {
  type: string;
  budget: string;
  name: string;
}

// Define node implementations
export class TypeNode implements NodeImplementation {
  async run(memory: GraphMemory) {
    // Filter activities by type (indoor/outdoor)
    return {
      activitiesToDo: ACTIVITIES.filter(
        (activity) => activity.type === memory.type
      ),
    };
  }
}

export class BudgetNode implements NodeImplementation {
  async run(memory: GraphMemory) {
    // Filter activities by budget
    return {
      activitiesToDo: memory.activitiesToDo.filter(
        (activity: any) => activity.budget === memory.budget
      ),
    };
  }
}

const id = "activity-flow";

// Replace __dirname based path construction with import.meta.url
const checkpointDir = path.dirname(new URL(import.meta.url).pathname);
await fs.mkdir(checkpointDir, { recursive: true }); // Create directory if it doesn't exist
const fileCheckpointer = new FileCheckpointer(checkpointDir);

// Initialize workflow with checkpointing
const workflow = new StateGraph("activity-recommender", {
  type: "indoor",
  budget: "medium",
  activitiesToDo: [],
})
  .setCheckpointer(fileCheckpointer)
  .addNode("type", new TypeNode())
  .addNode("budget", new BudgetNode())
  .addEdge("START", "type")
  .addEdge("type", "budget")
  .addEdge("budget", "END");

await workflow.loadFromCheckpoint(id, fileCheckpointer);

// Add event listener for monitoring
workflow.on((state) => {
  const { event, node, output } = state;
  console.log(`Event: ${event}`, { node, output });
});

// Run the workflow
const result = await workflow.run();
console.log("Result:", result);

📚 Core Concepts

Node Implementation

Nodes are the building blocks of your workflow. Each node should:

  • Implement the NodeImplementation interface
  • Return an object containing the data it produces
  • Have access to the complete workflow memory via GraphMemory
class ExampleNode implements NodeImplementation {
  async run(memory: GraphMemory) {
    // Access any previous data from memory
    const previousData = memory.someKey;

    // Return new data to be stored in memory
    return {
      newData: "This will be stored in memory",
      computedValue: 42,
    };
  }
}

Workflow Memory

The GraphMemory object is:

  • A complete, up-to-date state of your workflow
  • Automatically updated with each node's return data
  • Accessible in every node's run method
  • Strongly typed when using TypeScript

Graph Structure

Every workflow has:

  • A mandatory START edge pointing to your first node
  • A mandatory END edge from your final node
  • Custom edges connecting your nodes in between
const workflow = new StateGraph("my-workflow", initialMemory)
  .addNode("first", new FirstNode())
  .addNode("second", new SecondNode())
  .addEdge("START", "first") // Required start edge
  .addEdge("first", "second") // Custom edge
  .addEdge("second", "END"); // Required end edge

Event System

Monitor your workflow using the event system:

workflow.on((state) => {
  const { event, node, output, error } = state;
  console.log(`Event: ${event}`, { node, output, error });
});

Events include:

  • Node execution start/end
  • Edge transitions
  • Error occurrences
  • Workflow completion

Error Handling & Workflow Status

The workflow tracks status at both node and graph levels:

  • If a node throws an uncaught error, the workflow ends with WorkflowStatus.Failed
  • Each node's status is tracked independently
  • The overall workflow status reflects the current state of execution
const result = await workflow.run();
console.log(result.status); // WorkflowStatus.Completed or WorkflowStatus.Failed
console.log(result.nodeStatuses); // Status of each node

Checkpointing

Checkpointing is optional but powerful:

  • Allows saving and resuming workflow state
  • Create custom checkpointers by extending AbstractCheckpointer
  • Built-in FileCheckpointer for file-based storage
// Custom checkpointer example
class MyCheckpointer extends AbstractCheckpointer {
  async save(id: string, data: any): Promise<void> {
    // Implement your storage logic
  }

  async load(id: string): Promise<any> {
    // Implement your loading logic
  }
}

// Using a checkpointer
const workflow = new StateGraph("my-workflow", initialMemory).setCheckpointer(
  new MyCheckpointer()
);
// ... rest of workflow setup

🛠 Key Features

State Management

  • Persistent memory across workflow steps
  • Type-safe state handling with TypeScript
  • Automatic state propagation between nodes

Checkpointing

  • Save workflow progress with FileCheckpointer
  • Resume workflows from saved states
  • Perfect for long-running or interruptible processes

Event System

  • Monitor node execution with detailed events
  • Track edge transitions and conditions
  • Comprehensive error reporting

Error Handling

  • Graceful error management
  • Workflow status tracking
  • Detailed error states and recovery options

📌 Perfect For

  • AI/LLM Workflow Orchestration
  • Data Processing Pipelines
  • Decision Trees
  • Multi-step Business Processes
  • Stateful Application Workflows

🔍 Examples

Check out the src/examples directory for usage examples.

🗺️ Roadmap

ChronaGraph is actively being developed. Here are some of the planned improvements and features:

Type System Enhancements

  • Stricter type checking for node inputs and outputs
  • Runtime type validation for memory states
  • Enhanced TypeScript generics support for better IDE integration
  • Type-safe edge condition definitions

Workflow Control

  • Pause and resume functionality for long-running workflows
  • Step-by-step workflow execution mode

State Management

  • Additional checkpointing providers (Redis, MongoDB, etc.)

Developer Experience

  • Enhanced debugging tools and visualizations
  • Better error messages and debugging hints
  • More comprehensive documentation and examples

🤝 Contributing

Contributions are welcome! Feel free to:

  • Open issues for bugs or feature requests
  • Submit pull requests
  • Share your use cases and examples

📬 Stay Connected

  • Star and watch this repository for updates
  • Open issues for feature requests or bug reports
  • Share your ChronaGraph projects with the community
  • Follow @strange_quirks on X (Twitter) for updates and support

📄 License

MIT License - Feel free to use in your own projects!