Frontend Framework SDKs

Complete guide to using DataBridge with Angular, React, Vue, and Svelte - TypeScript SDKs for all major frameworks

Frontend Framework SDKs

DataBridge automatically generates type-safe TypeScript SDKs for Angular, React, Vue, and Svelte from your database schema.

Overview

When you run databridge generate, you can select which frontend frameworks to generate SDKs for:

cd my-project
databridge generate

# Select frameworks when prompted:
# 1. Angular (TypeScript services with HttpClient)
# 2. React (TypeScript hooks with fetch)
# 3. Vue.js (Composition API with fetch)
# 4. Svelte (TypeScript stores with fetch)
# 5. Skip frontend SDK generation

# Your choice (1-5) [default: 1]: 1,2,3,4

Or use the --frameworks flag:

databridge generate --frameworks angular,react,vue,svelte

Framework Comparison

FrameworkPatternState ManagementHTTP ClientOutput Directory
AngularServicesRxJS ObservablesHttpClientsrc/databridge/
ReactCustom HooksuseStatefetchsrc/databridge/
VueComposablesref()fetchsrc/databridge/
SvelteStoreswritable()fetchsrc/lib/databridge/

Angular SDK

What’s Generated

src/databridge/
├── services/
│   ├── products.service.ts
│   ├── users.service.ts
│   └── orders.service.ts
├── models/
│   ├── product.interface.ts
│   ├── user.interface.ts
│   └── order.interface.ts
└── index.ts

Usage Example

// app.component.ts
import { Component, OnInit } from '@angular/core';
import { ProductsService } from './databridge/services/products.service';
import { Product } from './databridge/models/product.interface';
import { Observable } from 'rxjs';

@Component({
  selector: 'app-products',
  template: `
    <div *ngFor="let product of products$ | async">
      <h3>{{ product.name }}</h3>
      <p>{{ product.price | currency }}</p>
    </div>
  `
})
export class ProductsComponent implements OnInit {
  products$!: Observable<Product[]>;

  constructor(private productsService: ProductsService) {}

  ngOnInit() {
    this.products$ = this.productsService.list();
  }

  createProduct(name: string, price: number) {
    this.productsService.create({ name, price }).subscribe(
      product => console.log('Created:', product),
      error => console.error('Error:', error)
    );
  }
}

Service API

Each generated service includes:

class ProductsService {
  list(): Observable<Product[]>                    // GET /products
  getById(id: number): Observable<Product>         // GET /products/:id
  create(data: CreateProduct): Observable<Product> // POST /products
  update(id: number, data: UpdateProduct): Observable<Product> // PUT /products/:id
  delete(id: number): Observable<void>             // DELETE /products/:id
}

Custom Queries (Angular)

If you have custom queries defined in databridge.queries.ts:

// databridge.queries.ts
export default defineQueries({
  'getUserDashboard': {
    method: 'GET',
    path: '/users/:userId/dashboard',
    params: { userId: { type: 'number', required: true } },
    handler: async (prisma, { params }) => { /* ... */ }
  }
});

Generated service includes:

// custom-queries.service.ts
class CustomQueriesService {
  getUserDashboard(userId: number): Observable<any> {
    return this.http.get(`${this.apiUrl}/users/${userId}/dashboard`);
  }
}

React SDK

What’s Generated

src/databridge/
├── hooks/
│   ├── useProducts.ts
│   ├── useUsers.ts
│   └── useOrders.ts
├── types/
│   ├── product.ts
│   ├── user.ts
│   └── order.ts
└── index.ts

Usage Example

// ProductList.tsx
import React, { useEffect } from 'react';
import { useProducts } from './databridge/hooks/useProducts';

export function ProductList() {
  const { 
    products, 
    loading, 
    error, 
    fetchProducts, 
    createProduct, 
    deleteProduct 
  } = useProducts();

  useEffect(() => {
    fetchProducts();
  }, []);

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error}</div>;

  return (
    <div>
      {products.map(product => (
        <div key={product.id}>
          <h3>{product.name}</h3>
          <p>${product.price}</p>
          <button onClick={() => deleteProduct(product.id)}>Delete</button>
        </div>
      ))}
      <button onClick={() => createProduct({ name: 'New Product', price: 99 })}>
        Add Product
      </button>
    </div>
  );
}

