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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@falkordb/text-to-cypher

v0.2.0

Published

Node.js bindings for FalkorDB text-to-cypher library - Convert natural language to Cypher queries

Readme

@falkordb/text-to-cypher

Node.js bindings for the FalkorDB text-to-cypher library - Convert natural language to Cypher queries using AI.

npm version License: MIT

Features

  • 🤖 AI-Powered: Convert natural language questions to Cypher queries using GPT-4, Claude, Gemini, and other AI models
  • 🔍 Schema Discovery: Automatically discovers and analyzes graph database schemas
  • Query Validation: Built-in validation to catch syntax errors before execution
  • 🚀 High Performance: Native Rust implementation with Node.js bindings via NAPI-RS
  • 🌍 Cross-Platform: Pre-built binaries for Linux, macOS, and Windows
  • 📦 Zero Dependencies: No runtime dependencies required

Installation

npm install @falkordb/text-to-cypher

📚 New to this library? Check out the Quick Start Guide for a 5-minute introduction!

Quick Start

const { TextToCypher } = require('@falkordb/text-to-cypher');

// Create a client
const client = new TextToCypher({
  model: 'gpt-4o-mini',
  apiKey: process.env.OPENAI_API_KEY,
  falkordbConnection: 'falkor://localhost:6379'
});

// Convert text to Cypher and execute
async function main() {
  const response = await client.textToCypher(
    'movies',
    'Find all actors who appeared in movies released after 2020'
  );

  console.log('Generated Query:', response.cypherQuery);
  console.log('Result:', response.cypherResult);
  console.log('Answer:', response.answer);
}

main().catch(console.error);

API Reference

new TextToCypher(options)

Creates a new text-to-cypher client.

Parameters:

  • options.model (string): AI model to use (e.g., 'gpt-4o-mini', 'openai:local-model', 'anthropic:claude-3', 'gemini:gemini-2.0-flash-exp')
  • options.apiKey (string): API key for the AI service
  • options.falkordbConnection (string): FalkorDB connection string (e.g., 'falkor://localhost:6379')
  • options.llmEndpoint (string, optional): Custom LLM provider endpoint/base URL for OpenAI-compatible local providers such as LM Studio (e.g., 'http://localhost:1234/v1')
  • options.discoverUdfs (boolean, optional): When true, discover the connected instance's user-defined functions (UDFs) via GRAPH.UDF LIST and surface their library.function call targets to the model. Off by default. Client-level — applies to textToCypher, textToCypherWithMessages, and cypherOnly. Ignored when udfs is provided.
  • options.udfs (UdfLibraryInput[], optional): A caller-supplied UDF catalog to surface to the model. Takes precedence over discoverUdfs — use it when you already have the UDF list (e.g. from GRAPH.UDF LIST) to avoid an extra discovery round-trip.

Example:

const client = new TextToCypher({
  model: 'gpt-4o-mini',
  apiKey: 'sk-...',
  falkordbConnection: 'falkor://localhost:6379'
});

For LM Studio or another OpenAI-compatible local server, pass the local endpoint:

const client = new TextToCypher({
  model: 'openai::google/gemma-4-e4b',
  apiKey: 'lm-studio',
  falkordbConnection: 'falkor://localhost:6379',
  llmEndpoint: 'http://localhost:1234/v1'
});

To let generated Cypher call your instance's UDFs, either discover them automatically or pass a catalog you already have:

// Auto-discover (one GRAPH.UDF LIST during generation)
const client = new TextToCypher({
  model: 'gpt-4o-mini',
  apiKey: 'sk-...',
  falkordbConnection: 'falkor://localhost:6379',
  discoverUdfs: true
});

// Or supply a catalog you already fetched (no extra round-trip)
const client = new TextToCypher({
  model: 'gpt-4o-mini',
  apiKey: 'sk-...',
  falkordbConnection: 'falkor://localhost:6379',
  udfs: [{ name: 'geo', functions: [{ name: 'distance' }, { name: 'within' }] }]
});

textToCypher(graphName, question)

Converts natural language to Cypher, executes the query, and generates a natural language answer.

Parameters:

  • graphName (string): Name of the graph to query
  • question (string): Natural language question

Returns: Promise<TextToCypherResponse>

Example:

const response = await client.textToCypher('movies', 'Who directed The Matrix?');
console.log(response.answer); // "The Matrix was directed by..."

textToCypherWithMessages(graphName, messages)

Same as textToCypher but accepts multiple messages for conversation context.

