--- title: Programmatic API description: Use Better-T-Stack programmatically in your Node.js applications --- ## Overview The Better-T-Stack CLI can be used programmatically in your Node.js applications, allowing you to create projects, add features, and manage configurations through JavaScript/TypeScript code instead of shell commands. ## Installation Install the package in your Node.js project: ```bash npm install create-better-t-stack # or pnpm add create-better-t-stack # or bun add create-better-t-stack ``` ## Quick Start ### Basic Project Creation ```typescript import { init } from "create-better-t-stack"; async function createProject() { const result = await init("my-app", { yes: true, // Use defaults, no prompts frontend: ["tanstack-router"], backend: "hono", database: "sqlite", orm: "drizzle", auth: "better-auth", packageManager: "bun", install: false, // Don't install deps automatically disableAnalytics: true, // Disable analytics }); if (result.success) { console.log(`✅ Project created at: ${result.projectDirectory}`); console.log(`📝 Reproducible command: ${result.reproducibleCommand}`); console.log(`⏱️ Time taken: ${result.elapsedTimeMs}ms`); } else { console.error(`❌ Failed: ${result.error}`); } } createProject(); ``` ### Directory Conflict Handling ```typescript import { init } from "create-better-t-stack"; const result = await init("existing-folder", { yes: true, directoryConflict: "increment", // Creates "existing-folder-1" renderTitle: false, // Hide ASCII art }); ``` ### Disabling Analytics You can disable analytics: ```typescript import { init } from "create-better-t-stack"; const result = await init("my-private-project", { yes: true, disableAnalytics: true, // No analytics data will be sent frontend: ["tanstack-router"], backend: "hono", }); ``` > **Note:** Analytics help improve Better-T-Stack by providing insights into usage patterns. When disabled, no data is collected or transmitted. ## API Reference ### `init(projectName?, options?)` Creates a new Better-T-Stack project. **Parameters:** - `projectName` (string, optional): Project name or directory path - `options` (CreateInput, optional): Configuration options **Returns:** `Promise` **Example:** ```typescript const result = await init("my-project", { frontend: ["next"], backend: "hono", database: "postgres", orm: "drizzle" }); ``` ### `sponsors()` Display Better-T-Stack sponsors (same as CLI). **Returns:** `Promise` ### `docs()` Open documentation in browser (same as CLI). **Returns:** `Promise` ### `builder()` Open web-based stack builder (same as CLI). **Returns:** `Promise` ## Type Definitions ### `CreateInput` Configuration options for project creation: ```typescript interface CreateInput { projectName?: string; yes?: boolean; // Skip prompts, use defaults yolo?: boolean; // Bypass validations (not recommended) verbose?: boolean; // Show JSON result (CLI only, programmatic always returns result) database?: Database; // "none" | "sqlite" | "postgres" | "mysql" | "mongodb" orm?: ORM; // "none" | "drizzle" | "prisma" | "mongoose" auth?: boolean; // Include authentication frontend?: Frontend[]; // Array of frontend frameworks addons?: Addons[]; // Array of addons examples?: Examples[]; // Array of examples git?: boolean; // Initialize git repo packageManager?: PackageManager; // "npm" | "pnpm" | "bun" install?: boolean; // Install dependencies dbSetup?: DatabaseSetup; // Database hosting setup backend?: Backend; // Backend framework runtime?: Runtime; // Runtime environment api?: API; // API type webDeploy?: WebDeploy; // Web deployment setup serverDeploy?: ServerDeploy; // Server deployment setup directoryConflict?: DirectoryConflict; // "merge" | "overwrite" | "increment" | "error" renderTitle?: boolean; // Show ASCII art title disableAnalytics?: boolean; // Disable analytics and telemetry } ``` ### `InitResult` Result object returned by `init()`: ```typescript interface InitResult { success: boolean; // Whether operation succeeded projectConfig: ProjectConfig; // Final project configuration reproducibleCommand: string; // CLI command to recreate project timeScaffolded: string; // ISO timestamp of creation elapsedTimeMs: number; // Time taken in milliseconds projectDirectory: string; // Absolute path to project relativePath: string; // Relative path to project error?: string; // Error message if failed } ``` ## Configuration Options ### Directory Conflict Resolution Control how existing directories are handled: ```typescript // Merge with existing files (careful with conflicts) directoryConflict: "merge" // Completely overwrite existing directory directoryConflict: "overwrite" // Create new directory with incremented name (my-app-1) directoryConflict: "increment" // Throw error if directory exists directoryConflict: "error" ``` ### Title Rendering Control CLI output appearance: ```typescript // Hide ASCII art title (useful for automated scripts) renderTitle: false // Show ASCII art title (default) renderTitle: true ``` ### YOLO Mode Bypass validation checks (not recommended): ```typescript // Skip compatibility validations yolo: true ``` ## Error Handling The programmatic API uses different error handling than the CLI: ### Directory Conflicts Directory conflict errors return structured results instead of throwing: ```typescript const result = await init("existing-dir", { directoryConflict: "error" }); if (!result.success) { console.log(result.error); // "Directory exists and is not empty..." // Handle gracefully instead of process exit } ``` ### Validation Errors Validation errors still throw exceptions (maintains CLI compatibility): ```typescript try { await init("test", { database: "mongodb", orm: "drizzle" // Invalid combination }); } catch (error) { console.error(error.message); // "MongoDB requires Mongoose or Prisma ORM" } ``` ## Migration from CLI ### CLI Command to Programmatic API Convert CLI commands to programmatic calls: ```bash # CLI Command create-better-t-stack my-app \ --frontend tanstack-router \ --backend hono \ --database postgres \ --orm drizzle \ --auth better-auth \ --yes ``` ```typescript // Programmatic Equivalent const result = await init("my-app", { frontend: ["tanstack-router"], backend: "hono", database: "postgres", orm: "drizzle", auth: "better-auth", yes: true }); ``` ### Handling Prompts CLI prompts become explicit options: ```typescript // Instead of interactive prompts, specify all options const result = await init("my-app", { yes: true, // Skip all prompts frontend: ["tanstack-router"], backend: "hono", database: "postgres", orm: "drizzle", auth: "better-auth", addons: ["biome", "turborepo"], examples: ["todo"], packageManager: "bun", install: false, git: true }); ```