Architecture

Environment Variables

Environment variables are global configuration values set during integration setup. They store sensitive information like API keys, configuration options, and settings that apply to the entire integration.

Key Characteristics

  • Global Scope: Available to all nodes and lifecycle hooks
  • Secure Storage: Sensitive values are encrypted and hidden
  • UI Configuration: Set through user-friendly controls during setup
  • Schema Validation: Support Standard Schema specification
  • Integration-Wide: Configured once, used everywhere

Basic Usage

import * as i from '@xentom/integration-framework';

export default i.integration({
  env: {
    API_KEY: i.env({
      control: i.controls.text({
        label: 'API Key',
        description: 'Your service API key',
        placeholder: 'sk-...',
        sensitive: true,
      }),
    }),

    DEBUG_MODE: i.env({
      control: i.controls.switch({
        label: 'Debug Mode',
        description: 'Enable debug logging',
        defaultValue: false,
      }),
    }),

    REGION: i.env({
      control: i.controls.select({
        label: 'Server Region',
        options: [
          { value: 'us-east-1', label: 'US East' },
          { value: 'eu-west-1', label: 'Europe West' },
        ],
        defaultValue: 'us-east-1',
      }),
    }),
  },

  nodes: {
    // Your nodes here
  },
});

Control Types

Text Input

For API keys, URLs, and string values:

API_KEY: i.env({
  control: i.controls.text({
    label: 'API Key',
    description: 'Your service API key for authentication',
    placeholder: 'Enter your API key...',
    sensitive: true, // Hides the value in UI
  }),
});

BASE_URL: i.env({
  control: i.controls.text({
    label: 'Base URL',
    description: 'API base URL',
    defaultValue: 'https://api.example.com',
  }),
});

Boolean Toggle

For feature flags and boolean settings:

ENABLE_CACHING: i.env({
  control: i.controls.switch({
    label: 'Enable Caching',
    description: 'Cache API responses for better performance',
    defaultValue: true,
  }),
});

STRICT_MODE: i.env({
  control: i.controls.switch({
    label: 'Strict Validation',
    description: 'Enable strict data validation',
    defaultValue: false,
  }),
});

For predefined options:

ENVIRONMENT: i.env({
  control: i.controls.select({
    label: 'Environment',
    description: 'Target deployment environment',
    options: [
      { value: 'development', label: 'Development' },
      { value: 'staging', label: 'Staging' },
      { value: 'production', label: 'Production' },
    ],
    defaultValue: 'development',
  }),
});

LOG_LEVEL: i.env({
  control: i.controls.select({
    label: 'Log Level',
    options: [
      { value: 'error', label: 'Error' },
      { value: 'warn', label: 'Warning' },
      { value: 'info', label: 'Info' },
      { value: 'debug', label: 'Debug' },
    ],
    defaultValue: 'info',
  }),
});

Schema Validation

Environment variables support schema validation using the Standard Schema specification. For comprehensive examples and detailed documentation, see Schema Validation.

import * as v from 'valibot';

API_KEY: i.env({
  control: i.controls.text({
    label: 'API Key',
    sensitive: true,
  }),
  schema: v.pipe(v.string(), v.startsWith('sk-'), v.minLength(10)),
});

Using Environment Variables

In Lifecycle Hooks

export default i.integration({
  env: {
    DATABASE_URL: i.env({
      control: i.controls.text({
        label: 'Database URL',
        sensitive: true,
      }),
    }),
  },

  async start({ state, env }) {
    // Use environment variables to initialize resources
    state.database = new Database(env.DATABASE_URL);
    await state.database.connect();
  },

  async stop({ state }) {
    await state.database.disconnect();
  },
});

Accessing in Nodes

Environment variables are not directly available in nodes. Instead, use them in lifecycle hooks to set up shared state:

export default i.integration({
  env: {
    API_KEY: i.env({
      control: i.controls.text({ sensitive: true }),
    }),
  },

  async start({ state, env }) {
    // Initialize API client with env variable
    state.apiClient = new ApiClient({
      apiKey: env.API_KEY,
    });
  },

  nodes: {
    fetchData: i.nodes.callable({
      outputs: {
        data: i.pins.data(),
      },

      async run({ next, state }) {
        // Use the client initialized with env variables
        const data = await state.apiClient.get('/data');
        next({ data });
      },
    }),
  },
});

Common Patterns

API Configuration

env: {
  API_KEY: i.env({
    control: i.controls.text({
      label: 'API Key',
      description: 'Your service API key',
      sensitive: true
    })
  }),

  API_URL: i.env({
    control: i.controls.text({
      label: 'API Base URL',
      description: 'Base URL for API requests',
      defaultValue: 'https://api.example.com'
    })
  }),

  TIMEOUT: i.env({
    control: i.controls.select({
      label: 'Request Timeout',
      options: [
        { value: '30', label: '30 seconds' },
        { value: '60', label: '1 minute' },
        { value: '300', label: '5 minutes' }
      ],
      defaultValue: '30'
    })
  })
}

Database Settings

env: {
  DATABASE_URL: i.env({
    control: i.controls.text({
      label: 'Database Connection String',
      description: 'PostgreSQL connection string',
      placeholder: 'postgresql://user:pass@localhost:5432/db',
      sensitive: true
    })
  }),

  MAX_CONNECTIONS: i.env({
    control: i.controls.select({
      label: 'Max Connections',
      options: [
        { value: '5', label: '5 connections' },
        { value: '10', label: '10 connections' },
        { value: '20', label: '20 connections' }
      ],
      defaultValue: '10'
    })
  })
}

Feature Flags

env: {
  ENABLE_RETRY: i.env({
    control: i.controls.switch({
      label: 'Enable Auto Retry',
      description: 'Automatically retry failed requests',
      defaultValue: true
    })
  }),

  USE_CACHE: i.env({
    control: i.controls.switch({
      label: 'Enable Caching',
      description: 'Cache responses to improve performance',
      defaultValue: false
    })
  })
}

Best Practices

Use Descriptive Names

// Good - Clear purpose
env: {
  SLACK_BOT_TOKEN: i.env({ /* ... */ }),
  WEBHOOK_SECRET: i.env({ /* ... */ }),
  MAX_RETRY_ATTEMPTS: i.env({ /* ... */ })
}

// Avoid - Generic names
env: {
  TOKEN: i.env({ /* ... */ }),
  SECRET: i.env({ /* ... */ }),
  CONFIG: i.env({ /* ... */ })
}

Mark Sensitive Data

// Good - Mark sensitive values
API_KEY: i.env({
  control: i.controls.text({
    label: 'API Key',
    sensitive: true, // Hides value in UI
  }),
});

Provide Defaults

// Good - Sensible defaults
TIMEOUT: i.env({
  control: i.controls.text({
    label: 'Timeout (seconds)',
    defaultValue: '30',
  }),
});

Use Validation

// Good - Validate important values
API_KEY: i.env({
  control: i.controls.text({
    label: 'API Key',
    sensitive: true,
  }),
  schema: v.pipe(v.string(), v.minLength(10)),
});

Environment variables provide secure, global configuration for your integrations while maintaining user-friendly setup experiences.

On this page