9gen
v1.0.9
Published
The 9gen SDK is a full-stack development toolkit for React Native/Expo applications, providing authentication, database operations, and API routing.
Readme
9gen SDK Documentation
The 9gen SDK is a full-stack development toolkit for React Native/Expo applications, providing authentication, database operations, and API routing.
Installation
npm install 9gen zod
# or
yarn add 9gen zod
# or
bun add 9gen zodQuick Start
1. Client Setup
Create a client instance in your app (e.g., lib/9gen.ts):
import { createClient } from "9gen";
import { z } from "zod";
export const client = createClient({
__DEV__, // Development mode flag
appId: "your-app-id", // Your 9gen application ID
baseURL: "https://api.9gen.dev", // API base URL (or localhost for dev)
requireAuth: true, // Require authentication for API routes
scheme: "myapp", // Your app's URL scheme
storagePrefix: "myapp", // Optional: prefix for secure storage keys
db: {
models: {
Todo: z.object({
title: z.string(),
description: z.string(),
completed: z.boolean(),
}),
// Add more models as needed
},
},
});2. Configuration Options
| Option | Type | Required | Description |
|--------|------|----------|-------------|
| __DEV__ | boolean | Yes | Development mode flag (uses "exp" scheme in dev) |
| appId | string | Yes | Your 9gen application ID |
| baseURL | string | No | API base URL (default: "https://api.9gen.dev") |
| requireAuth | boolean | No | Require authentication for API routes (default: false) |
| scheme | string | Yes | Your app's URL scheme for OAuth redirects |
| storagePrefix | string | No | Prefix for secure storage keys (default: appId) |
| db.models | Record<string, ZodObject> | Yes | Database model definitions using Zod schemas |
Authentication
Session Management
// Get current session
const { data: session } = client.auth.useSession();
// Check if user is authenticated
if (session?.user) {
console.log("User:", session.user);
}Social Authentication (Google, Apple)
// Google Sign In
await client.auth.signIn.social({
provider: "google",
callbackURL: "/",
});
// Apple Sign In
await client.auth.signIn.social({
provider: "apple",
callbackURL: "/",
});Email OTP Authentication
// Step 1: Send OTP to email
await client.auth.emailOtp.sendVerificationOtp({
email: "[email protected]",
type: "sign-in",
});
// Step 2: Verify OTP
await client.auth.signIn.emailOtp({
email: "[email protected]",
otp: "123456",
});Sign Out
await client.auth.signOut();Database Operations
The SDK automatically creates typed database entities based on your Zod schemas.
Insert
const todo = await db.Todo.insert({
title: "Learn 9gen SDK",
description: "Read the documentation",
completed: false,
});
// Returns: { id: string, title: string, description: string, completed: boolean }Get by ID
const todo = await db.Todo.get("todo-id");Update
const updatedTodo = await db.Todo.update("todo-id", {
completed: true,
});Delete
await db.Todo.delete("todo-id");List with Options
const result = await db.Todo.list({
query: { completed: false }, // Filter criteria
sort: "createdAt", // Sort field
limit: 10, // Number of items
skip: 0, // Pagination offset
fields: ["title", "completed"], // Select specific fields
});
// Returns: { entities: Todo[], totalCount: number }Delete Many
const result = await db.Todo.deleteMany({
completed: true,
});
// Returns: { success: boolean, deletedCount: number }API Routes (Expo)
Create server-side API routes in your Expo app with automatic authentication and database access.
Define API Route
Create a file like app/api/todos+api.ts:
import { client } from "@/lib/9gen";
export const GET = client.api.handler(async (request, context) => {
const { user, db } = context;
// User is automatically authenticated (if requireAuth: true)
console.log("Current user:", user);
// Database entities are available
const todos = await db.Todo.list();
return new Response(JSON.stringify(todos), {
headers: { "Content-Type": "application/json" },
});
});
export const POST = client.api.handler(async (request, context) => {
const { user, db } = context;
const body = await request.json();
const newTodo = await db.Todo.insert(body);
return new Response(JSON.stringify(newTodo), {
status: 201,
headers: { "Content-Type": "application/json" },
});
});Call API from Client
// Automatically includes authentication headers
const response = await client.api.fetch("/api/todos");
const todos = await response.json();TypeScript Support
All entities are fully typed based on your Zod schemas:
// Define schema
const TodoSchema = z.object({
title: z.string(),
description: z.string(),
completed: z.boolean(),
});
// Entity type is automatically inferred
type Todo = z.infer<typeof TodoSchema> & { id: string };
// Full autocomplete and type safety
const todo = await db.Todo.insert({
title: "...", // ✓ Type-safe
description: "...", // ✓ Type-safe
completed: false, // ✓ Type-safe
// @ts-expect-error - Property doesn't exist
invalid: "field", // ✗ Type error
});Complete Example
// lib/9gen.ts
import { createClient } from "9gen";
import { z } from "zod";
export const client = createClient({
__DEV__,
appId: "my-app",
baseURL: "http://localhost:3000",
requireAuth: true,
scheme: "myapp",
db: {
models: {
Todo: z.object({
title: z.string(),
description: z.string(),
completed: z.boolean(),
}),
User: z.object({
name: z.string(),
email: z.string().email(),
}),
},
},
});
// app/index.tsx
import { client } from "@/lib/9gen";
import { View, Button } from "react-native";
export default function Home() {
const { data: session } = client.auth.useSession();
const handleLogin = async () => {
await client.auth.signIn.social({
provider: "google",
callbackURL: "/",
});
};
const handleFetchTodos = async () => {
const response = await client.api.fetch("/api/todos");
const todos = await response.json();
console.log(todos);
};
return (
<View>
{!session ? (
<Button title="Sign In" onPress={handleLogin} />
) : (
<>
<Button title="Fetch Todos" onPress={handleFetchTodos} />
<Button title="Sign Out" onPress={() => client.auth.signOut()} />
</>
)}
</View>
);
}
// app/api/todos+api.ts
import { client } from "@/lib/9gen";
export const GET = client.api.handler(async (request, context) => {
const { user, db } = context;
const todos = await db.Todo.list();
return new Response(JSON.stringify(todos));
});Key Features
- Type-Safe Database: Zod schemas provide runtime validation and TypeScript types
- Built-in Authentication: Social OAuth and email OTP out of the box
- Expo Integration: Native support for Expo API routes and secure storage
- Auto-Authenticated Requests:
client.api.fetchautomatically includes auth headers - CRUD Operations: Full set of database operations (get, insert, update, delete, list)
- Flexible Querying: Filter, sort, paginate, and select specific fields
File Locations Reference
- Client setup:
lib/9gen.ts - API routes:
app/api/*+api.ts - Authentication usage:
app/index.tsx:8(useSession) - Social login:
app/index.tsx:10-22 - Email OTP:
app/index.tsx:23-38 - Database operations:
app/api/hello+api.ts:4-27 - Authenticated fetch:
app/index.tsx:44-48
