React Native Vibe Code SDK
Packages

@react-native-vibe-code/convex

Convex backend integration and provisioning for React Native Vibe Code

Overview

This package provides complete Convex integration:

  • Project Provisioning: OAuth and team-scoped token provisioning
  • Environment Management: Set and query environment variables
  • Authentication Setup: JWT/JWKS key generation
  • Sandbox Integration: Dev server management in E2B sandboxes
  • Management API: Full Convex dashboard API integration

Installation

pnpm add @react-native-vibe-code/convex

Configuration

Environment Variables

# Team-scoped token for managed provisioning
CONVEX_TEAM_SCOPED_TOKEN=your_team_token
CONVEX_TEAM_SLUG=your_team_slug

# Optional API endpoints
PROVISION_HOST=https://api.convex.dev      # Default
DASHBOARD_HOST=https://dashboard.convex.dev # Default

Usage

Use platform-managed provisioning with team-scoped tokens:

import { provisionManagedConvexProject } from '@react-native-vibe-code/convex'

const project = await provisionManagedConvexProject({
  teamScopedToken: process.env.CONVEX_TEAM_SCOPED_TOKEN,
  teamSlug: process.env.CONVEX_TEAM_SLUG,
  projectName: 'my-new-project'
})

console.log('Deployment URL:', project.deploymentUrl)
console.log('Admin Key:', project.adminKey)

OAuth Provisioning

For user-owned Convex projects:

import {
  getOAuthAuthorizeUrl,
  exchangeOAuthCode,
  provisionConvexProject
} from '@react-native-vibe-code/convex'

// Step 1: Get authorization URL
const authUrl = getOAuthAuthorizeUrl({
  clientId: 'your-client-id',
  redirectUri: 'https://your-app.com/callback',
  state: 'optional-state'
})
// Redirect user to authUrl

// Step 2: Exchange code for token
const tokens = await exchangeOAuthCode({
  code: authorizationCode,
  clientId: 'your-client-id',
  clientSecret: 'your-secret',
  redirectUri: 'https://your-app.com/callback'
})

// Step 3: Provision project
const project = await provisionConvexProject({
  accessToken: tokens.access_token,
  teamSlug: 'user-team',
  projectName: 'my-project',
  clientId: 'your-client-id',
  clientSecret: 'your-secret'
})

Environment Variables

import {
  setEnvVariables,
  queryEnvVariable,
  initializeConvexAuth
} from '@react-native-vibe-code/convex'

// Set variables
await setEnvVariables(project, {
  API_KEY: 'secret-key',
  DATABASE_URL: 'https://...'
})

// Query variable
const value = await queryEnvVariable(project, 'API_KEY')

// Initialize auth (generates JWT keys)
await initializeConvexAuth(project, 'https://your-site.com')
// Sets: SITE_URL, JWKS, JWT_PRIVATE_KEY

Sandbox Integration

import {
  updateSandboxEnvFile,
  startConvexDevServer,
  restoreConvexEnvToSandbox
} from '@react-native-vibe-code/convex'

// Update sandbox .env.local
await updateSandboxEnvFile(sandbox, 'EXPO_PUBLIC_CONVEX_URL', deploymentUrl)

// Start dev server in sandbox
const success = await startConvexDevServer(sandbox, projectId, {
  adminKey: project.adminKey,
  deploymentUrl: project.deploymentUrl
})

// Restore from database on sandbox restart
const restored = await restoreConvexEnvToSandbox(sandbox, projectId)

API Reference

Managed API

// Create managed project
createManagedProject(params: {
  teamScopedToken: string
  teamSlug: string
  projectName: string
  deploymentType?: 'dev' | 'prod'
}): Promise<CreateProjectResponse>

// Provision deployment
provisionManagedDeployment(params: {
  teamScopedToken: string
  teamSlug: string
  projectSlug: string
  deploymentType?: 'dev' | 'prod'
}): Promise<DeploymentProvisionResponse>

// Complete workflow
provisionManagedConvexProject(params: {
  teamScopedToken: string
  teamSlug: string
  projectName: string
}): Promise<ConvexProject>

