Supabase Best Practices Guide

6/30/2025

このガイドは、Supabase 開発のベストプラクティスを詳述しています。コードの組織化、一般的なパターン、パフォーマンス、セキュリティ、テスト、ツールなどの分野をカバーしています。また、一般的な落とし穴についても警告し、データベースのワークフロー設計や追加のベストプラクティスに関するアドバイスを提供し、堅牢で拡張可能かつ安全なアプリケーションを構築するための助けとなります。


# Supabase Best Practices: A Comprehensive Guide

This document outlines best practices for developing with Supabase, covering various aspects from code organization to security and performance.

## 1. Code Organization and Structure

A well-organized codebase is crucial for maintainability and scalability. Here's how to structure your Supabase project:

### 1.1. Directory Structure Best Practices

Adopt a modular structure that separates concerns:


project-root/
├── src/
│   ├── components/        # Reusable UI components
│   ├── pages/             # Page-level components (routes)
│   ├── services/          # Supabase client initialization and data fetching
│   │   ├── supabase.ts   # Supabase client initialization
│   │   ├── auth.ts       # Authentication-related functions
│   │   ├── database.ts   # Database interaction functions
│   ├── utils/             # Utility functions (e.g., date formatting)
│   ├── types/             # TypeScript types and interfaces
│   ├── hooks/             # Custom React hooks
│   ├── styles/            # Global styles and theme
│   └── App.tsx            # Main application component
├── migrations/        # Database migrations
├── tests/              # Unit and integration tests
├── .env                # Environment variables
└── package.json          # Project dependencies


### 1.2. File Naming Conventions

*   **Components:** Use PascalCase (e.g., `UserProfile.tsx`).
*   **Functions:** Use camelCase (e.g., `fetchUserData`).
*   **Variables:** Use camelCase (e.g., `userName`).
*   **Files:** Use kebab-case (e.g., `user-profile.tsx`).

### 1.3. Module Organization

*   Group related functionalities into modules.
*   Use clear and descriptive module names.
*   Export only what is necessary from each module to minimize the API surface.

### 1.4. Component Architecture

*   Favor small, reusable components.
*   Use a component-based approach (e.g., React, Vue.js) to build UIs.
*   Separate presentational components from container components to improve reusability and testability.

### 1.5. Code Splitting Strategies

*   Use dynamic imports to lazy-load modules.
*   Split large components into smaller chunks.
*   Implement route-based code splitting to load only the necessary code for each route.

## 2. Common Patterns and Anti-patterns

### 2.1. Design Patterns Specific to Supabase

*   **Repository Pattern:** Abstract database interactions behind a repository interface for better testability and maintainability.
*   **Observer Pattern:** Utilize Supabase's real-time capabilities to implement reactive UIs.

### 2.2. Recommended Approaches for Common Tasks

*   **Data Fetching:** Create reusable functions for fetching data from Supabase tables.
*   **Authentication:** Use Supabase Auth for user authentication and authorization.
*   **Real-time Updates:** Leverage Supabase Realtime for real-time data synchronization.
*   **File Storage:** Utilize Supabase Storage for managing file uploads and downloads.

### 2.3. Anti-patterns and Code Smells to Avoid

*   **Direct Database Access from UI Components:** This tightly couples the UI to the database and makes testing difficult. Use a service layer to abstract database interactions.
*   **Overusing Supabase Functions and Policies:** Keep business logic in your application code whenever possible to avoid vendor lock-in and improve testability.
*   **Manually Creating Tables Without an ORM:** Always use an ORM to manage your database schema and migrations.
*   **Ignoring Error Handling:** Implement proper error handling to prevent unexpected crashes and provide informative error messages to users.
*   **Storing Sensitive Data in Plain Text:** Never store sensitive data like passwords or API keys in plain text. Use encryption and secure storage mechanisms.

### 2.4. State Management Best Practices

*   Choose a state management library (e.g., Redux, Zustand, Recoil) based on your project's complexity.
*   Use local component state for simple UI state.
*   Centralize application state in a global store for complex data dependencies.
*   Use asynchronous actions to handle data fetching and updates.