Hook API

Each generated hook returns:

function useProducts() {
  return {
    products: Product[],              // List of products
    loading: boolean,                 // Loading state
    error: string | null,             // Error message
    fetchProducts: () => Promise<void>,        // GET /products
    fetchProductById: (id) => Promise<void>,   // GET /products/:id
    createProduct: (data) => Promise<void>,    // POST /products
    updateProduct: (id, data) => Promise<void>, // PUT /products/:id
    deleteProduct: (id) => Promise<void>       // DELETE /products/:id
  };
}

Custom Queries (React)

Custom queries become additional hooks:

// hooks/useCustomQueries.ts
export function useCustomQueries() {
  const [dashboard, setDashboard] = useState<any>(null);

  const getUserDashboard = async (userId: number) => {
    const response = await fetch(`/api/users/${userId}/dashboard`);
    const data = await response.json();
    setDashboard(data);
  };

  return { dashboard, getUserDashboard };
}

Vue SDK

What’s Generated

src/databridge/
├── composables/
│   ├── useProducts.ts
│   ├── useUsers.ts
│   └── useOrders.ts
├── types/
│   ├── product.ts
│   ├── user.ts
│   └── order.ts
└── index.ts

Usage Example

<!-- ProductList.vue -->
<script setup lang="ts">
import { onMounted } from 'vue';
import { useProducts } from '@/databridge/composables/useProducts';

const { 
  products, 
  loading, 
  error, 
  fetchProducts, 
  createProduct, 
  deleteProduct 
} = useProducts();

onMounted(() => {
  fetchProducts();
});

const handleCreate = () => {
  createProduct({ name: 'New Product', price: 99 });
};
</script>

<template>
  <div>
    <div v-if="loading">Loading...</div>
    <div v-else-if="error">Error: {{ error }}</div>
    <div v-else>
      <div v-for="product in products" :key="product.id">
        <h3>{{ product.name }}</h3>
        <p>${{ product.price }}</p>
        <button @click="deleteProduct(product.id)">Delete</button>
      </div>
      <button @click="handleCreate">Add Product</button>
    </div>
  </div>
</template>

Composable API

Each generated composable returns:

function useProducts() {
  return {
    products: Ref<Product[]>,         // Reactive list
    loading: Ref<boolean>,            // Loading state
    error: Ref<string | null>,        // Error message
    fetchProducts: () => Promise<void>,
    fetchProductById: (id: number) => Promise<void>,
    createProduct: (data: CreateProduct) => Promise<void>,
    updateProduct: (id: number, data: UpdateProduct) => Promise<void>,
    deleteProduct: (id: number) => Promise<void>
  };
}

Custom Queries (Vue)

Custom queries get their own composable:

// composables/useCustomQueries.ts
export function useCustomQueries() {
  const dashboard = ref<any>(null);

  const getUserDashboard = async (userId: number) => {
    const response = await fetch(`/api/users/${userId}/dashboard`);
    dashboard.value = await response.json();
  };

  return { dashboard, getUserDashboard };
}

Svelte SDK

What’s Generated

src/lib/databridge/
├── stores/
│   ├── products.ts
│   ├── users.ts
│   └── orders.ts
├── types/
│   ├── product.ts
│   ├── user.ts
│   └── order.ts
└── index.ts

Usage Example

<!-- ProductList.svelte -->
<script lang="ts">
  import { onMount } from 'svelte';
  import { 
    products, 
    loading, 
    error, 
    fetchProducts, 
    createProduct, 
    deleteProduct 
  } from '$lib/databridge/stores/products';

  onMount(() => {
    fetchProducts();
  });

  function handleCreate() {
    createProduct({ name: 'New Product', price: 99 });
  }
</script>