// Delete project
deleteManagedProject(params: {
  teamScopedToken: string
  projectId: number
}): Promise<void>

OAuth API

// Get auth URL
getOAuthAuthorizeUrl(params: {
  clientId: string
  redirectUri: string
  state?: string
  scope?: string
}): string

// Exchange code
exchangeOAuthCode(params: {
  code: string
  clientId: string
  clientSecret: string
  redirectUri: string
}): Promise<OAuthTokenResponse>

// Create project
createConvexProject(params: {
  accessToken: string
  teamSlug: string
  projectName: string
  deploymentType?: 'dev' | 'prod'
}): Promise<CreateProjectResponse>

// Full provisioning
provisionConvexProject(params: {
  accessToken: string
  teamSlug: string
  projectName: string
  clientId: string
  clientSecret: string
}): Promise<ConvexProject>

Environment API

// Query variable with retries
queryEnvVariableWithRetries(
  project: ConvexProject,
  name: string,
  maxRetries?: number,
  retryDelay?: number
): Promise<string | null>

// Set variables with retries
setEnvVariablesWithRetries(
  project: ConvexProject,
  variables: Record<string, string>,
  maxRetries?: number,
  retryDelay?: number
): Promise<void>

// Generate auth keys
generateAuthKeys(): Promise<{
  JWT_PRIVATE_KEY: string,
  JWKS: { keys: any[] }
}>

Sandbox API

// Update .env.local in sandbox
updateSandboxEnvFile(
  sandbox: Sandbox,
  key: string,
  value: string,
  filePath?: string
): Promise<void>

// Get credentials from database
getConvexCredentials(projectId: string): Promise<ConvexCredentials | null>

// Restore environment to sandbox
restoreConvexEnvToSandbox(sandbox: Sandbox, projectId: string): Promise<boolean>

// Start dev server
startConvexDevServer(
  sandbox: Sandbox,
  projectId: string,
  credentials: { adminKey: string; deploymentUrl: string }
): Promise<boolean>

Types

interface ConvexProject {
  token: string          // Admin key
  deploymentName: string
  deploymentUrl: string
  projectSlug: string
  teamSlug: string
}

interface ConvexProjectState {
  kind: 'connected' | 'connecting' | 'failed'
  // When connected:
  projectSlug?: string
  teamSlug?: string
  deploymentUrl?: string
  deploymentName?: string
  warningMessage?: string
  // When failed:
  errorMessage?: string
}

interface CreateProjectResponse {
  projectSlug: string
  projectId: number
  teamSlug: string
  deploymentName: string
  prodUrl: string       // Actually dev URL
  adminKey: string
  projectsRemaining: number
}

interface OAuthTokenResponse {
  access_token: string
  token_type: 'bearer'
  expires_in?: number
  refresh_token?: string
}

interface ConvexEnvVar {
  name: string
  value: string
}

Database Integration

The package stores credentials in the database:

convex_project_credentials table:

  • projectId - UUID
  • userId - string
  • mode - 'oauth' | 'managed'
  • teamSlug, projectSlug - Convex identifiers
  • deploymentUrl, deploymentName - Deployment info
  • adminKey, accessToken - Credentials
  • createdAt, updatedAt - Timestamps

Error Handling

// Handle quota errors
try {
  await createManagedProject(params)
} catch (error) {
  if (error.message.includes('ProjectQuotaReached')) {
    // Handle plan limit
  }
}

// Retry pattern
await queryEnvVariableWithRetries(project, 'KEY', 3, 500)
// Retries 3 times with 500ms delay

Package Structure

packages/convex/
├── src/
│   ├── index.ts              # Main exports
│   ├── types.ts              # Type definitions
│   ├── env-variables.ts      # Environment management
│   ├── management-api.ts     # Managed API functions
│   ├── provisioning.ts       # OAuth provisioning
│   └── sandbox-utils.ts      # Sandbox integration
├── package.json
└── tsconfig.json

Dependencies

  • @e2b/code-interpreter - Sandbox operations
  • @react-native-vibe-code/database - Credential storage
  • @react-native-vibe-code/pusher - Error notifications
  • @react-native-vibe-code/error-manager - Error handling

On this page