Parameters:

  • graphName (string): Name of the graph to query
  • messages (Array): Array of conversation messages

Example:

const response = await client.textToCypherWithMessages('movies', [
  { role: 'user', content: 'Show me actors' },
  { role: 'assistant', content: 'Here are some actors...' },
  { role: 'user', content: 'Filter those who acted after 2020' }
]);

cypherOnly(graphName, question)

Generates a Cypher query without executing it.

Parameters:

  • graphName (string): Name of the graph
  • question (string): Natural language question

Returns: Promise<TextToCypherResponse> (with only schema and cypherQuery populated)

Example:

const response = await client.cypherOnly('movies', 'Find all actors');
console.log('Generated query:', response.cypherQuery);
// Use the query however you want

discoverSchema(graphName)

Discovers and returns the schema of a graph as JSON.

Parameters:

  • graphName (string): Name of the graph

Returns: Promise<string> (JSON string)

Example:

const schema = await client.discoverSchema('movies');
const schemaObj = JSON.parse(schema);
console.log('Nodes:', schemaObj.nodes);
console.log('Relationships:', schemaObj.relationships);

Model Discovery

listModels()

Lists all available AI models across all supported providers.

Note: This method queries all provider APIs (OpenAI, Anthropic, Gemini, Ollama) and aggregates the results. Each provider's live results are merged with a small curated static catalog, so providers with a curated list still return their well-known models even when no matching API key is configured. Providers without a curated list (e.g. Ollama) only appear when reachable. Models are returned with provider prefixes (except OpenAI).

Returns: Promise<string[]> - Array of model names with provider prefixes where applicable

Example:

const models = await client.listModels();
console.log('All available models:', models);
// Output: [
//   'gpt-4o-mini', 'gpt-4o', 'gpt-4-turbo',  // OpenAI (no prefix)
//   'anthropic::claude-sonnet-4-5', 'anthropic::claude-opus-4-5',  // Anthropic
//   'gemini::gemini-2.5-pro', 'gemini::gemini-3-pro-preview',  // Gemini
//   'ollama::llama3', 'ollama::mistral'  // Ollama (if running)
// ]

Non-OpenAI models are namespaced with a provider::model (double-colon) prefix in the returned list. When passing a model to the constructor you can use either that form or the shorter provider:model (single-colon) form — both are accepted (e.g. 'anthropic::claude-sonnet-4-5' and 'anthropic:claude-sonnet-4-5' are equivalent).

listModelsByProvider(provider)

Lists available AI models from a specific provider by querying the actual provider APIs.

Note: This method merges each provider's live model list with a small curated static catalog. Providers with a curated list (OpenAI, Anthropic, Gemini) still return their well-known models even when no matching API key is configured; an API key adds any additional models the provider reports live. Providers without a curated list (e.g. Ollama) are only returned when reachable.

Parameters:

  • provider (string): Provider name - 'openai', 'anthropic', 'gemini', or 'ollama' (case-insensitive)

Returns: Promise<string[]> - Array of model names (without provider prefixes)

Example:

// List OpenAI models
const openaiModels = await client.listModelsByProvider('openai');
console.log('OpenAI models:', openaiModels);
// Output: ['gpt-4o-mini', 'gpt-4o', 'gpt-4-turbo', ...]

// List Anthropic models
const anthropicModels = await client.listModelsByProvider('anthropic');
console.log('Anthropic models:', anthropicModels);
// Output: ['claude-sonnet-4-5', 'claude-opus-4-5', 'claude-haiku-4-5']

// List Gemini models
const geminiModels = await client.listModelsByProvider('gemini');
console.log('Gemini models:', geminiModels);
// Output: ['gemini-2.5-pro', 'gemini-3-pro-preview', ...]

// List Ollama models (requires Ollama running locally)
const ollamaModels = await client.listModelsByProvider('ollama');
console.log('Ollama models:', ollamaModels);

Supported Providers

  • openai - OpenAI models (GPT-4, GPT-3.5, etc.)
    • Models can be used directly: 'gpt-4o-mini'
  • anthropic - Anthropic models (Claude variants)
    • Models require prefix when using: 'anthropic:claude-sonnet-4-5'
  • gemini - Google Gemini models
    • Models require prefix when using: 'gemini:gemini-2.5-pro'
  • ollama - Local Ollama models (if configured)
    • Models require prefix when using: 'ollama:llama3'

See the examples/list-models.js file for a complete working example.

Types

TextToCypherResponse