{#if $loading}
  <div>Loading...</div>
{:else if $error}
  <div>Error: {$error}</div>
{:else}
  {#each $products as product (product.id)}
    <div>
      <h3>{product.name}</h3>
      <p>${product.price}</p>
      <button on:click={() => deleteProduct(product.id)}>Delete</button>
    </div>
  {/each}
  <button on:click={handleCreate}>Add Product</button>
{/if}

Store API

Each generated store exports:

// Reactive stores
export const products = writable<Product[]>([]);
export const loading = writable<boolean>(false);
export const error = writable<string | null>(null);

// Actions
export function fetchProducts(): Promise<void>
export function fetchProductById(id: number): Promise<void>
export function createProduct(data: CreateProduct): Promise<void>
export function updateProduct(id: number, data: UpdateProduct): Promise<void>
export function deleteProduct(id: number): Promise<void>

Custom Queries (Svelte)

Custom queries get their own store:

// stores/customQueries.ts
import { writable } from 'svelte/store';

export const dashboard = writable<any>(null);

export async function getUserDashboard(userId: number) {
  const response = await fetch(`/api/users/${userId}/dashboard`);
  const data = await response.json();
  dashboard.set(data);
}

Common Features (All Frameworks)

TypeScript Types

All frameworks share the same TypeScript types:

// types/product.ts
export interface Product {
  id: number;
  name: string;
  price: number;
  description?: string;
  createdAt: Date;
  updatedAt: Date;
}

export interface CreateProduct {
  name: string;
  price: number;
  description?: string;
}

export interface UpdateProduct {
  name?: string;
  price?: number;
  description?: string;
}

API Configuration

All SDKs use the same base URL configuration:

// Angular
const API_URL = 'http://localhost:3000';

// React
const API_BASE_URL = 'http://localhost:3000';

// Vue
const API_URL = 'http://localhost:3000';

// Svelte
const API_BASE_URL = 'http://localhost:3000';

Update this in your generated code to match your API server URL.

Error Handling

All SDKs include consistent error handling:

// All frameworks catch errors and expose them in state
try {
  const response = await fetch(`${API_URL}/products`);
  if (!response.ok) {
    throw new Error(`HTTP ${response.status}: ${response.statusText}`);
  }
  const data = await response.json();
  // Update state...
} catch (err) {
  setError(err.message); // React
  error.value = err.message; // Vue
  error.set(err.message); // Svelte
  // return throwError(() => err); // Angular
}

Generating Multiple Frameworks

You can generate SDKs for multiple frameworks at once:

# Interactive selection
databridge generate
# Choose: 1,2,3,4

# Via flag
databridge generate --frameworks angular,react,vue,svelte

# Only React and Vue
databridge generate --frameworks react,vue

# Skip SDK generation
databridge generate --frameworks none

File Output:

my-project/
├── api/                      # Generated API routes
│   ├── routes/
│   ├── openapi.json
│   └── server.ts
├── src/databridge/           # Angular, React, Vue SDKs
│   ├── services/             # Angular
│   ├── hooks/                # React
│   ├── composables/          # Vue
│   ├── models/
│   └── types/
└── src/lib/databridge/       # Svelte SDK
    ├── stores/
    └── types/

Custom Queries Support

All frameworks support custom queries automatically!

Define custom query:

// databridge.queries.ts
export default defineQueries({
  'getUserDashboard': {
    method: 'GET',
    path: '/users/:userId/dashboard',
    params: { userId: { type: 'number', required: true } },
    handler: async (prisma, { params }) => {
      return { user, stats, recentOrders };
    }
  }
});

Generated SDK methods:

// Angular
customQueriesService.getUserDashboard(userId).subscribe(...)

// React
const { getUserDashboard } = useCustomQueries();
await getUserDashboard(userId);

// Vue
const { getUserDashboard } = useCustomQueries();
await getUserDashboard(userId);

// Svelte
import { getUserDashboard } from '$lib/databridge/stores/customQueries';
await getUserDashboard(userId);

Next Steps


Framework-Specific Resources

Angular

React

Vue

Svelte


Status

FrameworkStatusDocumentationExample AppNotes
Angular✅ Production-readyComplete✅ AvailableFully tested
React⚠️ Code completeThis guide🔜 Coming soonNeeds E2E testing
Vue⚠️ Code completeThis guide🔜 Coming soonNeeds E2E testing
Svelte⚠️ Code completeThis guide🔜 Coming soonNeeds E2E testing

Updated: January 5, 2026 | Version: 0.2.9

Was this page helpful?