Complete API documentation for @gridatek/nx-supabase
Generators are used to scaffold new projects and configurations.
Initializes the @gridatek/nx-supabase plugin in your workspace.
Usage:
npx nx g @gridatek/nx-supabase:init [options]Options:
| Option | Type | Default | Description |
|---|---|---|---|
--skipPackageJson |
boolean |
false |
Skip adding Supabase CLI to package.json devDependencies |
What it does:
- Adds
supabaseCLI (^2.65.6) to devDependencies (unless--skipPackageJsonis true) - Registers
@gridatek/nx-supabaseplugin innx.json - Returns a callback to install dependencies
Example:
# Standard initialization
npx nx g @gridatek/nx-supabase:init
# Skip package.json modification (manual Supabase CLI installation)
npx nx g @gridatek/nx-supabase:init --skipPackageJsonNotes:
- This generator is automatically run when using
nx add @gridatek/nx-supabase - The plugin won't be added twice if it already exists in
nx.json
Creates a new Supabase project in your workspace.
Usage:
npx nx g @gridatek/nx-supabase:project <name> [options]Arguments:
| Argument | Type | Required | Description |
|---|---|---|---|
name |
string |
Yes | The name of the Supabase project |
Options:
| Option | Type | Default | Description |
|---|---|---|---|
--directory |
string |
project name | Directory where the project will be created. Defaults to project name if not specified |
--environments |
string |
undefined |
Comma-separated list of additional environments to create (beyond production and local) |
What it creates:
<project-root>/
├── production/ # Base configuration (always created)
│ └── config.toml # Supabase configuration (generated by callback)
├── local/ # Local environment (always created, empty)
├── [additional-envs]/ # Any additional environments specified (empty)
├── .generated/ # Build output directory
│ └── .gitkeep
├── .gitignore # Ignores .generated/
├── README.md # Project documentation
└── project.json # Nx project configuration
Note: The generator creates empty environment directories. Users create migrations/ and seeds/ subdirectories as needed.
Examples:
# Basic project (defaults to project name as directory in the root)
npx nx g @gridatek/nx-supabase:project my-supabase
# Creates at: my-supabase/ (in the root)
# Custom directory (project name ≠ folder name)
npx nx g @gridatek/nx-supabase:project my-supabase --directory=apps/backend/supabase
# Creates at: apps/backend/supabase/
# Run with: nx run my-supabase:start
# Or match folder name to project name
npx nx g @gridatek/nx-supabase:project my-supabase --directory=apps/my-api/my-supabase
# Creates at: apps/my-api/my-supabase/
# With additional environments
npx nx g @gridatek/nx-supabase:project my-supabase \
--directory=apps/backend/supabase \
--environments=staging,qa,dev
# Creates at: apps/backend/supabase/
Environment Behavior:
- production and local are always created by default
- Use
--environmentsto add additional environments like staging, qa, dev, etc. - If you specify
productionorlocalin--environments, they will be filtered out (no duplicates)
Project Configuration:
Creates a project.json with:
{
"name": "my-supabase",
"root": "my-supabase",
"projectType": "application",
"sourceRoot": "my-supabase"
}Targets (build, start, stop, run-command) are inferred by the plugin, not explicitly defined.
Executors are used to run tasks on your Supabase projects.
Builds environment configurations by merging production config with environment-specific files.
Usage:
npx nx run <project>:buildSchema:
interface BuildExecutorSchema {
// No options - configuration is derived from project structure
}Behavior:
- Locates the project root from Nx context
- Finds all environment directories (excludes
.generated/and hidden directories) - For each environment except production:
- Cleans
.generated/<env>/directory - Copies files from
production/(base configuration) - Overlays files from
<env>/(environment-specific overrides) - Skips
.gitkeepfiles
- Cleans
- All environments are built to
.generated/<env>/supabase/
Output:
.generated/<env>/supabase/for all environments- Cached by Nx for faster rebuilds
Inputs (for caching):
- All files in environment directories:
{projectRoot}/<env>/**/*
Outputs (for caching):
{projectRoot}/.generated
Example:
# Build all environments
npx nx run my-api:build
# Build with verbose logging
npx nx run my-api:build --verbose
# Clear cache and rebuild
npx nx run my-api:build --skip-nx-cacheNotes:
- Automatically runs before
starttarget (viadependsOn) - Uses Nx caching for fast incremental builds
- Safe to run multiple times (cleans before building)
Starts a Supabase instance using the Supabase CLI.
Usage:
npx nx run <project>:start [options]Schema:
interface StartExecutorSchema {
env?: string; // Default: 'local'
}Options:
| Option | Type | Default | Description |
|---|---|---|---|
--env |
string |
'local' |
Environment to use (local, production, staging, etc.) |
Behavior:
- Runs
buildtarget first (viadependsOn) - Determines working directory:
- All environments: Uses
.generated/<env>/supabase/
- All environments: Uses
- Validates that
config.tomlexists - Executes
supabase startin the appropriate directory - Streams output to console
- Waits for process to complete
Examples:
# Start with default local environment
npx nx run my-api:start
# Start with production configuration
npx nx run my-api:start --env=production
# Start with staging environment
npx nx run my-api:start --env=stagingNotes:
- Requires Docker to be running
- First run may take several minutes to download Docker images
- Process runs in foreground by default
- Use
Ctrl+Cto stop, or use thestoptarget
Error Handling:
- Returns
{ success: false }if environment directory doesn't exist - Suggests running
buildtarget if.generated/<env>is missing - Returns exit code from Supabase CLI
Stops a running Supabase instance.
Usage:
npx nx run <project>:stop [options]Schema:
interface StopExecutorSchema {
env?: string; // Default: 'local'
}Options:
| Option | Type | Default | Description |
|---|---|---|---|
--env |
string |
'local' |
Environment to stop (local, production, staging, etc.) |
Behavior:
- Determines working directory (same logic as
start) - Validates environment exists
- Executes
supabase stop --no-backupin the appropriate directory - Streams output to console
Examples:
# Stop local environment
npx nx run my-api:stop
# Stop production environment
npx nx run my-api:stop --env=productionNotes:
- Uses
--no-backupflag to avoid creating database dumps - Safe to run even if Supabase is not running
- Stops Docker containers for the specific project
Generates TypeScript types from your Supabase database schema.
Usage:
npx nx run <project>:gen-types [options]Schema:
interface GenTypesExecutorSchema {
projectId?: string; // Remote project ID (if not provided, uses local)
outputPath?: string; // Output file path (default: 'database.types.ts')
schema?: string; // Comma-separated list of schemas (e.g., 'public,auth')
}Options:
| Option | Type | Default | Description |
|---|---|---|---|
--projectId |
string |
- | Supabase project ID. If not provided, generates types from local database |
--outputPath |
string |
'database.types.ts' |
Output file path relative to workspace root |
--schema |
string |
- | Comma-separated list of schemas to include (e.g., 'public,auth') |
Behavior:
- Runs
buildtarget first (viadependsOn) - Determines mode based on
projectId:- Local mode (no projectId): Uses
.generated/local/supabase/directory - Remote mode (with projectId): Uses project root directory
- Local mode (no projectId): Uses
- Validates environment directory exists (local mode only)
- Executes
supabase gen types typescriptwith appropriate flags - Captures stdout and writes to output file
- Creates output directory if needed
Examples:
# Generate types from local database (default)
npx nx run my-api:gen-types
# Generate types with custom output path
npx nx run my-api:gen-types --outputPath=src/types/database.types.ts
# Generate types from remote project
npx nx run my-api:gen-types --projectId=abcdefghijklmnop
# Generate types for specific schemas
npx nx run my-api:gen-types --schema=public,auth
# Combine options
npx nx run my-api:gen-types \
--projectId=abcdefghijklmnop \
--outputPath=libs/shared/types/src/database.types.ts \
--schema=publicNotes:
- For local mode, ensure Supabase is running (
nx run <project>:start) - For remote mode, ensure you're authenticated (
supabase login) - Output file is relative to workspace root, not project root
- The executor automatically creates parent directories if they don't exist
Error Handling:
- Returns
{ success: false }if local environment doesn't exist - Suggests running
buildtarget if.generated/localis missing - Returns failure if Supabase CLI command fails
Runs any arbitrary Supabase CLI command in the appropriate environment context.
Usage:
npx nx run <project>:run-command --command="<supabase-command>" [options]Schema:
interface RunCommandExecutorSchema {
command: string | string[]; // Required: Supabase CLI command to run
env?: string; // Default: 'local'
}Options:
| Option | Type | Default | Required | Description |
|---|---|---|---|---|
--command |
string or string[] |
- | Yes | Supabase CLI command to execute |
--env |
string |
'local' |
No | Environment context (local, production, staging, etc.) |
Behavior:
- Determines working directory based on environment
- Validates environment directory and config exist
- Parses command string (or joins array)
- Executes command via
npxin shell mode - Streams stdout/stderr to console
- Returns success/failure based on exit code
Examples:
# Check status
npx nx run my-api:run-command --command="supabase status"
# Create a new migration
npx nx run my-api:run-command --command="supabase migration new create_users"
# Reset database
npx nx run my-api:run-command --command="supabase db reset"
# Run migration up
npx nx run my-api:run-command --command="supabase db push"
# With specific environment
npx nx run my-api:run-command \
--env=staging \
--command="supabase db diff --use-migra"
# Array format (useful in project.json)
npx nx run my-api:run-command \
--command="['supabase', 'migration', 'new', 'my_table']"Common Commands:
| Command | Description |
|---|---|
supabase status |
Show status of all services |
supabase start |
Start Supabase (prefer using start target) |
supabase stop |
Stop Supabase (prefer using stop target) |
supabase db reset |
Reset database to initial state |
supabase db push |
Apply pending migrations |
supabase db diff |
Show SQL diff |
supabase migration new <name> |
Create new migration |
supabase gen types typescript |
Generate TypeScript types (prefer using gen-types executor) |
supabase functions new <name> |
Create new Edge Function |
supabase link --project-ref <ref> |
Link to remote project |
Notes:
- Runs in shell mode, so shell operators (pipes, redirects) are supported
- Working directory is set to environment directory
- All Supabase CLI commands available
- Return value indicates success/failure of command
Pushes all SQL files in db_functions/ to a Postgres database. Intended for idempotent definitions (CREATE OR REPLACE FUNCTION, CREATE OR REPLACE VIEW, RLS policy resets, etc.) that you want re-applied on every deploy without creating a migration.
Unlike supabase db query --file, this executor uses the pg driver's simple-query protocol, so files containing multiple statements — including function bodies with $$ ... $$ delimiters — are supported.
Usage:
npx nx run <project>:push-db-functions [options]Schema:
interface PushDbFunctionsExecutorSchema {
env?: string; // Default: 'local'
functionsDir?: string; // Override directory (relative to workspace root or absolute)
dbUrl?: string; // Postgres connection string
}Options:
| Option | Type | Default | Description |
|---|---|---|---|
--env |
string |
'local' |
Environment to use. The executor reads SQL from .generated/<env>/supabase/db_functions/ |
--functionsDir |
string |
— | Override directory containing .sql files. Relative paths resolve from the workspace root |
--dbUrl |
string |
— | Postgres connection string. Overrides $SUPABASE_DB_URL and auto-discovery |
Behavior:
- Runs
buildtarget first (viadependsOn) - Resolves the functions directory (option override, else
.generated/<env>/supabase/db_functions/under project root) - Resolves the database URL in this order:
--dbUrloption$SUPABASE_DB_URLenv varsupabase status -o envin the environment directory (local mode)
- Collects
*.sqlfiles sorted alphabetically - Connects via
pg.Client, executes each file as a single simple query, closes the connection
Examples:
# Push local functions (auto-discovers DB URL from `supabase status`)
npx nx run my-api:push-db-functions
# Push to staging with explicit URL
SUPABASE_DB_URL="postgresql://..." npx nx run my-api:push-db-functions --env=staging
# Custom functions directory
npx nx run my-api:push-db-functions --functionsDir=custom/sql/CI Usage:
In GitHub Actions, pass the DB URL via a secret:
- name: Push database functions
run: npx nx run my-api:push-db-functions --env=production
env:
SUPABASE_DB_URL: ${{ secrets.SUPABASE_DB_URL }}Notes:
- Files are executed in alphabetical order — prefix them (
01_,02_) if ordering matters - Statements run outside an outer transaction, so each file is autonomous
- Keep these files idempotent (
CREATE OR REPLACE,DROP ... IF EXISTS); don't use for migrations
Error Handling:
- Returns
{ success: false }if the functions directory doesn't exist - Returns
{ success: false }if no DB URL can be resolved - Returns
{ success: false }on any SQL execution error (connection is closed in afinally)
Configure the plugin behavior in nx.json.
Schema:
interface SupabasePluginOptions {
buildTargetName?: string;
startTargetName?: string;
stopTargetName?: string;
runCommandTargetName?: string;
statusTargetName?: string;
dbResetTargetName?: string;
dbPushTargetName?: string;
dbPullTargetName?: string;
genTypesTargetName?: string;
genTypesOutputPath?: string;
migrationNewTargetName?: string;
linkTargetName?: string;
dbDiffTargetName?: string;
pushDbFunctionsTargetName?: string;
}Options:
| Option | Type | Default | Description |
|---|---|---|---|
buildTargetName |
string |
'build' |
Name of the build target |
startTargetName |
string |
'start' |
Name of the start target |
stopTargetName |
string |
'stop' |
Name of the stop target |
runCommandTargetName |
string |
'run-command' |
Name of the run-command target |
statusTargetName |
string |
'status' |
Name of the status target |
dbResetTargetName |
string |
'db-reset' |
Name of the db-reset target |
dbPushTargetName |
string |
'db-push' |
Name of the db-push target |
dbPullTargetName |
string |
'db-pull' |
Name of the db-pull target |
genTypesTargetName |
string |
'gen-types' |
Name of the gen-types target |
genTypesOutputPath |
string |
'database.types.ts' |
Default output path for generated types |
migrationNewTargetName |
string |
'migration-new' |
Name of the migration-new target |
linkTargetName |
string |
'link' |
Name of the link target |
dbDiffTargetName |
string |
'db-diff' |
Name of the db-diff target |
pushDbFunctionsTargetName |
string |
'push-db-functions' |
Name of the push-db-functions target |
Example Configuration:
{
"plugins": [
{
"plugin": "@gridatek/nx-supabase",
"options": {
"buildTargetName": "supabase-build",
"startTargetName": "supabase-start",
"stopTargetName": "supabase-stop",
"genTypesTargetName": "generate-types",
"genTypesOutputPath": "libs/shared/types/src/database.types.ts",
"runCommandTargetName": "supabase"
}
}
]
}Inferred Tasks:
The plugin uses createNodesV2 API to automatically infer tasks for projects that have a production/config.toml file.
Detection Pattern:
**/production/config.toml
Inferred Target Configuration:
For each detected project, the plugin creates:
{
build: {
executor: '@gridatek/nx-supabase:build',
cache: true,
inputs: [
'{projectRoot}/production/**/*',
'{projectRoot}/local/**/*',
'{projectRoot}/<other-envs>/**/*'
],
outputs: ['{projectRoot}/.generated']
},
start: {
executor: '@gridatek/nx-supabase:run-command',
options: { command: 'supabase start' },
dependsOn: ['build']
},
stop: {
executor: '@gridatek/nx-supabase:run-command',
options: { command: 'supabase stop --no-backup' }
},
'run-command': {
executor: '@gridatek/nx-supabase:run-command'
}
}Project Name Extraction:
The plugin extracts the project name from config.toml:
project_id = "my-project-name" # Used as Nx project nameThis allows projects without project.json to be automatically detected and integrated into the Nx graph.
Standard Nx executor context, provided by @nx/devkit:
interface ExecutorContext {
root: string;
cwd: string;
isVerbose: boolean;
projectName?: string;
projectsConfigurations?: {
projects: Record<string, ProjectConfiguration>;
version: number;
};
nxJsonConfiguration?: any;
projectGraph?: ProjectGraph;
}All executors return a Promise with success status:
interface ExecutorResult {
success: boolean;
}Common error scenarios and how to resolve them:
| Error | Cause | Solution |
|---|---|---|
| "No project name found in context" | Executor called without valid project context | Ensure you're using nx run <project>:target |
| "Project not found" | Project name doesn't exist in workspace | Check project name with nx show projects |
| "Production directory not found" | Missing production/ folder |
Run project generator or create manually |
| "Environment 'X' not found" | Specified environment doesn't exist | Run build target or create environment directory |
| "Config file not found" | Missing config.toml in environment |
Run build target or check config exists |
| "Supabase command failed with code X" | Supabase CLI error | Check Supabase CLI logs and Docker status |
Override inferred targets in project.json:
{
"name": "my-api",
"targets": {
"build": {
"executor": "@gridatek/nx-supabase:build"
},
"start:dev": {
"executor": "@gridatek/nx-supabase:run-command",
"options": {
"command": "supabase start",
"env": "local"
},
"dependsOn": ["build"]
},
"migrate": {
"executor": "@gridatek/nx-supabase:run-command",
"options": {
"command": "supabase db reset",
"env": "local"
}
},
"types": {
"executor": "@gridatek/nx-supabase:gen-types",
"options": {
"outputPath": "types/database.ts"
}
}
}
}Use executors programmatically in scripts:
import { ExecutorContext } from '@nx/devkit';
import buildExecutor from '@gridatek/nx-supabase/build';
async function customBuild(context: ExecutorContext) {
const result = await buildExecutor({}, context);
if (!result.success) {
throw new Error('Build failed');
}
}For more examples and patterns, see Best Practices and Advanced Usage.