appwrite/agent-skills/appwrite-go

Claude Code and agent skill by appwrite/agent-skills

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Appwrite Go SDK skill. Use when building server-side Go applications with Appwrite. Covers user management, database/table CRUD, file storage, and functions via API keys. Uses per-service packages and functional options pattern.

Install

npx vskill@latest install appwrite/agent-skills/appwrite-go

SKILL.md

Appwrite Go SDK

Installation

bash
go get github.com/appwrite/sdk-for-go

Setting Up the Client

go
import (
"os"
"github.com/appwrite/sdk-for-go/client"
"github.com/appwrite/sdk-for-go/id"
"github.com/appwrite/sdk-for-go/users"
"github.com/appwrite/sdk-for-go/tablesdb"
"github.com/appwrite/sdk-for-go/storage"
)
clt := client.New(
client.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"),
client.WithProject(os.Getenv("APPWRITE_PROJECT_ID")),
client.WithKey(os.Getenv("APPWRITE_API_KEY")),
)

Code Examples

User Management
go
service := users.New(clt)
// Create user
user, err := service.Create(
id.Unique(),
"user@example.com",
"password123",
users.WithCreateName("User Name"),
)
// List users
list, err := service.List()
// Get user
fetched, err := service.Get("[USER_ID]")
// Delete user
_, err = service.Delete("[USER_ID]")
Database Operations
Note: Use TablesDB (not the deprecated Databases class) for all new code. Only use Databases if the existing codebase already relies on it or the user explicitly requests it.
Tip: Prefer explicit functional option parameters (e.g., tablesdb.WithUpdateRowData(...)) over bare positional arguments where available. Only use positional-only style if the existing codebase already uses it or the user explicitly requests it.
go
service := tablesdb.New(clt)
// Create database
db, err := service.Create(id.Unique(), "My Database")
// Create row
doc, err := service.CreateRow(
"[DATABASE_ID]",
"[TABLE_ID]",
id.Unique(),
map[string]interface{}{"title": "Hello World"},
)
// List rows
results, err := service.ListRows("[DATABASE_ID]", "[TABLE_ID]")
// Get row
row, err := service.GetRow("[DATABASE_ID]", "[TABLE_ID]", "[ROW_ID]")
// Update row
_, err = service.UpdateRow(
"[DATABASE_ID]",
"[TABLE_ID]",
"[ROW_ID]",
tablesdb.WithUpdateRowData(map[string]interface{}{"title": "Updated"}),
)
// Delete row
_, err = service.DeleteRow("[DATABASE_ID]", "[TABLE_ID]", "[ROW_ID]")
String Column Types
Note: The legacy string type is deprecated. Use explicit column types for all new columns.
TypeMax charactersIndexingStorage
varchar16,383Full index (if size ≤ 768)Inline in row
text16,383Prefix onlyOff-page
mediumtext4,194,303Prefix onlyOff-page
longtext1,073,741,823Prefix onlyOff-page
  • varchar is stored inline and counts towards the 64 KB row size limit. Prefer for short, indexed fields like names, slugs, or identifiers.
  • text, mediumtext, and longtext are stored off-page (only a 20-byte pointer lives in the row), so they don't consume the row size budget. size is not required for these types.
