Skip to content

Appwrite Cheat Sheet

Overview

Appwrite is a self-hosted or cloud-hosted backend-as-a-service (BaaS) that provides a complete set of APIs and tools for building web and mobile applications. It offers user authentication with multiple providers, a document-based database, file storage, serverless functions, realtime events, and push messaging, all accessible through REST APIs and client/server SDKs.

Appwrite supports over 10 programming language SDKs including JavaScript, Flutter, Swift, Kotlin, Python, and Ruby. It runs as a set of Docker containers and provides a web-based console for managing projects, users, and resources. The platform is designed to be a self-hosted alternative to Firebase with full control over your data.

Installation

Self-Hosted (Docker)

# One-line install
docker run -it --rm \
  --volume /var/run/docker.sock:/var/run/docker.sock \
  --volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
  --entrypoint="install" \
  appwrite/appwrite:1.6

# Or using Docker Compose manually
mkdir appwrite && cd appwrite
curl -o docker-compose.yml https://appwrite.io/install/compose
curl -o .env https://appwrite.io/install/env

# Edit .env with your settings
nano .env

# Start the services
docker compose up -d

# Console available at http://localhost:80

CLI Installation

# Install via npm
npm install -g appwrite-cli

# Or via script
curl -sL https://appwrite.io/cli/install.sh | bash

# Login to your instance
appwrite login

# Initialize a project
appwrite init project

Core Services

Authentication

# Create account via API
curl -X POST "https://cloud.appwrite.io/v1/account" \
  -H "Content-Type: application/json" \
  -H "X-Appwrite-Project: PROJECT_ID" \
  -d '{"userId":"unique()","email":"user@example.com","password":"password123","name":"Alice"}'

# Create email session
curl -X POST "https://cloud.appwrite.io/v1/account/sessions/email" \
  -H "Content-Type: application/json" \
  -H "X-Appwrite-Project: PROJECT_ID" \
  -d '{"email":"user@example.com","password":"password123"}'

JavaScript SDK

import { Client, Account, Databases, Storage, ID, Query } from "appwrite"

const client = new Client()
  .setEndpoint("https://cloud.appwrite.io/v1")
  .setProject("PROJECT_ID")

// Authentication
const account = new Account(client)
await account.create(ID.unique(), "user@example.com", "password123", "Alice")
await account.createEmailPasswordSession("user@example.com", "password123")
const user = await account.get()

// OAuth login
account.createOAuth2Session("google", "http://localhost:3000", "http://localhost:3000/fail")

Database Operations

const databases = new Databases(client)

// Create a document
const doc = await databases.createDocument(
  "DATABASE_ID",
  "COLLECTION_ID",
  ID.unique(),
  {
    title: "My Post",
    content: "Hello World",
    published: true,
    tags: ["news", "tech"],
  }
)

// List documents with queries
const posts = await databases.listDocuments("DATABASE_ID", "COLLECTION_ID", [
  Query.equal("published", true),
  Query.orderDesc("$createdAt"),
  Query.limit(20),
  Query.offset(0),
])

// Get a single document
const post = await databases.getDocument("DATABASE_ID", "COLLECTION_ID", "DOCUMENT_ID")

// Update a document
await databases.updateDocument("DATABASE_ID", "COLLECTION_ID", "DOCUMENT_ID", {
  title: "Updated Title",
})

// Delete a document
await databases.deleteDocument("DATABASE_ID", "COLLECTION_ID", "DOCUMENT_ID")

Query Operators

OperatorExampleDescription
Query.equal()Query.equal("status", "active")Exact match
Query.notEqual()Query.notEqual("role", "admin")Not equal
Query.greaterThan()Query.greaterThan("age", 18)Greater than
Query.lessThan()Query.lessThan("price", 100)Less than
Query.search()Query.search("title", "hello")Full-text search
Query.contains()Query.contains("tags", ["news"])Array contains
Query.between()Query.between("age", 18, 65)Range match
Query.isNull()Query.isNull("deletedAt")Is null
Query.isNotNull()Query.isNotNull("email")Is not null
Query.startsWith()Query.startsWith("name", "Al")String starts with
Query.orderAsc()Query.orderAsc("name")Sort ascending
Query.orderDesc()Query.orderDesc("$createdAt")Sort descending
Query.limit()Query.limit(25)Limit results
Query.offset()Query.offset(50)Skip results

File Storage

