betterspec
Core

Programmatic API

Use @betterspec/core to read specs, list changes, and scaffold projects from TypeScript.

Programmatic API

The @betterspec/core package is the TypeScript library that powers the betterspec CLI. You can use it directly to build your own tools, integrations, and workflows on top of betterspec.

This is the library, not the CLI. For CLI usage, see the CLI Reference.

Installation

bun add @betterspec/core

Key Exports

readConfig

Read the betterspec.json configuration for a project.

import { readConfig } from "@betterspec/core";

const config = await readConfig("/path/to/project");
// {
//   projectName: "my-app",
//   mode: "local",
//   globalRepo: undefined
// }

configExists

Check whether a project has been initialized with betterspec.

import { configExists } from "@betterspec/core";

const exists = await configExists("/path/to/project");
// true | false

listChanges

List all changes in a project, optionally filtered by status.

import { listChanges } from "@betterspec/core";

const changes = await listChanges("/path/to/project");
// [
//   { id: "auth-oauth", status: "in-progress" },
//   { id: "dark-mode", status: "proposed" }
// ]

readChange

Read the full spec contents for a specific change.

import { readChange } from "@betterspec/core";

const change = await readChange("/path/to/project", "auth-oauth");
// {
//   id: "auth-oauth",
//   status: "in-progress",
//   proposal: "# Add OAuth Authentication\n...",
//   requirements: "# Requirements\n...",
//   scenarios: "# Scenarios\n...",
//   design: "# Design\n...",
//   tasks: "# Tasks\n- [x] Install arctic..."
// }

createChange

Scaffold a new change with all spec files.

import { createChange } from "@betterspec/core";

await createChange("/path/to/project", "add-search", {
  title: "Add full-text search",
  description: "Implement search across all content using Typesense",
});

summarizeTasks

Parse tasks.md and return a progress summary.

import { summarizeTasks } from "@betterspec/core";

const summary = await summarizeTasks("/path/to/project", "auth-oauth");
// {
//   total: 8,
//   completed: 5,
//   remaining: 3,
//   percent: 62.5
// }

scaffoldSpecDirs

Create the betterspec/ directory structure for a project. This is what betterspec init calls internally.

import { scaffoldSpecDirs } from "@betterspec/core";

await scaffoldSpecDirs("/path/to/project");
// Creates: betterspec/, betterspec/changes/, betterspec/knowledge/, betterspec/capabilities/

scaffoldSkill

Generate a skill file (e.g., a Claude Code CLAUDE.md or system prompt) for AI agents to understand the project's betterspec setup.

import { scaffoldSkill } from "@betterspec/core";

await scaffoldSkill("/path/to/project");

scaffoldKnowledge

Generate initial knowledge base files from project context.

import { scaffoldKnowledge } from "@betterspec/core";

await scaffoldKnowledge("/path/to/project");
// Creates starter files in betterspec/knowledge/

Usage in Integrations

The @betterspec/core API is the recommended way to build betterspec integrations. Rather than shelling out to the CLI, import the library directly:

import { readConfig, listChanges, readChange, summarizeTasks } from "@betterspec/core";

async function getProjectDashboard(cwd: string) {
  const config = await readConfig(cwd);
  const changes = await listChanges(cwd);

  const dashboard = await Promise.all(
    changes.map(async (change) => {
      const detail = await readChange(cwd, change.id);
      const tasks = await summarizeTasks(cwd, change.id);
      return {
        id: change.id,
        status: change.status,
        progress: `${tasks.completed}/${tasks.total}`,
      };
    })
  );

  return { project: config.projectName, changes: dashboard };
}

See Building Integrations for patterns and best practices.

On this page