@basictech/react
v0.7.0
Published
React SDK for [Basic](https://basic.tech) - add authentication and real-time database to your React app in minutes.
Readme
@basictech/react
React SDK for Basic - add authentication and real-time database to your React app in minutes.
Installation
npm install @basictech/reactQuick Start
1. Create a Schema
Create a basic.config.ts file with your project configuration:
export const schema = {
project_id: "YOUR_PROJECT_ID",
version: 1,
tables: {
todos: {
type: "collection",
fields: {
title: { type: "string", indexed: true },
completed: { type: "boolean", indexed: true }
}
}
}
}2. Add the Provider
Wrap your app with BasicProvider:
import { BasicProvider } from '@basictech/react'
import { schema } from './basic.config'
function App() {
return (
<BasicProvider schema={schema}>
<YourApp />
</BasicProvider>
)
}3. Use the Hook
Access auth and database in any component:
import { useBasic, useQuery } from '@basictech/react'
function TodoList() {
const { db, isSignedIn, signIn, signOut, user } = useBasic()
// Live query - automatically updates when data changes
const todos = useQuery(() => db.collection('todos').getAll())
const addTodo = async () => {
await db.collection('todos').add({
title: 'New todo',
completed: false
})
}
if (!isSignedIn) {
return <button onClick={signIn}>Sign In</button>
}
return (
<div>
<p>Welcome, {user?.email}</p>
<button onClick={addTodo}>Add Todo</button>
<ul>
{todos?.map(todo => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
<button onClick={signOut}>Sign Out</button>
</div>
)
}API Reference
<BasicProvider>
Root provider component. Must wrap your entire app.
<BasicProvider
schema={schema} // Required: Your Basic schema
debug={false} // Optional: Enable console logging
dbMode="sync" // Optional: "sync" (default) or "remote"
/>Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| schema | object | required | Schema with project_id and tables |
| debug | boolean | false | Enable debug logging |
| dbMode | "sync" \| "remote" | "sync" | Database mode |
Database Modes
sync- Local-first with IndexedDB + real-time sync via WebSocketremote- Direct REST API calls (no local storage)
useBasic()
Main hook for accessing auth and database.
const {
// Auth state
isReady, // boolean - SDK initialized
isSignedIn, // boolean - User authenticated
user, // { id, email, ... } | null
// Auth methods
signIn, // () => void - Redirect to login
signOut, // () => void - Clear session
signInWithCode, // (code, state?) => Promise - Manual OAuth
getSignInUrl, // (redirectUri?) => string - Get OAuth URL
getToken, // () => Promise<string> - Get access token
// Database
db, // Database instance
dbStatus, // "OFFLINE" | "CONNECTING" | "ONLINE" | "SYNCING"
dbMode, // "sync" | "remote"
} = useBasic()useQuery()
Live query hook - automatically re-renders when data changes.
import { useQuery } from '@basictech/react'
// Get all items
const todos = useQuery(() => db.collection('todos').getAll())
// With type safety
interface Todo {
id: string
title: string
completed: boolean
}
const todos = useQuery(() => db.collection<Todo>('todos').getAll())Note: Only works in
syncmode. Inremotemode, use manual fetching.
Database Methods
db.collection(name)
Access a collection by name.
const { db } = useBasic()
const todos = db.collection('todos')Collection Methods
| Method | Returns | Description |
|--------|---------|-------------|
| getAll() | Promise<T[]> | Get all records |
| get(id) | Promise<T \| null> | Get one record by ID |
| add(data) | Promise<T> | Create new record (returns with ID) |
| put(data) | Promise<T> | Upsert record (requires ID) |
| update(id, data) | Promise<T \| null> | Partial update |
| delete(id) | Promise<boolean> | Delete record |
| filter(fn) | Promise<T[]> | Filter with predicate |
Examples
// Create
const todo = await db.collection('todos').add({
title: 'Buy milk',
completed: false
})
console.log(todo.id) // Auto-generated ID
// Read
const allTodos = await db.collection('todos').getAll()
const oneTodo = await db.collection('todos').get('some-id')
// Update
await db.collection('todos').update('some-id', { completed: true })
// Delete
await db.collection('todos').delete('some-id')
// Filter
const incomplete = await db.collection('todos').filter(t => !t.completed)Advanced Usage
Manual OAuth Flow
For custom OAuth handling (mobile apps, popups, etc.):
const { signInWithCode, getSignInUrl } = useBasic()
// Get OAuth URL with custom redirect
const url = getSignInUrl('myapp://callback')
// Exchange code for session
const result = await signInWithCode(code, state)
if (result.success) {
console.log('Signed in!')
}Remote Mode
For server-rendered apps or when you don't need offline support:
<BasicProvider schema={schema} dbMode="remote">
<App />
</BasicProvider>In remote mode:
- Data is fetched via REST API
- No IndexedDB storage
useQuerywon't auto-update (use manual refresh)- Requires authentication for all operations
Error Handling
import { NotAuthenticatedError } from '@basictech/react'
try {
await db.collection('todos').add({ title: 'Test' })
} catch (error) {
if (error instanceof NotAuthenticatedError) {
// User needs to sign in
signIn()
}
}TypeScript
Full TypeScript support with generics:
interface Todo {
id: string
title: string
completed: boolean
createdAt: number
}
// Type-safe collection
const todos = db.collection<Todo>('todos')
// All methods are typed
const todo = await todos.add({
title: 'Test',
completed: false,
createdAt: Date.now()
})
// todo is typed as TodoLicense
ISC