go
// Create table with explicit string column types
_, err = service.CreateTable(
"[DATABASE_ID]",
id.Unique(),
"articles",
tablesdb.WithCreateTableColumns([]map[string]interface{}{
{"key": "title", "type": "varchar", "size": 255, "required": true},
{"key": "summary", "type": "text", "required": false},
{"key": "body", "type": "mediumtext", "required": false},
{"key": "raw_data", "type": "longtext", "required": false},
}),
)
Query Methods
go
import "github.com/appwrite/sdk-for-go/query"
// Filtering
query.Equal("field", "value") // == (or pass slice for IN)
query.NotEqual("field", "value") // !=
query.LessThan("field", 100) // <
query.LessThanEqual("field", 100) // <=
query.GreaterThan("field", 100) // >
query.GreaterThanEqual("field", 100) // >=
query.Between("field", 1, 100) // 1 <= field <= 100
query.IsNull("field") // is null
query.IsNotNull("field") // is not null
query.StartsWith("field", "prefix") // starts with
query.EndsWith("field", "suffix") // ends with
query.Contains("field", "sub") // contains
query.Search("field", "keywords") // full-text search (requires index)
// Sorting
query.OrderAsc("field")
query.OrderDesc("field")
// Pagination
query.Limit(25) // max rows (default 25, max 100)
query.Offset(0) // skip N rows
query.CursorAfter("[ROW_ID]") // cursor pagination (preferred)
query.CursorBefore("[ROW_ID]")
// Selection & Logic
query.Select([]string{"field1", "field2"})
query.Or([]string{query.Equal("a", 1), query.Equal("b", 2)}) // OR
query.And([]string{query.GreaterThan("age", 18), query.LessThan("age", 65)}) // AND (default)
query.Relationship("comments", []string{query.Equal("approved", true), query.Limit(25)}) // related documents
// Aggregations (optional alias)
query.Count("*", "total")
query.Sum("amount", "revenue")
query.Avg("score", "avgScore")
query.Min("price", "minPrice")
query.Max("price", "maxPrice")
// Grouping
query.GroupBy([]interface{}{"status", "year"})
query.Having([]string{query.GreaterThan("total", 1)})
query.Distinct()
// Joins (table id, left key, right key, operator, alias)
query.Join("orders", "$id", "customerId", "=", "")
query.LeftJoin("orders", "$id", "customerId", "=", "ord")
query.LeftJoinOn("orders", "ord", []string{
query.On("$id", "customerId", ""),
query.Equal("ord.status", "paid"),
})
// Fluent builder. Pass Build() into list methods.
queries := query.NewBuilder().
Equal("status", "published").
LeftJoin("orders", "$id", "customerId", "=", "ord").
Count("*", "total").
GroupBy([]interface{}{"status"}).
Limit(25).
Build()
_, _ = service.ListRows("[DATABASE_ID]", "[TABLE_ID]", service.WithListRowsQueries(queries))
File Storage
go
import "github.com/appwrite/sdk-for-go/file"
service := storage.New(clt)
// Upload file
f, err := service.CreateFile(
"[BUCKET_ID]",
"[FILE_ID]",
file.NewInputFile("/path/to/file.png", "file.png"),
)
// List files
files, err := service.ListFiles("[BUCKET_ID]")
// Delete file
_, err = service.DeleteFile("[BUCKET_ID]", "[FILE_ID]")
InputFile Factory Methods
go
import "github.com/appwrite/sdk-for-go/file"
file.NewInputFile("/path/to/file.png", "file.png") // from filesystem path
file.NewInputFileFromReader(reader, "file.png", size) // from io.Reader (size required)
file.NewInputFileFromBytes(data, "file.png") // from []byte
Teams
go
import "github.com/appwrite/sdk-for-go/teams"
svc := teams.New(clt)
// Create team
team, err := svc.Create(id.Unique(), "Engineering")
// List teams
list, err := svc.List()
// Create membership (invite user by email)
membership, err := svc.CreateMembership(
"[TEAM_ID]",
[]string{"editor"},
teams.WithCreateMembershipEmail("user@example.com"),
)
// List memberships
members, err := svc.ListMemberships("[TEAM_ID]")
// Update membership roles
_, err = svc.UpdateMembership("[TEAM_ID]", "[MEMBERSHIP_ID]", []string{"admin"})
// Delete team
_, err = svc.Delete("[TEAM_ID]")
Role-based access: Use role.Team("[TEAM_ID]") for all team members or role.Team("[TEAM_ID]", "editor") for a specific team role when setting permissions.
Serverless Functions
go
import "github.com/appwrite/sdk-for-go/functions"
svc := functions.New(clt)
// Execute function
execution, err := svc.CreateExecution(
"[FUNCTION_ID]",
functions.WithCreateExecutionBody(`{"key": "value"}`),
)
// List executions
executions, err := svc.ListExecutions("[FUNCTION_ID]")
Writing a Function Handler (Go runtime)
go
// src/main.go — Appwrite Function entry point
package handler
import (
"github.com/open-runtimes/types-for-go/v4/openruntimes"
)
func Main(context openruntimes.Context) openruntimes.Response {
// context.Req.Body — raw body (string)
// context.Req.BodyJson — parsed JSON (map[string]interface{})
// context.Req.Headers — headers (map[string]string)
// context.Req.Method — HTTP method
// context.Req.Path — URL path
// context.Req.Query — query params (map[string]string)
context.Log("Processing: " + context.Req.Method + " " + context.Req.Path)
if context.Req.Method == "GET" {
return context.Res.Json(map[string]interface{}{"message": "Hello!"})
}
return context.Res.Json(map[string]interface{}{"success": true})
// context.Res.Text("Hello") // plain text
// context.Res.Empty() // 204
// context.Res.Redirect("https://...") // 302
}
Server-Side Rendering (SSR) Authentication

