Kickstarting Development: Initial Environment Setup for NestJS with Supabase
The Problem
Starting a new project often begins with the tedious, yet critical, task of environment configuration. Inconsistent setups, missing variables, or differing local configurations can lead to frustrating "it works on my machine" scenarios, slowing down initial development and team onboarding. For our vive-tu-mente-preview project, we wanted to ensure a smooth and standardized kickoff.
The Approach
Our goal was to establish a clear, repeatable, and robust initial environment setup. This involved standardizing how we manage environment variables, integrate core services like Supabase, and ensure our NestJS application was ready for development from the first commit. The focus was on clarity, security, and developer experience.
Phase 1: Core Environment Variables
The first step involved defining a canonical set of environment variables needed for both local development and deployment. We opted for a .env file structure to manage these, ensuring sensitive information is kept out of source control. NestJS's ConfigModule is an excellent way to safely load and expose these variables throughout the application.
import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [
ConfigModule.forRoot({
isGlobal: true, // Makes the ConfigModule available everywhere
envFilePath: ['.env.development', '.env'], // Prioritize dev env
}),
],
})
export class AppConfigModule {}
This module ensures that our application loads configuration from a .env file, with .env.development taking precedence for local overrides, offering flexibility while maintaining a consistent base.
Phase 2: Integrating Supabase
With environment variables sorted, the next crucial step was integrating Supabase for our backend data needs. This involved setting up the Supabase client and ensuring its credentials (API URL and Anon Key) were correctly pulled from the environment variables. A dedicated module handles this connection, making it reusable and testable.
import { Module } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { createClient, SupabaseClient } from '@supabase/supabase-js';
@Module({
providers: [
{
provide: 'SUPABASE_CLIENT',
useFactory: (configService: ConfigService): SupabaseClient => {
const supabaseUrl = configService.get<string>('SUPABASE_URL');
const supabaseKey = configService.get<string>('SUPABASE_ANON_KEY');
return createClient(supabaseUrl, supabaseKey);
},
inject: [ConfigService],
},
],
exports: ['SUPABASE_CLIENT'],
})
export class SupabaseModule {}
This setup allows any part of our NestJS application to inject the SUPABASE_CLIENT and interact with our Supabase instance, leveraging the configured environment variables securely.
Key Insight
By prioritizing a structured approach to initial environment configuration and service integration, we significantly reduced setup friction. Standardizing .env usage and centralizing service client instantiation (like Supabase) ensures that all developers start from a consistent, secure, and ready-to-develop foundation, accelerating the project's initial velocity.
Generated with Gitvlg.com