### 2.5. Error Handling Patterns

*   Use try-catch blocks to handle exceptions.
*   Implement a global error handler to catch unhandled exceptions.
*   Log errors to a monitoring service for tracking and analysis.
*   Display user-friendly error messages to the user.

## 3. Performance Considerations

### 3.1. Optimization Techniques

*   **Indexing:** Add indexes to frequently queried columns to improve query performance.
*   **Query Optimization:** Use efficient SQL queries and avoid N+1 query problems.
*   **Caching:** Implement caching strategies to reduce database load.
*   **Connection Pooling:** Use connection pooling to reuse database connections and reduce overhead.

### 3.2. Memory Management

*   Avoid memory leaks by properly cleaning up resources.
*   Use garbage collection to reclaim unused memory.
*   Optimize data structures to reduce memory usage.

### 3.3. Rendering Optimization

*   Use memoization techniques to prevent unnecessary re-renders.
*   Virtualize long lists to improve rendering performance.
*   Optimize images and other assets to reduce file sizes.

### 3.4. Bundle Size Optimization

*   Use tree shaking to remove unused code.
*   Minify code to reduce file sizes.
*   Compress assets to reduce transfer times.

### 3.5. Lazy Loading Strategies

*   Lazy load images and other assets that are not immediately visible.
*   Implement infinite scrolling to load data in chunks as the user scrolls.
*   Use code splitting to load only the necessary code for each route.

## 4. Security Best Practices

### 4.1. Common Vulnerabilities and How to Prevent Them

*   **SQL Injection:** Prevent SQL injection by using parameterized queries and prepared statements.
*   **Cross-Site Scripting (XSS):** Sanitize user input to prevent XSS attacks.
*   **Cross-Site Request Forgery (CSRF):** Implement CSRF protection to prevent unauthorized requests.
*   **Authentication and Authorization Issues:** Secure your authentication and authorization mechanisms to prevent unauthorized access.

### 4.2. Input Validation

*   Validate all user input to prevent malicious data from entering your system.
*   Use server-side validation in addition to client-side validation.
*   Sanitize user input to remove potentially harmful characters.

### 4.3. Authentication and Authorization Patterns

*   Use Supabase Auth for user authentication and authorization.
*   Implement role-based access control (RBAC) to manage user permissions.
*   Use row-level security (RLS) to control data access at the row level.

### 4.4. Data Protection Strategies

*   Encrypt sensitive data at rest and in transit.
*   Use secure storage mechanisms to store API keys and other secrets.
*   Implement data masking to protect sensitive data from unauthorized access.

### 4.5. Secure API Communication

*   Use HTTPS to encrypt API traffic.
*   Implement API rate limiting to prevent abuse.
*   Validate API requests to prevent malicious input.

## 5. Testing Approaches

### 5.1. Unit Testing Strategies

*   Write unit tests for individual functions and components.
*   Use mocking and stubbing to isolate units of code.
*   Aim for high code coverage.

### 5.2. Integration Testing

*   Write integration tests to verify the interaction between different parts of your system.
*   Test the integration between your application and Supabase.

### 5.3. End-to-end Testing

*   Write end-to-end tests to simulate user interactions and verify the overall functionality of your application.
*   Use tools like Cypress or Playwright to automate end-to-end tests.

### 5.4. Test Organization

*   Organize tests into separate directories based on functionality.
*   Use descriptive test names.
*   Keep tests concise and focused.

### 5.5. Mocking and Stubbing

*   Use mocking to replace external dependencies with controlled substitutes.
*   Use stubbing to replace specific method calls with predefined values.
*   Avoid over-mocking, as it can make tests less reliable.

## 6. Common Pitfalls and Gotchas

### 6.1. Frequent Mistakes Developers Make

*   Not using an ORM for database schema management.
*   Over-relying on Supabase functions and policies for business logic.
*   Using Supabase-only features without considering open-source alternatives.
*   Ignoring error handling and security best practices.

### 6.2. Edge Cases to Be Aware Of

