appwrite-typescript
npx skills add https://github.com/chiragagg5k/appwrite-agent-skills --skill appwrite-typescript
Agent 安装分布
Skill 文档
Appwrite TypeScript SDK
Installation
# Web
npm install appwrite
# React Native
npm install react-native-appwrite
# Node.js / Deno
npm install node-appwrite
Setting Up the Client
Client-side (Web / React Native)
// Web
import { Client, Account, TablesDB, Storage, ID, Query } from 'appwrite';
// React Native
import { Client, Account, TablesDB, Storage, ID, Query } from 'react-native-appwrite';
const client = new Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
.setProject('[PROJECT_ID]');
Server-side (Node.js / Deno)
import { Client, Users, TablesDB, Storage, Functions, ID, Query } from 'node-appwrite';
const client = new Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
.setProject(process.env.APPWRITE_PROJECT_ID)
.setKey(process.env.APPWRITE_API_KEY);
Code Examples
Authentication (client-side)
const account = new Account(client);
// Email signup
await account.create({
userId: ID.unique(),
email: 'user@example.com',
password: 'password123',
name: 'User Name'
});
// Email login
const session = await account.createEmailPasswordSession({
email: 'user@example.com',
password: 'password123'
});
// OAuth login
account.createOAuth2Session({
provider: 'github',
success: 'https://example.com/success',
failure: 'https://example.com/fail'
});
// Get current user
const user = await account.get();
// Logout
await account.deleteSession({ sessionId: 'current' });
User Management (server-side)
const users = new Users(client);
// Create user
const user = await users.create({
userId: ID.unique(),
email: 'user@example.com',
password: 'password123',
name: 'User Name'
});
// List users
const list = await users.list({ queries: [Query.limit(25)] });
// Get user
const fetched = await users.get({ userId: '[USER_ID]' });
// Delete user
await users.delete({ userId: '[USER_ID]' });
Database Operations
Note: Use
TablesDB(not the deprecatedDatabasesclass) for all new code. Only useDatabasesif the existing codebase already relies on it or the user explicitly requests it.
const tablesDB = new TablesDB(client);
// Create database (server-side only)
const db = await tablesDB.create({ databaseId: ID.unique(), name: 'My Database' });
// Create table (server-side only)
const col = await tablesDB.createTable({
databaseId: '[DATABASE_ID]',
tableId: ID.unique(),
name: 'My Table'
});
// Create row
const doc = await tablesDB.createRow({
databaseId: '[DATABASE_ID]',
tableId: '[TABLE_ID]',
rowId: ID.unique(),
data: { title: 'Hello World', content: 'Example content' }
});
// List rows with query
const results = await tablesDB.listRows({
databaseId: '[DATABASE_ID]',
tableId: '[TABLE_ID]',
queries: [Query.equal('status', 'active'), Query.limit(10)]
});
// Get row
const row = await tablesDB.getRow({
databaseId: '[DATABASE_ID]',
tableId: '[TABLE_ID]',
rowId: '[ROW_ID]'
});
// Update row
await tablesDB.updateRow({
databaseId: '[DATABASE_ID]',
tableId: '[TABLE_ID]',
rowId: '[ROW_ID]',
data: { title: 'Updated Title' }
});
// Delete row
await tablesDB.deleteRow({
databaseId: '[DATABASE_ID]',
tableId: '[TABLE_ID]',
rowId: '[ROW_ID]'
});
File Storage
const storage = new Storage(client);
// Upload file (client-side â from file input)
const file = await storage.createFile({
bucketId: '[BUCKET_ID]',
fileId: ID.unique(),
file: document.getElementById('file-input').files[0]
});
// Upload file (server-side â from path)
import { InputFile } from 'node-appwrite/file';
const file2 = await storage.createFile({
bucketId: '[BUCKET_ID]',
fileId: ID.unique(),
file: InputFile.fromPath('/path/to/file.png', 'file.png')
});
// List files
const files = await storage.listFiles({ bucketId: '[BUCKET_ID]' });
// Get file preview (image)
const preview = storage.getFilePreview({
bucketId: '[BUCKET_ID]',
fileId: '[FILE_ID]',
width: 300,
height: 300
});
// Download file
const download = await storage.getFileDownload({
bucketId: '[BUCKET_ID]',
fileId: '[FILE_ID]'
});
// Delete file
await storage.deleteFile({ bucketId: '[BUCKET_ID]', fileId: '[FILE_ID]' });
Real-time Subscriptions (client-side)
// Subscribe to row changes
const unsubscribe = client.subscribe('databases.[DATABASE_ID].tables.[TABLE_ID].rows', (response) => {
console.log(response.payload);
});
// Subscribe to file changes
client.subscribe('buckets.[BUCKET_ID].files', (response) => {
console.log(response.payload);
});
// Unsubscribe
unsubscribe();
Serverless Functions (server-side)
const functions = new Functions(client);
// Execute function
const execution = await functions.createExecution({
functionId: '[FUNCTION_ID]',
body: JSON.stringify({ key: 'value' })
});
// List executions
const executions = await functions.listExecutions({ functionId: '[FUNCTION_ID]' });
Server-Side Rendering (SSR) Authentication
SSR apps (Next.js, SvelteKit, Nuxt, Remix, Astro) use the server SDK (node-appwrite) to handle auth. You need two clients:
- Admin client â uses an API key, creates sessions, bypasses rate limits (reusable singleton)
- Session client â uses a session cookie, acts on behalf of a user (create per-request, never share)
import { Client, Account, OAuthProvider } from 'node-appwrite';
// Admin client (reusable)
const adminClient = new Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
.setProject('[PROJECT_ID]')
.setKey(process.env.APPWRITE_API_KEY);
// Session client (create per-request)
const sessionClient = new Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
.setProject('[PROJECT_ID]');
const session = req.cookies['a_session_[PROJECT_ID]'];
if (session) {
sessionClient.setSession(session);
}
Email/Password Login
app.post('/login', async (req, res) => {
const account = new Account(adminClient);
const session = await account.createEmailPasswordSession({
email: req.body.email,
password: req.body.password,
});
// Cookie name must be a_session_<PROJECT_ID>
res.cookie('a_session_[PROJECT_ID]', session.secret, {
httpOnly: true,
secure: true,
sameSite: 'strict',
expires: new Date(session.expire),
path: '/',
});
res.json({ success: true });
});
Authenticated Requests
app.get('/user', async (req, res) => {
const session = req.cookies['a_session_[PROJECT_ID]'];
if (!session) return res.status(401).json({ error: 'Unauthorized' });
// Create a fresh session client per request
const sessionClient = new Client()
.setEndpoint('https://<REGION>.cloud.appwrite.io/v1')
.setProject('[PROJECT_ID]')
.setSession(session);
const account = new Account(sessionClient);
const user = await account.get();
res.json(user);
});
OAuth2 SSR Flow
// Step 1: Redirect to OAuth provider
app.get('/oauth', async (req, res) => {
const account = new Account(adminClient);
const redirectUrl = await account.createOAuth2Token({
provider: OAuthProvider.Github,
success: 'https://example.com/oauth/success',
failure: 'https://example.com/oauth/failure',
});
res.redirect(redirectUrl);
});
// Step 2: Handle callback â exchange token for session
app.get('/oauth/success', async (req, res) => {
const account = new Account(adminClient);
const session = await account.createSession({
userId: req.query.userId,
secret: req.query.secret,
});
res.cookie('a_session_[PROJECT_ID]', session.secret, {
httpOnly: true, secure: true, sameSite: 'strict',
expires: new Date(session.expire), path: '/',
});
res.json({ success: true });
});
Cookie security: Always use
httpOnly,secure, andsameSite: 'strict'to prevent XSS. The cookie name must bea_session_<PROJECT_ID>.
Forwarding user agent: Call
sessionClient.setForwardedUserAgent(req.headers['user-agent'])to record the end-user’s browser info for debugging and security.
Permissions & Roles (Critical)
Appwrite uses permission strings to control access to resources. Each permission pairs an action (read, update, delete, create, or write which grants create + update + delete) with a role target. By default, no user has access unless permissions are explicitly set at the document/file level or inherited from the collection/bucket settings. Permissions are arrays of strings built with the Permission and Role helpers.
import { Permission, Role } from 'appwrite';
// Server-side: import from 'node-appwrite'
Database Row with Permissions
const doc = await tablesDB.createRow({
databaseId: '[DATABASE_ID]',
tableId: '[TABLE_ID]',
rowId: ID.unique(),
data: { title: 'Hello World' },
permissions: [
Permission.read(Role.user('[USER_ID]')), // specific user can read
Permission.update(Role.user('[USER_ID]')), // specific user can update
Permission.read(Role.team('[TEAM_ID]')), // all team members can read
Permission.read(Role.any()), // anyone (including guests) can read
]
});
File Upload with Permissions
const file = await storage.createFile({
bucketId: '[BUCKET_ID]',
fileId: ID.unique(),
file: document.getElementById('file-input').files[0],
permissions: [
Permission.read(Role.any()),
Permission.update(Role.user('[USER_ID]')),
Permission.delete(Role.user('[USER_ID]')),
]
});
When to set permissions: Set document/file-level permissions when you need per-resource access control. If all documents in a collection share the same rules, configure permissions at the collection/bucket level and leave document permissions empty.
Common mistakes:
- Forgetting permissions â the resource becomes inaccessible to all users (including the creator)
Role.any()withwrite/update/deleteâ allows any user, including unauthenticated guests, to modify or remove the resourcePermission.read(Role.any())on sensitive data â makes the resource publicly readable
API Reference
For complete method documentation, see the reference files:
- Account â The Account service allows you to authenticate and manage a user account.
- Avatars â The Avatars service aims to help you complete everyday tasks related to your app image, icons, and avatars.
- Assistant
- Console â The Console service allows you to interact with console relevant information.
- Databases â The Databases service allows you to create structured collections of documents, query and filter lists of documents
- Functions â The Functions Service allows you view, create and manage your Cloud Functions.
- Graphql â The GraphQL API allows you to query and mutate your Appwrite server using GraphQL.
- Health â The Health service allows you to both validate and monitor your Appwrite server’s health.
- Locale â The Locale service allows you to customize your app based on your users’ location.
- Messaging â The Messaging service allows you to send messages to any provider type (SMTP, push notification, SMS, etc.).
- Migrations â The Migrations service allows you to migrate third-party data to your Appwrite project.
- Project â The Project service allows you to manage all the projects in your Appwrite server.
- Projects â The Project service allows you to manage all the projects in your Appwrite server.
- Proxy â The Proxy Service allows you to configure actions for your domains beyond DNS configuration.
- Sites â The Sites Service allows you view, create and manage your web applications.
- Storage â The Storage service allows you to manage your project files.
- TablesDB
- Teams â The Teams service allows you to group users of your project and to enable them to share read and write access to your project resources
- Tokens
- Users â The Users service allows you to manage your project users.
- Vcs