RaisFastRaisFast
Getting Started

Frontend Integration

Connect your frontend to RaisFast using the official TypeScript SDK.

The official SDK (@raisfast/sdk) is a framework-agnostic TypeScript client for the RaisFast API.

Install

pnpm add @raisfast/sdk
# or
npm install @raisfast/sdk
# or
bun add @raisfast/sdk

Initialize

import { RaisFast } from "@raisfast/sdk";

const client = new RaisFast("http://localhost:9898/api/v1");

The constructor accepts an optional auth store (defaults to localStorage):

import { RaisFast, LocalAuthStore } from "@raisfast/sdk";

const store = new LocalAuthStore("my_auth_key");
const client = new RaisFast("http://localhost:9898/api/v1", { authStore: store });

Authentication

// Login
const result = await client.auth.login("admin@raisfast.dev", "admin123");
console.log(result.user, result.access_token);

// Register
await client.auth.register({
  email: "user@example.com",
  password: "strongpassword",
  username: "newuser",
});

// Get current user
const me = await client.auth.getMe();

// Logout
await client.auth.logout();

// Listen to auth state changes
client.authStore.onChange((auth) => {
  console.log("logged in:", !!auth?.token);
});

Tokens are auto-refreshed on 401 responses — no manual refresh needed.

Query Content Types

Use client.collection() to access any content type:

// Access the "portfolios" content type
const portfolios = client.collection<Portfolio>("portfolios");

// List with pagination
const page1 = await portfolios.getList(1, 20);
console.log(page1.items);   // Portfolio[]
console.log(page1.total);   // total count

// List with filters, sort, and relation expansion
const result = await portfolios.getList(1, 20, {
  filter: 'status = "published"',
  sort: "-created_at",
  expand: "category,tags",
});

// Get single item
const item = await portfolios.getOne("item_id");

// Get by filter
const item = await portfolios.getFirstListItem('slug = "my-saas"');

// Fetch all items (auto-paginates)
const all = await portfolios.getFullList();

Mutate Data

// Create
const created = await portfolios.create({
  title: "My SaaS App",
  url: "https://mysaas.com",
  tech_stack: ["Rust", "React"],
});

// Update
const updated = await portfolios.update(created.id, {
  url: "https://mysaas.app",
});

// Delete
await portfolios.delete(created.id);

Type Definitions

Define your types to match the content type schema:

interface Portfolio {
  id: string;
  title: string;
  url?: string;
  cover?: string;
  description?: string;
  tech_stack?: string[];
  status: string;
  created_at: string;
  updated_at: string;
}

// Or generate types from CLI
// raisfast ct types portfolio -o types/portfolio.ts

Use in React

import { RaisFast } from "@raisfast/sdk";
import { useEffect, useState } from "react";

const client = new RaisFast(import.meta.env.VITE_API_URL!);

function PortfolioList() {
  const [items, setItems] = useState<any[]>([]);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    const portfolios = client.collection("portfolios");
    portfolios
      .getList(1, 20, { expand: "category,tags" })
      .then((res) => setItems(res.items))
      .finally(() => setLoading(false));
  }, []);

  if (loading) return <div>Loading...</div>;

  return (
    <ul>
      {items.map((item) => (
        <li key={item.id}>
          <h3>{item.title}</h3>
          <p>{item.description}</p>
        </li>
      ))}
    </ul>
  );
}

Use in Vue

<script setup>
import { RaisFast } from "@raisfast/sdk";
import { ref, onMounted } from "vue";

const client = new RaisFast(import.meta.env.VITE_API_URL!);
const items = ref([]);
const loading = ref(true);

onMounted(async () => {
  const portfolios = client.collection("portfolios");
  const res = await portfolios.getList(1, 20, { expand: "category,tags" });
  items.value = res.items;
  loading.value = false;
});
</script>

<template>
  <div v-if="loading">Loading...</div>
  <ul v-else>
    <li v-for="item in items" :key="item.id">
      <h3>{{ item.title }}</h3>
      <p>{{ item.description }}</p>
    </li>
  </ul>
</template>

Use in Vanilla JS

<script type="module">
import { RaisFast } from "@raisfast/sdk";

const client = new RaisFast("http://localhost:9898/api/v1");
const portfolios = client.collection("portfolios");
const { items } = await portfolios.getList(1, 20);

document.getElementById("list").innerHTML = items
  .map((item) => `<li><h3>${item.title}</h3><p>${item.description}</p></li>`)
  .join("");
</script>

File Upload

const media = client.collection("portfolios");

// Upload a file
const fileInput = document.querySelector<HTMLInputElement>("#cover")!;
const file = fileInput.files![0];

await media.upload(portfolioId, file, "cover");

Admin API

Admin endpoints require admin authentication:

// List all content type schemas
const schemas = await client.admin.contentTypes.list();

// List users
const users = await client.admin.users.list(1, 20);

// Manage plugins
const plugins = await client.admin.plugins.list();
await client.admin.plugins.reload("com.example.my-plugin");

// Dashboard stats
const stats = await client.admin.stats.overview();

Error Handling

import { SDKError } from "@raisfast/sdk";

try {
  await portfolios.getOne("invalid-id");
} catch (e) {
  if (e instanceof SDKError) {
    console.log(e.status);   // 404
    console.log(e.code);     // backend error code
    console.log(e.message);  // "not found"
  }
}

Real-Time Events (SSE)

const es = client.events.subscribe();

es.addEventListener("post.created", (event) => {
  console.log("New post:", JSON.parse(event.data));
});

es.addEventListener("order.paid", (event) => {
  console.log("Order paid:", JSON.parse(event.data));
});

// Cleanup
es.close();

Multi-Tenant

client.setTenantId("tenant-123");  // adds X-Tenant-ID header
client.setTenantId(null);           // reset

Next Step

On this page