interface TextToCypherResponse {
  status: string;           // "success" or "error"
  schema?: string;          // JSON schema of the graph
  cypherQuery?: string;     // Generated Cypher query
  cypherResult?: string;    // Query execution result
  answer?: string;          // Natural language answer
  error?: string;           // Error message if status is "error"
  tokenUsage?: TokenUsage;  // Aggregated LLM token usage (omitted when no tokens were spent)
}

interface TokenUsage {
  promptTokens: number;     // Total input (prompt) tokens across all LLM calls
  completionTokens: number; // Total output (completion) tokens across all LLM calls
  totalTokens: number;      // Total tokens across all LLM calls
}

tokenUsage aggregates the prompt, completion, and total tokens reported by the LLM provider across every call made while serving a request (cypher generation, the final answer, self-healing retries, and skill tool-call rounds). It is present on successful responses and omitted when no tokens were consumed. Failed requests reject with an error, so tokenUsage is not surfaced for failures.

See examples/token-usage.js for a complete working example.

Message

interface Message {
  role: string;    // "user", "assistant", or "system"
  content: string; // Message content
}

Supported AI Models

This library uses the genai crate and supports:

  • OpenAI: gpt-4o-mini, gpt-4o, gpt-4-turbo, etc.
  • Anthropic: anthropic:claude-3-5-sonnet-20241022, anthropic:claude-3-opus-20240229
  • Google Gemini: gemini:gemini-2.0-flash-exp, gemini:gemini-1.5-pro

See genai documentation for a complete list.

Examples

Using with FalkorDB Browser

const { TextToCypher } = require('@falkordb/text-to-cypher');

// In your Express.js or other Node.js server
app.post('/api/text-to-cypher', async (req, res) => {
  const { graphName, question } = req.body;

  try {
    const client = new TextToCypher({
      model: 'gpt-4o-mini',
      apiKey: process.env.OPENAI_API_KEY,
      falkordbConnection: process.env.FALKORDB_CONNECTION
    });

    const response = await client.textToCypher(graphName, question);
    res.json(response);
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

TypeScript Usage

import { TextToCypher, ClientOptions, TextToCypherResponse } from '@falkordb/text-to-cypher';

const options: ClientOptions = {
  model: 'gpt-4o-mini',
  apiKey: process.env.OPENAI_API_KEY!,
  falkordbConnection: 'falkor://localhost:6379'
};

const client = new TextToCypher(options);

const response: TextToCypherResponse = await client.textToCypher(
  'movies',
  'Find top 10 highest rated movies'
);

console.log(response.answer);

Error Handling

try {
  const response = await client.textToCypher('movies', 'Find all actors');
  
  if (response.status === 'error') {
    console.error('Error:', response.error);
  } else {
    console.log('Success:', response.answer);
  }
} catch (error) {
  console.error('Exception:', error.message);
}

Tracking Token Usage

Each request aggregates the token counts from every LLM call it makes (cypher generation, self-healing retries, skill tool-call rounds, and final answer generation) into response.tokenUsage:

const response = await client.textToCypher('movies', 'How many actors are there?');

if (response.tokenUsage) {
  console.log('Prompt tokens:', response.tokenUsage.promptTokens);
  console.log('Completion tokens:', response.tokenUsage.completionTokens);
  console.log('Total tokens:', response.tokenUsage.totalTokens);
}

See examples/token-usage.js for a complete, runnable example.

Requirements

  • Node.js >= 20
  • FalkorDB instance running and accessible
  • API key for your chosen AI provider (OpenAI, Anthropic, etc.)

Development

Building from Source

# Install dependencies
npm install

# Build the native module
npm run build

# Run tests
npm test

Prerequisites for Building

  • Rust toolchain (install from rustup.rs)
  • Node.js >= 20
  • C++ compiler (platform-specific)

Platform Support

Pre-built binaries are available for:

  • Linux x64 (glibc and musl)
  • Linux ARM64 (glibc and musl)
  • macOS x64 (Intel)
  • macOS ARM64 (Apple Silicon)
  • Windows x64

Releasing

Versions are derived automatically from Git tags. To publish a new release:

  1. Create a GitHub release with a semver tag (e.g., v1.2.0)
  2. The release workflow builds all platform binaries and publishes to npm
  3. The version in package.json (0.0.0) is a placeholder — the release CI sets the real version from the tag

No manual package.json version edits are needed.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

MIT License - see LICENSE file for details.

Related Projects

Support

Acknowledgments

Built with NAPI-RS - A framework for building compiled Node.js add-ons in Rust.