Getting Started with SMRT

Learn how to install SMRT, create your first project, and build your first SmrtObject in under 10 minutes.

What is SMRT?

SMRT is a full-stack TypeScript framework that abstracts away implementation details for databases, REST APIs, MCP tools, and CLI commands through simple object definitions. Define your data models once, and SMRT automatically generates everything you need.

Core Benefits:

  • No Vendor Lock: Works with PostgreSQL, SQLite, and more
  • Adaptable: Easy to extend and customize
  • Brief: Minimal boilerplate code
  • Scalable: From prototypes to production

Prerequisites

  • Node.js 20+ installed
  • Basic TypeScript knowledge
  • Familiarity with npm/pnpm

Installation

Install Core Packages

bash
pnpm add @happyvertical/smrt-core @happyvertical/smrt-types @happyvertical/smrt-config

Add Domain Packages as Needed

Install additional packages for your use case. For example, for agents and background jobs:

bash
pnpm add @happyvertical/smrt-agents @happyvertical/smrt-jobs

Your First SmrtObject

Step 1: Define Your Model

Create a file src/models/Task.ts:

typescript
import { SmrtObject, smrt } from '@happyvertical/smrt-core';

@smrt({
  api: true,    // Generate REST API
  cli: true,    // Generate CLI commands
  mcp: true     // Generate MCP tools
})
export class Task extends SmrtObject {
  title: string = '';
  description: string = '';
  status: string = 'todo';
  dueDate: string = '';

  // Custom method
  complete() {
    this.status = 'done';
  }
}

Step 2: Create the Collection

typescript
import { SmrtCollection } from '@happyvertical/smrt-core';
import { Task } from './Task.js';

export class TaskCollection extends SmrtCollection<Task> {
  static readonly _itemClass = Task;

  // Custom query methods
  async findByStatus(status: string) {
    return this.list({ where: { status } });
  }

  async findOverdue() {
    return this.list({
      where: {
        'status !=': 'done',
        'dueDate <': new Date().toISOString()
      }
    });
  }
}

Step 3: Use Your Object

typescript
import { TaskCollection } from './models/TaskCollection.js';

// Create collection via static factory
const tasks = await TaskCollection.create({
  db: 'tasks.db'
});

// Create
const task = await tasks.create({
  title: 'Learn SMRT Framework',
  description: 'Read the getting started guide',
  dueDate: '2025-01-20'
});
await task.save();

// Query
const allTasks = await tasks.list();
const todoTasks = await tasks.findByStatus('todo');
const overdue = await tasks.findOverdue();

// Update
task.status = 'in_progress';
await task.save();

// Custom method
task.complete();
await task.save();

// Delete
await task.delete();

Auto-Generated Features

With the @smrt decorator, you automatically get:

REST API Endpoints

http
GET    /api/tasks          # List tasks
GET    /api/tasks/:id      # Get task by ID
POST   /api/tasks          # Create task
PATCH  /api/tasks/:id      # Update task
DELETE /api/tasks/:id      # Delete task

CLI Commands

bash
smrt tasks list
smrt tasks get <id>
smrt tasks create --title "My Task"
smrt tasks update <id> --status done
smrt tasks delete <id>

MCP Tools (Claude Integration)

Claude Code can now interact with your tasks using natural language.

Configuration

Create smrt.config.ts in your project root:

typescript
import { defineConfig } from '@happyvertical/smrt-config';

export default defineConfig({
  smrt: {
    logLevel: 'info',
    environment: 'development',
    embeddings: { provider: 'local' }
  },
  modules: {
    // Module-scoped configs keyed by module name
    'my-agent': {
      cronSchedule: '0 2 * * *',
      maxRetries: 3
    }
  },
  packages: {
    // Package-scoped configs keyed by package name
    ai: { defaultModel: 'gpt-4o' }
  }
});

Note:

The config top-level keys are smrt (global options), modules (module-scoped config), packages (package-scoped config), site (site templates), and export (SSG export). Use getModuleConfig() and getPackageConfig() to retrieve them at runtime.

Next Steps

Common Patterns

Relationships

typescript
import { SmrtObject, smrt, foreignKey, manyToMany } from '@happyvertical/smrt-core';

@smrt()
class Project extends SmrtObject {
  name: string = '';

  @foreignKey(User)
  ownerId: string = '';

  @manyToMany(Tag, { through: 'project_tags' })
  tags: Tag[] = [];
}

Computed Properties

typescript
@smrt()
class Order extends SmrtObject {
  subtotal: number = 0.0;
  taxRate: number = 0.08;

  get total(): number {
    return this.subtotal * (1 + this.taxRate);
  }
}

AI-Powered Methods

typescript
// is() — evaluate criteria against the object, returns boolean
const isValid = await product.is(`
  - Has a non-empty description
  - Price is greater than $10
  - Name does not contain profanity
`);

// do() — perform an action based on instructions, returns string
const summary = await product.do(`
  Write a 50-word marketing description.
  Highlight key features and target audience.
`);

Need Help?