SSR apps using Go frameworks (net/http, Gin, Echo, Chi, etc.) use the server SDK 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)
go
import (
"github.com/appwrite/sdk-for-go/client"
"github.com/appwrite/sdk-for-go/account"
)
// Admin client (reusable)
adminClient := client.New(
client.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"),
client.WithProject(os.Getenv("APPWRITE_PROJECT_ID")),
client.WithKey(os.Getenv("APPWRITE_API_KEY")),
)
// Session client (create per-request)
sessionClient := client.New(
client.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"),
client.WithProject(os.Getenv("APPWRITE_PROJECT_ID")),
)
cookie, err := r.Cookie("a_session_[PROJECT_ID]")
if err == nil {
sessionClient.SetSession(cookie.Value)
}
Email/Password Login
go
http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
svc := account.New(adminClient)
session, err := svc.CreateEmailPasswordSession(r.FormValue("email"), r.FormValue("password"))
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// Cookie name must be a_session_<PROJECT_ID>
http.SetCookie(w, &http.Cookie{
Name: "a_session_[PROJECT_ID]",
Value: session.Secret,
HttpOnly: true,
Secure: true,
SameSite: http.SameSiteStrictMode,
Path: "/",
})
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"success": true}`))
})
Authenticated Requests
go
http.HandleFunc("/user", func(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie("a_session_[PROJECT_ID]")
if err != nil {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
sessionClient := client.New(
client.WithEndpoint("https://<REGION>.cloud.appwrite.io/v1"),
client.WithProject(os.Getenv("APPWRITE_PROJECT_ID")),
client.WithSession(cookie.Value),
)
svc := account.New(sessionClient)
user, err := svc.Get()
// Marshal user to JSON and write response
})
OAuth2 SSR Flow
go
// Step 1: Redirect to OAuth provider
http.HandleFunc("/oauth", func(w http.ResponseWriter, r *http.Request) {
svc := account.New(adminClient)
redirectURL, err := svc.CreateOAuth2Token(
"github",
account.WithCreateOAuth2TokenSuccess("https://example.com/oauth/success"),
account.WithCreateOAuth2TokenFailure("https://example.com/oauth/failure"),
)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, redirectURL, http.StatusFound)
})

This is the start of the file. Read the full SKILL.md on GitHub.

Security

  • Security scanPassed, 100 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

Repository stars
17
7-day trend score
14

Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 9 Apr 2026, 7 months ago.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/appwrite/agent-skills/appwrite-go/badge)](https://verified-skill.com/skills/appwrite/agent-skills/appwrite-go)

Something wrong with this skill or its page? Tell us.