Frontend Development with Ductape
Ductape provides powerful frontend client libraries that make it easy to build real-time, data-driven applications. Our frontend SDKs give you direct access to databases, storage, workflows, agents, and more—all from the browser with built-in security and real-time synchronization.
Available Packages
Ductape offers three complementary packages for frontend development:
@ductape/client
The core client library that works with any JavaScript framework or vanilla JavaScript. Provides a simple, type-safe interface for all Ductape services.
Use when:
- Building with vanilla JavaScript/TypeScript
- Using frameworks not yet supported (Angular, Svelte, etc.)
- You want full control over data fetching and state management
import { Ductape } from '@ductape/client';
const ductape = new Ductape({
publishableKey: 'your-publishable-key',
});
@ductape/react
React hooks and components built on top of @ductape/client, providing a React-idiomatic way to work with Ductape.
Use when:
- Building React applications (React 17+)
- You want automatic loading states and error handling
- You prefer declarative data fetching with hooks
import { DuctapeProvider, useDatabaseQuery } from '@ductape/react';
import { session } from './config'; // or from your auth (e.g. useSessionToken())
function UsersList() {
const { data, isLoading } = useDatabaseQuery('users', {
table: 'users',
limit: 10,
session, // required when using publishable key
});
}
@ductape/vue
Vue 3 composables and plugin built on top of @ductape/client for Vue applications.
Use when:
- Building Vue 3 applications
- You want reactive data with Vue's composition API
- You need seamless integration with Vue's ecosystem
<script setup>
import { useDatabaseQuery } from '@ductape/vue';
const sessionToken = useSessionToken(); // from your auth/backend
const { data, isLoading } = useDatabaseQuery(
['users'],
{ table: 'users', limit: 10, session: sessionToken }
);
</script>
Key Features
Real-time Subscriptions
Subscribe to database changes, workflow updates, and more with WebSocket-based real-time synchronization.
// Session token from your backend (e.g. after auth)
const sessionToken = getSessionFromYourBackend();
// Automatic real-time updates
const { data } = useDatabaseQuery('todos', {
table: 'todos',
where: { completed: false },
session: sessionToken,
});
// Subscribe to changes
ductape.databases.subscribe({
table: 'todos',
session: sessionToken,
onChange: (event) => console.log('Todo changed:', event)
});
Publishable key and session (required)
When you use a publishable key (the normal frontend setup), the proxy requires a session as a second layer of validation:
- Session in params: Every request must include a
sessionproperty in the options object. The value is a session token issued by your backend (e.g. after user login). Ifsessionis missing or empty, the proxy rejects the request.
// Get session token from your backend (e.g. after auth)
const sessionToken = getSessionFromYourBackend();
// Include session in every Ductape request
const data = await ductape.databases.query({
table: 'orders',
limit: 10,
session: sessionToken, // required when using publishable key
});
await ductape.storage.upload({
storage: 'gcp-storage',
fileName: 'path/file.txt',
data: blob,
mimeType: 'text/plain',
session: sessionToken,
});
- Session APIs are backend-only: When using a publishable key, you cannot call session methods (
sessions.start,sessions.verify,sessions.refresh,sessions.revoke, etc.) from the client—they throw. Sessions must be started and managed only on your backend. Your backend returns a session token to the frontend; the frontend only passes that token assessionin each request.
Type Safety
Full TypeScript support with intelligent type inference for your database schemas and API responses.
const sessionToken = getSessionFromYourBackend();
interface User {
id: string;
name: string;
email: string;
}
const { data } = await ductape.databases.query<User>({
table: 'users',
where: { active: true },
session: sessionToken,
});
// data.rows is typed as User[]
Optimistic Updates
Update your UI instantly while changes sync in the background.
const sessionToken = getSessionFromYourBackend();
const { mutate } = useDatabaseInsert({
onMutate: async (newTodo) => {
// Optimistically update UI
return { newTodo };
},
onError: (err, variables, context) => {
// Rollback on error
}
});
// When calling mutate, include session in the payload
mutate({ table: 'todos', data: newTodo, session: sessionToken });
What Can You Build?
- Real-time Dashboards: Live data visualization with automatic updates
- Collaborative Apps: Multi-user applications with real-time sync
- Chat Applications: Message brokers and presence tracking
- File Sharing: Upload, download, and manage files
- Data-Driven UIs: Complex queries with filtering, sorting, and pagination
- AI-Powered Features: Run agents and workflows directly from the frontend
- Graph Applications: Social networks, recommendation engines
- Vector Search: Semantic search and AI features
Getting Started
Choose your framework and jump right in:
Architecture
All three packages share a common architecture:
┌─────────────────────────────────────────┐
│ Your Application │
├─────────────────────────────────────────┤
│ @ductape/react or @ductape/vue │ ← Framework-specific bindings
├─────────────────────────────────────────┤
│ @ductape/client │ ← Core client SDK
├─────────────────────────────────────────┤
│ HTTP/WebSocket │ ← Transport layer
├─────────────────────────────────────────┤
│ Ductape Backend Services │ ← Your configured product
└─────────────────────────────── ──────────┘
The framework-specific packages (@ductape/react and @ductape/vue) are thin wrappers that provide idiomatic APIs for each framework while leveraging the full power of @ductape/client under the hood.
Next Steps
- Install: Choose your package and install it
- Configure: Set up your client with access keys
- Connect: Initialize connection to your product
- Build: Start using databases, storage, workflows, and more
Explore the documentation for your chosen framework to learn more.