While the default stack for full-stack web applications is Next.js, it's crucial to understand its trade-offs compared to a more focused client-side setup like Vite + React. This guide clarifies when to use each approach.
This combination pairs React, the premier UI library, with Vite, a best-in-class build tool.
- Architecture: Pure Single Page Application (SPA). The browser downloads a JavaScript bundle and renders the application locally. It is decoupled from the backend and communicates via API calls.
- Primary Strength: Unmatched Developer Experience (DX). Vite's near-instantaneous Hot Module Replacement (HMR) creates an extremely fast and fluid development workflow.
- Best For:
- Admin Dashboards & Internal Tools: Where SEO is irrelevant and users have long sessions.
- Complex Web Applications: Such as online editors or project management tools where dynamic interactivity is more critical than initial load time.
- Projects with a pre-existing, separate backend API.
Next.js is an opinionated, all-in-one framework that extends React to handle both frontend and backend concerns.
- Architecture: Full-stack with hybrid rendering capabilities. It can pre-render pages on the server before sending them to the client.
- Primary Strength: Performance & SEO. Server-Side Rendering (SSR) and Static Site Generation (SSG) provide fast initial page loads and make content easily indexable by search engines.
- Best For:
- Public-Facing Websites: Blogs, marketing sites, and e-commerce platforms where SEO is paramount.
- Content-Driven Applications: Where initial page load performance is a key user metric.
- Projects where an integrated frontend and backend (API routes) simplifies development.
Consideration | Choose Vite + React | Choose Next.js (Default) |
---|---|---|
Is SEO critical? | No | Yes |
Is it a public site? | No (e.g., internal dashboard) | Yes (e.g., blog, e-commerce) |
Primary Goal | Maximum developer velocity, complex client-side UI | Fast initial load, SEO, integrated full-stack |
Backend | A separate, dedicated API exists or is planned | Need to build API endpoints alongside the frontend |
This document outlines the core principles and actionable decisions for creating beautiful, responsive, and user-centric applications.
Before any specific design choice, adhere to these principles:
- Clarity: The user should always understand what they are seeing and what will happen when they take an action. Avoid ambiguity.
- Consistency: Elements that look the same should behave the same. A consistent design language reduces the cognitive load on the user, making the app feel intuitive.
- Simplicity: Less is more. Every element on the screen should serve a purpose. Aggressively remove clutter to focus the user's attention on what matters.
These three areas form the bedrock of your application's look and feel.
A. Layout & Spacing: Creating Rhythm and Hierarchy
A structured layout is the skeleton of a beautiful app.
- Use a Grid System: All layouts should be built on a grid (e.g., a 12-column grid is a web standard). This ensures alignment and a professional, organized look.
- Establish a Spacing Scale: Do not use random margin or padding values. Use a consistent scale based on a multiple of 4 or 8 (e.g., 4px, 8px, 12px, 16px, 24px, 32px). This creates a visual rhythm and makes components feel like they belong together.
- Decision: Use an 8-point grid system for all spacing and sizing.
- Embrace Whitespace: Whitespace (or negative space) is not empty space; it's a powerful design tool. Use it generously to group related items, separate unrelated ones, and give your content room to breathe.
B. Typography: The Voice of Your Application
Typography is 90% of design. Getting it right is critical for usability and aesthetics.
- Limit Font Families: Do not use more than two fonts in your application—one for headings (a "display" font) and one for body text (a "body" font). This ensures consistency and avoids a chaotic look.
- Decision: Use a clean, sans-serif font like Inter, Manrope, or the system UI font stack for maximum readability.
- Establish a Type Scale: Just like with spacing, define a clear hierarchy for text sizes (e.g., 12px, 14px, 16px, 20px, 24px, 32px). This visually communicates the importance of different pieces of information.
- Prioritize Readability:
- Line Height: Set body text line-height to ~1.5x the font size for comfortable reading.
- Line Length: Aim for 50-75 characters per line. Lines that are too long or too short are fatiguing to read.
C. Color Palette: Setting the Mood and Guiding the Eye
Color is used to create hierarchy, convey meaning, and establish a brand.
- Define a Structured Palette:
- Primary (1-2 colors): Your main brand colors. Used for primary actions and key elements.
- Secondary (1-2 colors): Complements the primary colors. Used for secondary actions and highlighting information.
- Neutrals (3-5 shades): Your grays and off-whites. Used for text, backgrounds, and borders. A good range of neutrals is essential for a clean UI.
- Semantic Colors (4 colors): Colors with specific meanings:
- Success (Green): For confirmations and positive feedback.
- Warning (Yellow/Orange): For potential issues or alerts.
- Error (Red): For validation errors and critical failures.
- Info (Blue): For informational messages.
- Check for Accessibility: Ensure all text has a sufficient contrast ratio against its background to be readable by users with visual impairments. Use a WCAG contrast checker tool.
- Decision: All text/background color combinations must pass WCAG AA standards.
- Design for States: A component is never static. Explicitly design for all its states: default, hover, focused, active, disabled, loading, and empty. This makes the UI feel responsive and alive.
- Provide Instant Feedback: When a user performs an action, the UI must provide immediate feedback. This can be a spinner on a button, a success toast, or a validation message. Never leave the user wondering if their action was registered.
- Use a Component Library: Do not reinvent the wheel. Use a high-quality, headless component library like shadcn/ui or Radix UI. They provide the foundation for accessible, robust components that you can style to match your brand.
Your application must be usable and beautiful on any screen size.
- Adopt a Mobile-First Approach: Design for the smallest screen (mobile) first. This forces you to prioritize the most important content and features. Then, use media queries to "progressively enhance" the layout for larger screens.
- Use Fluid Layouts: Use relative units like percentages (%) and viewport units (vw, vh) for containers, so they adapt smoothly to different screen sizes.
- Define Breakpoints Logically: Don't define breakpoints based on specific devices (e.g., "iPhone" or "iPad"). Define them where your layout naturally "breaks" or starts to look awkward. Common breakpoints are
sm
,md
,lg
,xl
. - Optimize Touch Targets: On mobile, ensure all interactive elements (buttons, links) have a large enough touch target (at least 44x44px) to be easily tappable.
This guide provides a decision framework for selecting a backend technology stack. The primary recommendations are designed to meet modern demands for performance, developer velocity, and a rich ecosystem.
Both Node.js and Python offer mature, powerful ecosystems for building robust backend services. The choice often comes down to team expertise and specific project requirements.
A. Node.js (TypeScript): For I/O-Heavy, Scalable Web Services
Leveraging the same language as the frontend (JavaScript/TypeScript), Node.js is a natural fit for full-stack development. Its non-blocking, event-driven architecture makes it exceptionally performant for handling many concurrent connections, which is typical for APIs.
- Core Philosophy: Asynchronous, non-blocking I/O for maximum throughput. Share a single language across the stack.
- Performance: Excellent for I/O-bound tasks (e.g., APIs, databases, microservices). Raw compute performance is less than compiled languages but more than sufficient for most web workloads.
- Ecosystem: Unmatched. The
npm
registry is the largest software library in the world. You will find a package for almost anything. - Recommended Frameworks:
- NestJS: A full-featured, opinionated framework that provides a highly structured, modular architecture out-of-the-box. It uses TypeScript decorators heavily and is excellent for large, complex applications where maintainability is key. Think of it as the "Angular of the backend."
- Express.js: A minimal, unopinionated, and incredibly flexible framework. It's the de-facto standard for Node.js. You have complete freedom, but you are also responsible for choosing and structuring all your components (e.g., logging, configuration).
- Best For:
- Real-time applications (e.g., chat, notifications).
- Data-intensive APIs that orchestrate multiple database calls or microservice requests.
- Full-stack teams who want to use TypeScript everywhere.
B. Python: For Rapid Development, Data Science, and Readability
Python's clean syntax and extensive standard library make it a joy to work with, enabling rapid development cycles. With modern frameworks, its performance is now competitive with Node.js.
- Core Philosophy: Developer-friendliness, readability, and a "batteries-included" approach.
- Performance: Historically slower, but modern frameworks have changed the game.
- Ecosystem: Massive, especially in data science, machine learning, and scientific computing. If your application has any AI/ML features, Python is the default choice.
- Recommended Framework:
- FastAPI: A modern, high-performance framework that is on par with Node.js and Go. It leverages Python type hints to provide automatic data validation, serialization, and interactive API documentation (via OpenAPI/Swagger). It is the clear choice for building new APIs in Python today.
- Best For:
- Applications with AI/ML or heavy data processing requirements.
- Projects where rapid prototyping and development speed are the highest priority.
- Teams who value code readability and maintainability.
When raw performance and deployment simplicity are the absolute top priorities, Go is the undisputed champion.
- Core Philosophy: Simplicity, extreme performance, and concurrency as a first-class citizen.
- Performance: Exceptional. As a compiled language, it's significantly faster than Node.js or Python. Its concurrency model (goroutines) is lightweight and powerful.
- Ecosystem: Good and growing, but smaller than Node.js and Python. You may need to write more boilerplate for tasks that are trivial in other ecosystems.
- Deployment: The Best-in-Class. Go compiles to a single, dependency-free static binary. Deployment can be as simple as copying one file to a server or into a minimal
scratch
Docker image. - Best For:
- High-performance microservices (e.g., network proxies, API gateways).
- Infrastructure tooling and CLIs.
- Services where low memory footprint and CPU usage are critical.
Consideration | Choose Node.js (NestJS/Express) | Choose Python (FastAPI) | Choose Go |
---|---|---|---|
Primary Goal | Scalable, I/O-heavy APIs | Rapid development, AI/ML integration | Maximum performance & simple deployment |
Team Expertise | JavaScript/TypeScript | Python | Statically-typed language experience (C++, Java) |
Project Type | Real-time apps, full-stack JS | Data-driven apps, AI-powered services | Infrastructure, high-throughput microservices |
Architectural Style | Flexible (Express) or Structured (NestJS) | Modern & clean with auto-docs (FastAPI) | Minimalist, explicit, and highly concurrent |
Ecosystem Needs | Vast web-focused library support | Unbeatable data science/ML libraries | Strong for networking & systems programming |
This document outlines the complete lifecycle of the application, from local development to production deployment and operations on Google Cloud.
The goal is a seamless "inner loop" where changes are reflected instantly.
- Frontend (Vite): Your current Vite setup already provides best-in-class hot-reloading for the React frontend via the
npm run dev
command. No changes are needed here. - Backend (Node.js/Python):
- Node.js: Use
nodemon
to watch for file changes and automatically restart the server. - Python (FastAPI): The development server has this built-in. Run it with
uvicorn main:app --reload
.
- Node.js: Use
- Unified Local Environment (Recommended):
- Tooling: Use a tool like
concurrently
to run both frontend and backend dev servers with a single command. - Containerization (
docker-compose
): This is the best practice. Create adocker-compose.yml
file to define and run your entire local stack: the frontend container, the backend container, and a local Postgres database container.- Benefit: A single command (
docker-compose up
) starts everything. Every developer gets the exact same setup, eliminating "it works on my machine" issues.
- Benefit: A single command (
- Tooling: Use a tool like
Cloud Run is the ideal target for containerized applications, offering auto-scaling (even to zero) and a simple developer experience.
- Strategy: Deploy the frontend and backend as two separate, independent Cloud Run services.
- Frontend Service: A
Dockerfile
will build the React app and use a lightweight web server like Nginx to serve the static files. - Backend Service: A
Dockerfile
will package your Node.js or Python application.
- Frontend Service: A
- Communication: The frontend service will be configured with the public URL of the backend service to make API calls.
- Security:
- The frontend service should be public.
- The backend service should be configured to only accept requests from the frontend service and authenticated users.
Using Vertex AI is the enterprise-grade way to use Gemini models.
- Authentication: Do not use API keys in production. Instead, use Workload Identity.
- Create a dedicated IAM Service Account for your backend service (e.g.,
my-app-backend-sa
). - Grant this service account the
Vertex AI User
role. - Configure your backend's Cloud Run service to use this service account.
- Create a dedicated IAM Service Account for your backend service (e.g.,
- Benefit: Your application code automatically and securely authenticates to the Vertex AI API using Google Cloud's infrastructure. No keys to manage or leak.
Google Cloud offers a suite of databases. Using the right one is critical for performance and cost.
Database / Storage | Data Model | Use Case | When to Choose It |
---|---|---|---|
Firestore | NoSQL (Documents) | User profiles, real-time chat, activity feeds, semi-structured data. | You need rapid development, automatic scaling, and easy synchronization with web/mobile clients. |
Cloud SQL | Relational (Postgres) | Your default choice. E-commerce orders, financial data, user credentials, any structured data. | You need ACID compliance, complex queries, joins, and the reliability of a traditional relational database. |
Cloud Spanner | Relational (Global) | Global financial ledgers, massive-scale inventory systems, multi-region applications. | You need the consistency of SQL but at a global scale that exceeds Cloud SQL's limits. This is for huge apps. |
Bigtable | NoSQL (Wide-column) | IoT sensor data, ad-tech analytics, monitoring metrics. | You have massive (terabytes+) datasets with very high write and read throughput needs. |
BigQuery | Analytical Warehouse | Business intelligence dashboards, log analysis, feeding data to ML models. | You need to run complex analytical queries on huge datasets. It is not a transactional database. |
Cloud Storage | Object Storage | User-uploaded images/videos, static assets, backups, data lake storage. | For storing unstructured files. Your application will store the URL to the object in a database like Cloud SQL. |
Automate your path from code to production using a GitOps workflow.
- Source: Connect your GitHub repository to Cloud Build.
- Build (
cloudbuild.yaml
): In your repository, create acloudbuild.yaml
file. When code is pushed to themain
branch, it will trigger Cloud Build to:- Install dependencies (
npm install
,pip install
). - Run all tests.
- Build the frontend and backend Docker images.
- Push the versioned images to Artifact Registry.
- Install dependencies (
- Deploy (
clouddeploy.yaml
): Cloud Build will then trigger a Cloud Deploy pipeline.- Delivery Pipeline: Define your promotion path (e.g.,
dev
->staging
->prod
). - Targets: Each target is a different Cloud Run environment.
- Benefit: This gives you safe, auditable, one-click promotions, and instant rollbacks.
- Delivery Pipeline: Define your promotion path (e.g.,
These services are non-negotiable for a production-grade application.
- Secret Manager: For all secrets: database passwords, third-party API keys, etc. Your Cloud Run services will be granted secure access at runtime.
- IAM (Identity and Access Management): Enforce the Principle of Least Privilege. Services and developers should only have the exact permissions they need.
- Cloud Logging & Monitoring: Your eyes and ears. All Cloud Run services automatically stream logs here. Set up dashboards and alerts to monitor application health and performance.
- VPC & Serverless VPC Access Connector: This is critical for connecting your Cloud Run service to your Cloud SQL database securely and with low latency over a private network.
- Cloud Armor: A Web Application Firewall (WAF) to protect your public-facing frontend from common web attacks and DDoS attempts.
This section details the remaining components and workflows required for a comprehensive, modern tech stack.
These are components you will almost certainly need as your application grows.
-
Frontend State Management:
- Problem: As the UI grows, managing state with just React's built-in hooks (
useState
,useContext
) becomes complex and leads to "prop drilling." - Solution: A dedicated state management library.
- Recommendations:
- Zustand: A minimalist, modern, and unopinionated library. It's incredibly easy to adopt and is often the best first choice.
- Redux Toolkit: The industry standard for large-scale applications with complex, shared state. It's more boilerplate-heavy but provides powerful debugging tools and a strict, predictable structure.
- Decision: Start with Zustand for simplicity. Graduate to Redux Toolkit if the application's state logic becomes exceptionally complex.
- Problem: As the UI grows, managing state with just React's built-in hooks (
-
Backend Data Access (ORMs):
- Problem: Writing raw SQL queries is error-prone, hard to maintain, and not type-safe.
- Solution: An Object-Relational Mapper (ORM) maps your database tables to code (models or schemas).
- Recommendations:
- Node.js (TypeScript): Prisma is the undisputed modern champion. It provides unparalleled type safety, an intuitive schema-first workflow, and an excellent query builder.
- Python: SQLAlchemy is the long-standing, powerful, and feature-rich standard. Use it with FastAPI for a robust data layer.
- Decision: Use Prisma with Node.js/TypeScript. Use SQLAlchemy with Python/FastAPI.
-
Asynchronous Tasks & Message Queues:
- Problem: What happens when a user action needs to trigger a long-running process (e.g., sending 10,000 emails, processing a video)? You can't make the user wait for the API response.
- Solution: Decouple the task using a message queue. The API publishes a "job" to a queue, and a separate worker service processes it in the background.
- Recommendations:
- Google Cloud Pub/Sub: A fully-managed, planet-scale messaging service. It's the perfect cloud-native choice for event-driven architectures and background job processing.
- Redis: Can be used as a simple, fast, in-memory message broker for less critical background tasks.
-
Real-Time Applications (e.g., Live Chat, Collaborative Editing):
- Technology: WebSockets. This allows for persistent, two-way communication between the client and server.
- Implementation: Use libraries like
socket.io
(for Node.js) which provide fallbacks and a simpler API over raw WebSockets. Your backend Cloud Run service can manage these connections.
-
Event-Driven & Microservices Architectures:
- Concept: Instead of one giant "monolith" backend, you have many small, independent services that communicate by sending events to each other.
- Technology: Google Cloud Pub/Sub is the backbone of this architecture. One service publishes an event (e.g.,
user_created
), and other services subscribe to that event to perform actions (e.g.,send_welcome_email
,create_user_profile
).
This is the practical guide to moving from your docker-compose
setup to a production deployment.
Baseline: You have a docker-compose.yml
that spins up your frontend, backend, and a local Postgres database.
Step 1: Author Production Dockerfile
s
Your docker-compose
file uses Dockerfile
s, but they need to be production-ready. This means multi-stage builds to create small, secure final images. For the frontend, this involves building the static assets and then copying them into a minimal Nginx image.
Step 2: Externalize Configuration & Secrets This is the most critical transition.
- Local: You use a
.env
file anddocker-compose
to inject environment variables likeDATABASE_URL=postgres://user:pass@localhost:5432/mydb
. - Cloud:
- Store all secrets (database passwords, API keys) in Google Secret Manager.
- In your Cloud Run service definition, you will mount these secrets as environment variables.
- Your application code does not change. It still reads from
process.env.DATABASE_URL
. The value is just supplied by Cloud Run (from Secret Manager) instead ofdocker-compose
.
Step 3: Provision Cloud Infrastructure with IaC Do not click in the GCP console to create your database or Cloud Run services. Use Infrastructure as Code (IaC).
- Tool: Terraform.
- Workflow:
- Write Terraform files (
.tf
) that define all your GCP resources: the Cloud SQL Postgres instance, the VPC network, the Serverless VPC Access Connector, the IAM service accounts, the Cloud Run services, etc. - Running
terraform apply
will create or update all your cloud infrastructure in a repeatable, version-controlled way.
- Write Terraform files (
Step 4: Connect to the Database
- Local: Your backend connects to
localhost:5432
. - Cloud: Your backend Cloud Run service connects to the private IP address of your Cloud SQL instance via the Serverless VPC Access Connector. This is crucial for security and low latency. The private IP is a value you get from your Terraform output and securely provide to your Cloud Run service as an environment variable.
Step 5: Automate with a cloudbuild.yaml
CI/CD Pipeline
This file orchestrates the entire process when you push to your main
branch.
- Test: Runs
npm test
orpytest
. - Build: Runs
docker build
for your frontend and backend, using the productionDockerfile
s. - Push: Pushes the versioned images to Artifact Registry.
- Apply Infrastructure: Runs
terraform apply
to ensure your cloud environment is configured correctly. - Deploy: Runs
gcloud run deploy
to update your Cloud Run services with the new container images from Artifact Registry.
This section covers the non-negotiable standards for code quality, dependency management, and specialized AI development workflows.
Caching is not an afterthought; it is a primary architectural concern.
- Core Caching: Use an in-memory cache for frequently accessed, non-critical data.
- Technology: Redis. It is the industry standard.
- Cloud Equivalent: Memorystore for Redis. Provision this via Terraform and connect to it from Cloud Run via a Serverless VPC Access Connector, just like with Cloud SQL.
- Local Development: Add a
redis
service to yourdocker-compose.yml
.
- LLM Semantic Caching: A critical pattern for AI applications.
- Problem: LLM calls are slow and expensive. Many user queries are semantically identical even if worded differently (e.g., "how do I reset my password?" vs. "I forgot my password").
- Solution: Before calling the LLM, check your Redis cache for a similar, previously answered query. This involves generating embeddings for the new query and performing a vector similarity search against cached queries.
- Implementation: Use a library like
gptcache
or build a simple version using Redis's vector search capabilities.
- Agentic Frameworks: For building applications that reason and orchestrate tool use.
- Default Choice: LangChain & LangGraph (Python). It is the most mature, flexible, and widely adopted ecosystem. Its agnosticism allows you to swap components (models, vector stores) easily.
- Google-Native Option: Google ADK (Agents & Development Kit). A strong contender for projects that are deeply integrated with Vertex AI from the start. Monitor its maturity. Use it if its native integrations provide a significant advantage over LangChain for your specific use case.
- Rapid Prototyping:
- Tool: Gradio. Use this for building quick, interactive UIs to test and share your AI models and pipelines. This is for internal experimentation, not the production user-facing UI.
- Model & Dataset Sourcing:
- Platform: Hugging Face. It is the primary resource for sourcing open-source pre-trained models (e.g., for embedding generation, classification) and datasets. Use their
transformers
library to easily download and use these models in your Python backend.
- Platform: Hugging Face. It is the primary resource for sourcing open-source pre-trained models (e.g., for embedding generation, classification) and datasets. Use their
These are mandatory for all projects.
- Code Style & Linting (Enforced in CI):
- JavaScript/TypeScript: ESLint (for linting) and Prettier (for formatting). Use a pre-commit hook to run these automatically.
- Python: Ruff (for ultra-fast linting and formatting). It replaces older tools like Black, isort, and Flake8.
- Go: Standard
gofmt
andgolint
.
- Dependency Management:
- Node.js: Use
npm
orpnpm
. All projects must have apackage-lock.json
orpnpm-lock.yaml
file committed to the repository to ensure reproducible builds. - Python: Use
uv
with apyproject.toml
file. This is the modern, high-speed replacement forpip
andvenv
. Thepyproject.toml
defines all dependencies, anduv
creates a virtual environment based on it.
- Node.js: Use
This final section covers the critical pillars of security, testing, and observability that ensure an application is truly production-ready, secure, and maintainable.
This is a critical security function that should never be built from scratch.
- The Principle: Always use a dedicated, managed identity provider.
- Recommendations:
- Google Cloud Identity Platform (GCIP) / Firebase Auth: The default choice for seamless integration with Google Cloud and Firebase. Provides secure, scalable authentication with a generous free tier.
- Auth0 / Okta: Excellent, vendor-agnostic alternatives for complex enterprise environments or when multi-cloud/hybrid integration is a primary concern.
A structured testing strategy is mandatory.
- Level 1: Unit Tests (Most Numerous):
- Goal: Test individual functions/components in isolation.
- Tools: Jest (JS/TS), Pytest (Python).
- Level 2: Integration Tests:
- Goal: Test the interaction between services (e.g., API to Database).
- Environment: Run these against the stateful services defined in your
docker-compose.yml
within your CI (Cloud Build) pipeline.
- Level 3: End-to-End (E2E) Tests (Least Numerous):
- Goal: Simulate a full user journey in a real browser.
- Tools: Playwright or Cypress.
To understand and debug a distributed system, you need more than just logs.
- Structured Logging: All services must log in JSON format. This makes logs searchable and analyzable in Cloud Logging.
- Distributed Tracing: Implement Google Cloud Trace to trace requests as they flow through your frontend, backend, and other services. This is invaluable for pinpointing bottlenecks and errors.
- Metrics & Alerting: Define and monitor key performance indicators (KPIs) and Service Level Objectives (SLOs) in Cloud Monitoring. Create alerts for critical thresholds (e.g., p99 latency > 2s, error rate > 1%).
Security is a continuous process, not a one-time setup.
- Automated Vulnerability Scanning (CI/CD):
- Dependency Scanning: The CI pipeline must include a step to run
npm audit
orpip-audit
to check for vulnerabilities in third-party packages. - Container Scanning: Enable Artifact Registry's built-in security scanning to automatically analyze your Docker images for known OS-level vulnerabilities.
- Dependency Scanning: The CI pipeline must include a step to run
This final section specifies the essential, non-negotiable tools for interacting with Google Cloud and ensuring a productive, language-specific development experience.
Every developer on the project must have the Google Cloud CLI (gcloud
) installed and authenticated. It is the foundational tool for all manual and scripted interactions with the project's cloud environment.
Your application code must use the official Google Cloud Client Libraries to interact with GCP services. These libraries handle authentication (via Workload Identity), retries, and provide an idiomatic interface.
- Node.js (TypeScript): Use the
@google-cloud/[SERVICE]
packages (e.g.,@google-cloud/storage
,@google-cloud/pubsub
). - Python: Use the
google-cloud-[SERVICE]
packages (e.g.,google-cloud-storage
,google-cloud-pubsub
). - Go: Use the
cloud.google.com/go/[SERVICE]
packages.
These tools are not optional; they are part of the standard toolkit for their respective languages to ensure productivity and code quality.
- Node.js (TypeScript) / Frontend:
- Configuration Management: Use
zod
for validating environment variables at runtime. This prevents misconfigurations and ensures your application starts in a known-good state.
- Configuration Management: Use
- Python:
- Configuration Management: Use
pydantic
for settings management. It provides the same benefits aszod
for the Python ecosystem. - CLI Tooling: For any Python-based CLIs, use
Typer
orClick
. They provide a simple, declarative way to build robust command-line interfaces.
- Configuration Management: Use
- Go:
- Configuration Management: Use
viper
for handling configuration from files, environment variables, and flags. - CLI Tooling: Use
cobra
to build powerful, modern CLI applications. It is the foundation of many popular tools likekubectl
andhugo
.
- Configuration Management: Use