s-m-r-t

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

Option 1: Create New Project (Recommended)

bash
npm create smrt-app@latest my-app
cd my-app
npm install
npm run dev

Option 2: Add to Existing Project

bash
npm install @happyvertical/smrt-core @happyvertical/smrt-types

Your First SmrtObject

Step 1: Define Your Model

Create a file src/models/Task.ts:

typescript
import { SmrtObject, field, 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 {
  @field({ required: true })
  title: string = '';

  @field()
  description: string = '';

  @field({ default: 'todo' })
  status: 'todo' | 'in_progress' | 'done' = 'todo';

  @field()
  dueDate?: Date;

  // 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 itemClass = Task;

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

  async findOverdue() {
    return this.list({
      where: {
        status: { $ne: 'done' },
        dueDate: { $lt: new Date() }
      }
    });
  }
}

Step 3: Use Your Object

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

// Initialize
const tasks = await TaskCollection.create({
  db: { /* database config */ }
});

// Create
const task = await tasks.create({
  title: 'Learn SMRT Framework',
  description: 'Read the getting started guide',
  dueDate: new Date('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({
  database: {
    type: 'postgresql',
    host: process.env.DB_HOST,
    port: 5432,
    database: 'myapp',
    user: process.env.DB_USER,
    password: process.env.DB_PASSWORD
  },
  api: {
    enabled: true,
    port: 3000,
    prefix: '/api'
  },
  cli: {
    enabled: true
  },
  mcp: {
    enabled: true,
    port: 3100
  }
});

Next Steps

Common Patterns

Relationships

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

@smrt()
class Project extends SmrtObject {
  @field({ required: true })
  name: string = '';

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

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

Computed Properties

typescript
@smrt()
class Order extends SmrtObject {
  @field()
  subtotal: number = 0;

  @field()
  taxRate: number = 0.08;

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

AI-Powered Methods

typescript
@smrt()
class Document extends SmrtObject {
  @field()
  content: string = '';

  // AI automatically generates these methods
  async summarize(): Promise<string> {
    // AI-powered summarization
  }

  async extractKeywords(): Promise<string[]> {
    // AI-powered keyword extraction
  }
}

Need Help?