*   Handling large datasets efficiently.
*   Dealing with real-time data synchronization conflicts.
*   Managing user sessions and authentication tokens securely.

### 6.3. Version-Specific Issues

*   Be aware of breaking changes in Supabase and its dependencies.
*   Test your application thoroughly after upgrading Supabase or its dependencies.
*   Refer to the Supabase documentation for migration guides.

### 6.4. Compatibility Concerns

*   Ensure compatibility between your application and the Supabase client library.
*   Test your application on different browsers and devices.

### 6.5. Debugging Strategies

*   Use browser developer tools to debug client-side code.
*   Use server-side logging to track errors and performance issues.
*   Use the Supabase dashboard to monitor database activity.

## 7. Tooling and Environment

### 7.1. Recommended Development Tools

*   Supabase CLI: For local development and database management.
*   VS Code: For code editing and debugging.
*   Drizzle ORM: For database schema management.
*   Postman/Insomnia: For testing API endpoints.

### 7.2. Build Configuration

*   Use a build tool like Webpack or Parcel to bundle your code.
*   Configure your build tool to optimize for production.
*   Use environment variables to configure your application.

### 7.3. Linting and Formatting

*   Use ESLint to enforce code style and prevent errors.
*   Use Prettier to format your code automatically.
*   Integrate linting and formatting into your development workflow.

### 7.4. Deployment Best Practices

*   Use a CI/CD pipeline to automate deployments.
*   Deploy your application to a production-ready environment.
*   Monitor your application for errors and performance issues.

### 7.5. CI/CD Integration

*   Use a CI/CD tool like GitHub Actions or GitLab CI to automate your build, test, and deployment processes.
*   Configure your CI/CD pipeline to run tests and linting before deployment.
*   Use environment variables to configure your application in the CI/CD environment.

## 8. Database Workflow Design

*   **Avoid Direct Changes in Production**: Once your application is live, refrain from making database changes using the Supabase Dashboard. Instead, utilize migration tools and enforce access control to prevent unauthorized modifications.
*   **Multiple Environments**: Adopt a multi-stage development workflow (`local -> staging -> prod`). This approach allows for thorough testing and validation at each stage before changes are deployed to production.
*   **Point-in-Time Recovery**: As your database grows, consider moving to Point-in-Time Recovery (PITR) to minimize the impact on database performance during maintenance and ensure data safety.
*   **Database Migrations**: Use database migration tools to manage schema changes. This practice helps maintain consistency across different environments and simplifies version control.
*   **Access Control**: Be mindful of who has access to your production environment. Limit access to experienced team members and set clear internal workflows to mitigate risks.
*   **Security**: Regularly review and update your security measures. Ensure that tables with sensitive data have appropriate access levels and that database secrets and API keys are stored securely.
*   **Performance Monitoring**: Utilize Supabase's observability tooling to monitor database performance and optimize queries, indexes, and connection management.

## 9. Additional Best Practices

*   **Understand Shared Responsibilities:** When using Supabase, be aware of the shared responsibilities model. Supabase manages infrastructure, but you are responsible for application architecture, security, and data management.
*   **Proper Indexing:** Essential for query optimization. Indices should be created based on common query patterns to reduce search time.
*   **Load Testing**: Before deploying changes to production, perform load testing in a staging environment. Tools such as `k6` can simulate traffic and help identify potential bottlenecks.
*   **Resource Upgrades**: Monitor resource usage and upgrade your database when necessary. For significant traffic surges, contact support in advance for assistance.
*   **Database Optimization**: Regularly optimize your database by adding filters on large queries, using caching strategies, and managing connections efficiently.
*   **Regular Backups:** Schedule regular backups of your database to protect against data loss.
*   **Use of Postgres Features**: As Supabase is built around Postgres, understand and leverage Postgres features for performance and scalability.

## 10. Conclusion

By following these best practices, you can build robust, scalable, and secure applications with Supabase. Remember to stay up-to-date with the latest Supabase documentation and community resources to continuously improve your development practices.

@file ./supabase_code_examples.mdc