const storage = new Storage(client)

// Upload a file
const file = await storage.createFile(
  "BUCKET_ID",
  ID.unique(),
  document.getElementById("fileInput").files[0]
)

// Get file URL for preview
const url = storage.getFilePreview("BUCKET_ID", "FILE_ID", 400, 300)

// Download a file
const download = storage.getFileDownload("BUCKET_ID", "FILE_ID")

// List files
const files = await storage.listFiles("BUCKET_ID")

// Delete a file
await storage.deleteFile("BUCKET_ID", "FILE_ID")

Configuration

CLI Commands

CommandDescription
appwrite loginAuthenticate with your instance
appwrite init projectInitialize project in current directory
appwrite init collectionCreate a collection configuration
appwrite init functionScaffold a new function
appwrite deployDeploy functions and collections
appwrite deploy --allDeploy everything
appwrite consoleOpen the web console

Environment Variables (.env)

_APP_ENV=production
_APP_DOMAIN=appwrite.yourdomain.com
_APP_DOMAIN_TARGET=appwrite.yourdomain.com
_APP_OPENSSL_KEY_V1=your-secret-key
_APP_DB_HOST=mariadb
_APP_DB_PORT=3306
_APP_DB_SCHEMA=appwrite
_APP_DB_USER=user
_APP_DB_PASS=password
_APP_REDIS_HOST=redis
_APP_REDIS_PORT=6379
_APP_SMTP_HOST=smtp.yourdomain.com
_APP_SMTP_PORT=587
_APP_SMTP_USERNAME=mail@yourdomain.com
_APP_SMTP_PASSWORD=smtp-password
_APP_STORAGE_LIMIT=30000000
_APP_FUNCTIONS_SIZE_LIMIT=30000000
_APP_FUNCTIONS_TIMEOUT=900

Advanced Usage

Serverless Functions

// functions/hello/src/main.js
export default async ({ req, res, log, error }) => {
  if (req.method === "GET") {
    return res.json({ message: "Hello from Appwrite Functions!" })
  }

  if (req.method === "POST") {
    const { name } = JSON.parse(req.body)
    log(`Processing request for ${name}`)
    return res.json({ message: `Hello, ${name}!` })
  }

  return res.json({ error: "Method not allowed" }, 405)
}
# Deploy a function
appwrite deploy function

# Execute a function
curl -X POST "https://cloud.appwrite.io/v1/functions/FUNCTION_ID/executions" \
  -H "Content-Type: application/json" \
  -H "X-Appwrite-Project: PROJECT_ID" \
  -H "X-Appwrite-Key: API_KEY" \
  -d '{"body":"{\"name\":\"Alice\"}"}'

Realtime Subscriptions

// Subscribe to document changes
client.subscribe(
  ["databases.DATABASE_ID.collections.COLLECTION_ID.documents"],
  (response) => {
    console.log(response.events)  // e.g., ["databases.*.collections.*.documents.*.create"]
    console.log(response.payload) // the document data
  }
)

// Subscribe to file changes
client.subscribe(["buckets.BUCKET_ID.files"], (response) => {
  console.log("File event:", response.events)
})

// Subscribe to account changes
client.subscribe(["account"], (response) => {
  console.log("Account event:", response.events)
})

Server-Side SDK (Node.js)

import { Client, Databases, Users } from "node-appwrite"

const client = new Client()
  .setEndpoint("https://cloud.appwrite.io/v1")
  .setProject("PROJECT_ID")
  .setKey("API_KEY")

const users = new Users(client)
const userList = await users.list()

const databases = new Databases(client)
await databases.createDocument("DB_ID", "COLL_ID", ID.unique(), {
  title: "Server-created doc",
})

Troubleshooting

IssueSolution
Docker containers not startingCheck Docker resources; ensure ports 80/443 are free
CORS errorsAdd your domain to project platforms in the console
File upload size exceededIncrease _APP_STORAGE_LIMIT in .env
Function timeoutIncrease _APP_FUNCTIONS_TIMEOUT; optimize function code
Authentication errorsVerify project ID and API endpoint; check session validity
Realtime not connectingEnsure WebSocket port is accessible; check SSL configuration
Slow database queriesAdd indexes to frequently queried attributes in the console
Email not sendingConfigure SMTP settings in .env; verify credentials
SSL certificate issuesEnsure _APP_DOMAIN matches your SSL certificate domain