Tech Stack Selection
Philosophy: Choose tools based on context, requirements, and user preference. No "one size fits all" solutions. Core Principle: ASK user preferences, SUGGEST based on context, EXPLAIN trade-offs.
When to Use This Skill
Use this skill when:
- Starting a new project (no existing code)
- Adding a new feature that could use different stacks
- User asks "what stack should I use?"
- Migration between technologies is being considered
Do NOT use this skill when:
- Project already has established stack (maintain consistency)
- User explicitly specifies what to use
- Only minor adjustments are needed
Question Tool Protocol (MANDATORY)
ALWAYS use the question tool for stack selection decisions.
Multi-Option Format (Preferred)
question({
questions: [{
question: "Which backend framework would you like to use?",
header: "Backend Framework",
options: [
{
label: "Fullstack Blueprint (Recommended)",
description: "FastAPI + SQLAlchemy + Alembic - battle-tested, includes Docker, Redis, Celery"
},
{
label: "FastAPI (Custom)",
description: "Fast, modern, async - great for APIs"
},
{
label: "Express/Node.js",
description: "Flexible, huge ecosystem, good for fullstack JavaScript"
},
{
label: "Hono",
description: "Ultra-fast, edge-ready, TypeScript-first"
},
{
label: "Other",
description: "Let me know your preference"
}
]
}]
})
Preference Questions Format
When checking user preferences:
question({
questions: [{
question: "Do you have any tech stack preferences?",
header: "Stack Preferences",
multiple: true,
options: [
{
label: "Use the Fullstack Blueprint",
description: "I want the standard stack: React/Vite + FastAPI + SQLAlchemy"
},
{
label: "I have specific preferences",
description: "I'll tell you exactly what I want"
},
{
label: "Suggest based on my requirements",
description: "Help me choose based on what I'm building"
}
]
}]
})
See .opencode/rules/MASTER.md for complete Question Tool Protocol.
Stack Selection Process
Phase 1: Context Analysis (ALWAYS FIRST)
Before suggesting anything, gather context:
| Question | Why It Matters |
|---|---|
| What are you building? | Web app, API, mobile, landing page? |
| What's your scale? | Prototype, MVP, production, enterprise? |
| What's your timeline? | Rushed, normal, no constraints? |
| What's your team size/expertise? | Solo, small team, large team? |
| Any constraints? | Edge deployment, legacy systems, compliance? |
Reference: See
@blueprints/fullstack/for an example of a well-configured fullstack setup. Use it as reference, not requirement.
Phase 2: Check Existing Stack
| Question | Why It Matters |
|---|---|
| What are you building? | Web app, API, mobile, landing page? |
| What's the scale? | Prototype, MVP, production, enterprise? |
| What's your timeline? | Rushed, normal, no constraints? |
| What's your team size/expertise? | Solo, small team, large team? |
| Any constraints? | Edge deployment, legacy systems, compliance? |
Phase 2: Check Existing Stack
Before suggesting, check if stack exists:
# Check for existing backend
ls backend/pyproject.toml backend/package.json backend/go.mod 2>/dev/null
# Check for existing frontend
ls frontend/package.json package.json 2>/dev/null
# Check for config files
ls docker-compose.* vite.config.* next.config.* 2>/dev/null
If stack exists:
- Maintain consistency unless migration is explicitly requested
- Ask user: "You already use [X]. Should I continue with that stack, or are you considering changes?"
Phase 3: User Preferences
ALWAYS ask about preferences:
Primary question:
question({ questions: [{ question: "Do you have any tech stack preferences?", header: "Stack Preferences", multiple: true, options: [ { label: "I have specific preferences", description: "I'll tell you exactly what I want" }, { label: "Suggest based on my requirements", description: "Help me choose based on what I'm building" } ] }] })If user wants suggestions: Proceed to Phase 4 with decision trees
Phase 4: Suggest Based on Requirements
If user wants suggestions, provide options with trade-offs:
Example Backend Suggestion:
| Option | Best For | Trade-offs |
|---|---|---|
| FastAPI | APIs, async, Python expertise | Smaller ecosystem than Node.js |
| Express | Fullstack JS, flexibility | Slower, callback hell risk |
| Hono | Edge, performance, TypeScript | Newer, smaller community |
| Go | Performance, concurrency | Slower development, verbose |
Fullstack Blueprint (Example Stack)
Blueprint Stack Details
Note: This is an example of a well-configured fullstack setup used in @blueprints/fullstack/. It's not mandatory - use it as reference, not requirement.
Frontend:
- React 18: Modern, component-based
- Vite: Fast dev server, optimized builds
- TanStack Query: Server state management (caching, refetching)
- TanStack Router: Type-safe routing
- Tailwind CSS: Utility-first styling
- ShadcnUI: Accessible, customizable components
Backend:
- FastAPI: Async, modern Python, automatic OpenAPI docs
- SQLAlchemy: ORM, migrations via Alembic
- PostgreSQL: Robust relational database
- Redis: Caching, Celery broker
- Celery: Async task queue
- Docker: Containerization
Infrastructure:
- Docker Compose: Dev and production setups
- Poetry: Python dependency management
Backend Decision Tree
Framework Selection
What runtime do you prefer?
├── Python
│ ├── Need async/high performance?
│ │ ├── Yes → FastAPI (recommended)
│ │ └── No → Django (batteries included) or Flask (lightweight)
│ └── Need full features?
│ ├── Yes → Django
│ └── No → FastAPI or Flask
├── Node.js
│ ├── Edge deployment?
│ │ ├── Yes → Hono or Bun
│ │ └── No → Fastify (performance) or Express (flexible)
│ └── TypeScript fullstack?
│ └── Consider tRPC with Next.js
└── Go/Rust
└── Performance critical → FastAPI is usually sufficient
Database Selection
What type of data?
├── Relational data, complex relationships
│ ├── Production → PostgreSQL (recommended)
│ ├── Edge/Serverless → Neon (serverless PG)
│ └── Simple/Local → SQLite
├── Vector search/AI
│ └── PostgreSQL + pgvector or dedicated vector DB
├── Global distribution
│ └── Turso (edge SQLite) or PlanetScale (MySQL)
└── Key-value cache
└── Redis or Upstash (serverless)
ORM Selection
Python:
├── FastAPI → SQLAlchemy (recommended) or Tortoise ORM
├── Django → Django ORM (built-in)
└── Simple → Pydantic models + direct SQL
Node.js:
├── PostgreSQL → Prisma or Drizzle
└── Performance → Drizzle (edge-ready)
Frontend Decision Tree
Framework Selection
What type of application?
├── Single Page App (SPA)
│ ├── React ecosystem?
│ │ ├── Yes → React + Vite (recommended in blueprint)
│ │ └── No → Svelte + SvelteKit or Vue + Vite
│ └── Build tools → Vite (fastest) or Next.js (SSR)
├── Server-Side Rendering (SSR)
│ ├── Need SEO/crawling?
│ │ ├── Yes → Next.js (recommended)
│ │ └── No → Consider SPA
│ └── Fullstack TypeScript?
│ └── Next.js + tRPC (type-safe)
└── Static Site
└── Next.js (static export) or Astro
State Management
What state do you need?
├── Server data (API calls)
│ └── TanStack Query (recommended) or SWR
├── Client state (UI state)
│ ├── Simple → React built-in (useState, useReducer)
│ ├── Complex but local → Zustand
│ └── Global/shared → Context API or Redux Toolkit
└── URL state (shareable)
└── URL params + useSearchParams
UI Library Selection
What do you need?
├── Blueprint default → ShadcnUI (recommended)
├── Full-featured component library
│ ├── Radix UI (unstyled primitives)
│ ├── Mantine (opinionated)
│ ├── Chakra UI (simple)
│ └── Material UI (Google design)
├── Design system building
│ └── Headless UI or Radix UI
└── Complete control
│ └── Custom CSS or Tailwind only
Styling
What approach?
├── Blueprint default → Tailwind CSS (recommended)
├── CSS-in-JS
│ ├── Styled Components
│ └── Emotion
├── CSS Modules
│ └── CSS file per component
└── Traditional CSS
│ └── Plain CSS with variables
Stack Decision Template
When documenting stack decisions, use this format:
Backend Stack
| Component | Choice | Why? |
|---|---|---|
| Runtime | [e.g., Python 3.12] | Team expertise, async support |
| Framework | [e.g., FastAPI] | Performance, automatic docs |
| Database | [e.g., PostgreSQL] | Relational data, ACID compliance |
| ORM | [e.g., SQLAlchemy] | Migration support, type hints |
| Task Queue | [e.g., Celery] | Async jobs, Python ecosystem |
Frontend Stack
| Component | Choice | Why? |
|---|---|---|
| Framework | [e.g., React 18] | Team expertise, ecosystem |
| Build Tool | [e.g., Vite] | Fast dev experience |
| Routing | [e.g., TanStack Router] | Type-safe, file-based |
| State Management | [e.g., TanStack Query] | Server state, caching |
| UI Library | [e.g., ShadcnUI] | Accessible, customizable |
| Styling | [e.g., Tailwind CSS] | Developer experience |
Infrastructure
| Component | Choice | Why? |
|---|---|---|
| Containerization | [e.g., Docker] | Reproducibility, deployment |
| Deployment | [e.g., Docker Compose] | Simple setup, production-ready |
Selection Checklist
Before finalizing stack selection:
- Asked user about preferences?
- Checked for existing stack?
- Offered blueprint as option?
- Explained trade-offs of options?
- Documented rationale?
- Team expertise considered?
- Constraints considered?
Anti-Patterns
DON'T:
- Force a stack without asking user
- Assume "modern" = "best" for every project
- Ignore existing code/stack
- Choose based on trends instead of requirements
- Skip trade-off explanations
DO:
- Always ask user preferences first
- Explain why you're recommending each option
- Consider team expertise and constraints
- Document rationale for decisions
- Offer blueprint as default, not mandate
Related Skills
| Need | Skill |
|---|---|
| Backend patterns | @[skills/python-patterns] or @[skills/api-patterns] |
| Frontend patterns | @[skills/frontend-design] or @[skills/nextjs-react-expert] |
| Architecture | @[skills/architecture] |
| Database design | @[skills/database-design] |
Usage Examples
Example 1: New Project, No Preferences
User: "I want to build a web application for task management"
Process:
- Ask: "Do you want to use the Fullstack Blueprint (React + FastAPI + SQLAlchemy)?"
- If yes → Use blueprint stack
- If no → Ask about preferences or suggest based on requirements
Example 2: Existing Project
User: "Add a new feature to the existing app"
Process:
- Check existing stack (e.g., FastAPI + React)
- Maintain consistency
- Ask: "You're using FastAPI + React. Continue with that stack?"
Example 3: Migration
User: "I want to migrate to a different stack"
Process:
- Understand motivation (performance, team expertise, etc.)
- Suggest alternatives with trade-offs
- Document migration plan
Remember: There's no "perfect" stack. The best stack is the one that fits the project requirements, team expertise, and constraints. Always involve the user in decisions.