Base44 Coder
Build apps on the Base44 platform using the Base44 JavaScript SDK.
⚡ IMMEDIATE ACTION REQUIRED - Read This First
This skill activates on ANY mention of "base44" or when a base44/ folder exists. DO NOT read documentation files or search the web before acting.
Your first action MUST be:
- Check if
base44/config.jsoncexists in the current directory - If YES (existing project scenario):
- This skill (base44-sdk) handles the request
- Implement features using Base44 SDK
- Do NOT use base44-cli unless user explicitly requests CLI commands
- If NO (new project scenario):
- Transfer to base44-cli skill for project initialization
- This skill cannot help until project is initialized
When to Use This Skill vs base44-cli
Use base44-sdk when:
- Building features in an EXISTING Base44 project
base44/config.jsoncalready exists in the project- Base44 SDK imports are present (
@base44/sdk) - Writing JavaScript/TypeScript code using Base44 SDK modules
- Implementing functionality, components, or features
- User mentions: "implement", "build a feature", "add functionality", "write code for"
- User says "create a [type] app" and a Base44 project already exists
DO NOT USE base44-sdk for:
- ❌ Initializing new Base44 projects (use
base44-cliinstead) - ❌ Empty directories without Base44 configuration
- ❌ When user says "create a new Base44 project/app/site" and no project exists
- ❌ CLI commands like
npx base44 create,npx base44 deploy,npx base44 login(usebase44-cli)
Skill Dependencies:
base44-sdkassumes a Base44 project is already initializedbase44-cliis a prerequisite forbase44-sdkin new projects- If user wants to "create an app" and no Base44 project exists, use
base44-clifirst
State Check Logic: Before selecting this skill, verify:
- IF (user mentions "create/build app" OR "make a project"):
- IF (directory is empty OR no
base44/config.jsoncexists): → Use base44-cli (project initialization needed) - ELSE: → Use base44-sdk (project exists, build features)
- IF (directory is empty OR no
Quick Start
javascript1// In Base44-generated apps, base44 client is pre-configured and available 2 3// CRUD operations 4const task = await base44.entities.Task.create({ title: "New task", status: "pending" }); 5const tasks = await base44.entities.Task.list(); 6await base44.entities.Task.update(task.id, { status: "done" }); 7 8// Get current user 9const user = await base44.auth.me();
javascript1// External apps 2import { createClient } from "@base44/sdk"; 3 4// IMPORTANT: Use 'appId' (NOT 'clientId' or 'id') 5const base44 = createClient({ appId: "your-app-id" }); 6await base44.auth.loginViaEmailPassword("user@example.com", "password");
⚠️ CRITICAL: Do Not Hallucinate APIs
Before writing ANY Base44 code, verify method names against this table or QUICK_REFERENCE.md.
Base44 SDK has unique method names. Do NOT assume patterns from Firebase, Supabase, or other SDKs.
Authentication - WRONG vs CORRECT
| ❌ WRONG (hallucinated) | ✅ CORRECT |
|---|---|
signInWithGoogle() | loginWithProvider('google') |
signInWithProvider('google') | loginWithProvider('google') |
auth.google() | loginWithProvider('google') |
signInWithEmailAndPassword(email, pw) | loginViaEmailPassword(email, pw) |
signIn(email, pw) | loginViaEmailPassword(email, pw) |
createUser() / signUp() | register({email, password}) |
onAuthStateChanged() | me() (no listener, call when needed) |
currentUser | await auth.me() |
Functions - WRONG vs CORRECT
| ❌ WRONG (hallucinated) | ✅ CORRECT |
|---|---|
functions.call('name', data) | functions.invoke('name', data) |
functions.run('name', data) | functions.invoke('name', data) |
callFunction('name', data) | functions.invoke('name', data) |
httpsCallable('name')(data) | functions.invoke('name', data) |
Integrations - WRONG vs CORRECT
| ❌ WRONG (hallucinated) | ✅ CORRECT |
|---|---|
ai.generate(prompt) | integrations.Core.InvokeLLM({prompt}) |
openai.chat(prompt) | integrations.Core.InvokeLLM({prompt}) |
llm(prompt) | integrations.Core.InvokeLLM({prompt}) |
sendEmail(to, subject, body) | integrations.Core.SendEmail({to, subject, body}) |
email.send() | integrations.Core.SendEmail({to, subject, body}) |
uploadFile(file) | integrations.Core.UploadFile({file}) |
storage.upload(file) | integrations.Core.UploadFile({file}) |
Entities - WRONG vs CORRECT
| ❌ WRONG (hallucinated) | ✅ CORRECT |
|---|---|
entities.Task.find({...}) | entities.Task.filter({...}) |
entities.Task.findOne(id) | entities.Task.get(id) |
entities.Task.insert(data) | entities.Task.create(data) |
entities.Task.remove(id) | entities.Task.delete(id) |
entities.Task.onChange(cb) | entities.Task.subscribe(cb) |
SDK Modules
| Module | Purpose | Reference |
|---|---|---|
entities | CRUD operations on data models | entities.md |
auth | Login, register, user management | auth.md |
agents | AI conversations and messages | base44-agents.md |
functions | Backend function invocation | functions.md |
integrations | AI, email, file uploads, custom APIs | integrations.md |
connectors | OAuth tokens (service role only) | connectors.md |
analytics | Track custom events and user activity | analytics.md |
appLogs | Log user activity in app | app-logs.md |
users | Invite users to the app | users.md |
For client setup and authentication modes, see client.md.
TypeScript Support: Each reference file includes a "Type Definitions" section with TypeScript interfaces and types for the module's methods, parameters, and return values.
Installation
Install the Base44 SDK:
bash1npm install @base44/sdk
Important: Never assume or hardcode the @base44/sdk package version. Always install without a version specifier to get the latest version.
Creating a Client (External Apps)
When creating a client in external apps, ALWAYS use appId as the parameter name:
javascript1import { createClient } from "@base44/sdk"; 2 3// ✅ CORRECT 4const base44 = createClient({ appId: "your-app-id" }); 5 6// ❌ WRONG - Do NOT use these: 7// const base44 = createClient({ clientId: "your-app-id" }); // WRONG 8// const base44 = createClient({ id: "your-app-id" }); // WRONG
Required parameter: appId (string) - Your Base44 application ID
Optional parameters:
token(string) - Pre-authenticated user tokenoptions(object) - Configuration optionsoptions.onError(function) - Global error handler
Example with error handler:
javascript1const base44 = createClient({ 2 appId: "your-app-id", 3 options: { 4 onError: (error) => { 5 console.error("Base44 error:", error); 6 } 7 } 8});
Module Selection
Working with app data?
- Create/read/update/delete records →
entities - Import data from file →
entities.importEntities() - Realtime updates →
entities.EntityName.subscribe()
User management?
- Login/register/logout →
auth - Get current user →
auth.me() - Update user profile →
auth.updateMe() - Invite users →
users.inviteUser()
AI features?
- Chat with AI agents →
agents(requires logged-in user) - Create new conversation →
agents.createConversation() - Manage conversations →
agents.getConversations() - Generate text/JSON with AI →
integrations.Core.InvokeLLM() - Generate images →
integrations.Core.GenerateImage()
Custom backend logic?
- Run server-side code →
functions.invoke() - Need admin access →
base44.asServiceRole.functions.invoke()
External services?
- Send emails →
integrations.Core.SendEmail() - Upload files →
integrations.Core.UploadFile() - Custom APIs →
integrations.custom.call() - OAuth tokens (Google, Slack) →
connectors(backend only)
Tracking and analytics?
- Track custom events →
analytics.track() - Log page views/activity →
appLogs.logUserInApp()
Common Patterns
Filter and Sort Data
javascript1const pendingTasks = await base44.entities.Task.filter( 2 { status: "pending", assignedTo: userId }, // query 3 "-created_date", // sort (descending) 4 10, // limit 5 0 // skip 6);
Protected Routes (check auth)
javascript1const user = await base44.auth.me(); 2if (!user) { 3 // Navigate to your custom login page 4 navigate('/login', { state: { returnTo: window.location.pathname } }); 5 return; 6}
Backend Function Call
javascript1// Frontend 2const result = await base44.functions.invoke("processOrder", { 3 orderId: "123", 4 action: "ship" 5}); 6 7// Backend function (Deno) 8import { createClientFromRequest } from "npm:@base44/sdk"; 9 10Deno.serve(async (req) => { 11 const base44 = createClientFromRequest(req); 12 const { orderId, action } = await req.json(); 13 // Process with service role for admin access 14 const order = await base44.asServiceRole.entities.Orders.get(orderId); 15 return Response.json({ success: true }); 16});
Service Role Access
Use asServiceRole in backend functions for admin-level operations:
javascript1// User mode - respects permissions 2const myTasks = await base44.entities.Task.list(); 3 4// Service role - full access (backend only) 5const allTasks = await base44.asServiceRole.entities.Task.list(); 6const token = await base44.asServiceRole.connectors.getAccessToken("slack");
Frontend vs Backend
| Capability | Frontend | Backend |
|---|---|---|
entities (user's data) | Yes | Yes |
auth | Yes | Yes |
agents | Yes | Yes |
functions.invoke() | Yes | Yes |
integrations | Yes | Yes |
analytics | Yes | Yes |
appLogs | Yes | Yes |
users | Yes | Yes |
asServiceRole.* | No | Yes |
connectors | No | Yes |
Backend functions use Deno.serve() and createClientFromRequest(req) to get a properly authenticated client.