Appwrite is a self-hosted backend-as-a-service with auth, databases, storage, functions, and real-time — all in one Docker deployment. It's Firebase you actually own.
Why Appwrite?
- Self-hosted — Docker install, you own everything
- Everything built-in — auth, DB, storage, functions, messaging
- 14+ SDKs — web, mobile, server-side, CLI
- Free tier (cloud) — 75K requests, 2GB bandwidth, 10GB storage
Quick Start (Self-Hosted)
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.0
# Console at http://localhost
JavaScript SDK
npm install appwrite
import { Client, Account, Databases } from 'appwrite';
const client = new Client()
.setEndpoint('https://cloud.appwrite.io/v1')
.setProject('YOUR_PROJECT_ID');
const account = new Account(client);
const databases = new Databases(client);
Auth
// Sign up
await account.create('unique()', 'alice@example.com', 'password', 'Alice');
// Login
await account.createEmailPasswordSession('alice@example.com', 'password');
// OAuth
await account.createOAuth2Session('github');
// Get current user
const user = await account.get();
// Logout
await account.deleteSession('current');
Database
// Create document
const post = await databases.createDocument(
'main', // database ID
'posts', // collection ID
'unique()', // document ID
{
title: 'Hello Appwrite',
content: 'This is great',
published: true,
}
);
// List with filters
const posts = await databases.listDocuments('main', 'posts', [
Query.equal('published', true),
Query.orderDesc('$createdAt'),
Query.limit(10),
]);
// Update
await databases.updateDocument('main', 'posts', postId, {
title: 'Updated Title',
});
// Delete
await databases.deleteDocument('main', 'posts', postId);
Storage
import { Storage } from 'appwrite';
const storage = new Storage(client);
// Upload file
const file = await storage.createFile(
'images', // bucket ID
'unique()',
document.getElementById('upload').files[0]
);
// Get file URL
const url = storage.getFileView('images', file.$id);
// Get preview (with transforms)
const preview = storage.getFilePreview('images', file.$id, 200, 200);
Real-Time
const unsubscribe = client.subscribe(
'databases.main.collections.messages.documents',
(response) => {
if (response.events.includes('databases.*.collections.*.documents.*.create')) {
console.log('New message:', response.payload);
}
}
);
Functions (Serverless)
// functions/hello/src/main.js
export default async ({ req, res, log }) => {
const { name } = JSON.parse(req.body);
log(`Hello ${name}`);
return res.json({ message: `Hello, ${name}!` });
};
Need backend data from the web? Check out my Apify actors for web scraping + Appwrite integration. Email spinov001@gmail.com for custom solutions.
Appwrite, Supabase, or Firebase — which BaaS do you choose? Share below!
Top comments (0)