Copy/paste/own infrastructure adapters
Last Updated: November 11, 2025
The Docks Registry is a collection of provider adapters that translate provider APIs to StackDock's universal schema. Adapters follow the copy/paste/own model - you install them into your codebase and own the code.
Current Status: Registry structure ready. GridPane adapter exists in runtime (convex/docks/adapters/gridpane/). Registry manifest structure defined. Ready for adapter contributions.
Two Locations, Two Purposes:
-
packages/docks/- Registry (copy/paste/own)- Source code for adapters
- Copy to your repo via CLI
- You own and modify them
-
convex/docks/adapters/- Runtime (execution)- Adapters imported and executed by Convex
- These are copies from the registry
- Modified versions live here
Flow:
packages/docks/gridpane/ → npx stackdock add gridpane → convex/docks/adapters/gridpane/
(registry) (CLI copies) (runtime execution)
# Install an adapter (when CLI is ready)
npx stackdock add gridpane
# Adapter is copied to convex/docks/adapters/gridpane/
# You own it, modify it, customize itpackages/docks/
├── gridpane/ # Provider adapter
│ ├── adapter.ts # Main adapter logic
│ ├── api.ts # API client
│ ├── types.ts # TypeScript types
│ ├── README.md # Documentation
│ └── package.json
├── vercel/
├── digitalocean/
└── registry.json # Registry manifest
Adapters translate provider APIs to universal tables:
servers- Any server provider (AWS, DigitalOcean, Vultr, etc.)webServices- Any PaaS provider (Vercel, GridPane, Railway, etc.)domains- Any DNS provider (Cloudflare, Route53, etc.)databases- Any database provider
// GridPane API Response → Universal webServices Table
{
id: 12345, → provider: "gridpane",
name: "site.com", TRANSLATES providerResourceId: "12345",
primary_domain: "site.com", TO name: "site.com",
status: "running", productionUrl: "site.com",
phpVersion: "8.2", status: "running",
backup_schedule: "daily" fullApiData: { /* original */ }
}See DOCK_ADAPTER_GUIDE.md for complete instructions.
- Create adapter directory:
packages/docks/my-provider/ - Implement
DockAdapterinterface (seeconvex/docks/_types.ts) - Build API client:
api.ts - Add adapter logic:
adapter.ts - Add documentation:
README.md - Update
registry.jsonwith adapter metadata
Every adapter must implement:
export interface DockAdapter {
provider: string
// Validate API credentials
validateCredentials(apiKey: string): Promise<boolean>
// Sync functions (one per resource type)
syncWebServices?(ctx: MutationCtx, dock: Doc<"docks">): Promise<void>
syncServers?(ctx: MutationCtx, dock: Doc<"docks">): Promise<void>
syncDomains?(ctx: MutationCtx, dock: Doc<"docks">): Promise<void>
syncDatabases?(ctx: MutationCtx, dock: Doc<"docks">): Promise<void>
}See registry.json for the manifest format. Each adapter entry includes:
name: Adapter identifiertitle: Display namedescription: What provider it supportsversion: Semantic versionprovider: Provider identifier (e.g., "gridpane")resourceTypes: Universal tables it syncs tofiles: Files to copydependencies: npm dependenciesapiDocs: Link to provider API documentation
No adapters in registry yet. Check back soon!
Note: Runtime adapters exist in convex/docks/adapters/ (e.g., GridPane), but registry structure is being set up.
- Build your adapter following DOCK_ADAPTER_GUIDE.md
- Ensure it maps to universal tables (not provider-specific tables)
- Implement all required sync methods
- Add tests
- Submit PR
- DOCK_ADAPTER_GUIDE.md - How to build adapters
- ARCHITECTURE.md - System architecture
- CONTRIBUTING.md - Development workflow
Remember: Adapters are copy/paste/own. You install them, you own them, you customize them.