Project Scaffolding
Learning Outcomes
- Generate complete project directory structures from natural language descriptions
- Scaffold framework-specific projects (React, Express, Flask, etc.) with best practices
- Create configuration files (ESLint, Prettier, TypeScript, Docker) with appropriate settings
- Customize generated scaffolds to match team conventions and preferences
- Use templates and existing projects as references for consistent scaffolding
Lesson Plan
| Segment | Duration | Topic |
|---|---|---|
| Intro | 3 min | Scaffolding vs manual setup — why use Codex for this |
| Demo 1 | 10 min | Scaffolding a complete Node.js API from scratch |
| Demo 2 | 8 min | Framework-specific scaffolding (React + TypeScript) |
| Explain | 5 min | Configuration file generation strategies |
| Demo 3 | 8 min | Docker + CI/CD config generation |
| Demo 4 | 8 min | Customizing scaffolds with team conventions |
| Explain | 4 min | Using existing projects as templates |
| Wrap-up | 4 min | Scaffolding workflow best practices |
Before You Begin
Pre-work:
- Complete Lesson 5 — Debugging & Error Resolution
- Create an empty directory for scaffolding exercises
- Have a reference project you'd like to replicate the structure of (optional)
Shopping List:
- Codex CLI installed and configured
- An empty project directory (we'll build from scratch)
- Node.js or Python installed (for verifying generated projects)
- Docker installed (optional, for container-related exercises)
Codex CLI can generate an entire project structure from a single detailed prompt. The key is being explicit about what you need.
Starting from an empty directory:
mkdir ~/projects/my-new-api && cd ~/projects/my-new-api
git init
codex
mkdir %USERPROFILE%\projects\my-new-api && cd %USERPROFILE%\projects\my-new-api
git init
codex
A comprehensive scaffolding prompt:
> Scaffold a Node.js REST API project with this structure:
>
> - src/
> - controllers/ (user and product controllers)
> - models/ (User and Product with Mongoose schemas)
> - routes/ (user and product routes)
> - middleware/ (auth, error-handler, rate-limiter)
> - config/ (database, environment variables)
> - utils/ (logger, response helpers)
> - tests/ (mirrors src/ structure)
> - package.json (with express, mongoose, dotenv, jest)
> - .env.example
> - .gitignore (Node.js appropriate)
> - README.md (basic project documentation)
>
> Use ES modules (import/export), include JSDoc comments,
> and follow RESTful naming conventions.
Codex will create files one by one. In untrusted policy, you approve each. In on-request policy, they're created automatically.
What makes a good scaffolding prompt:
| Include | Why |
|---|---|
| Directory structure | Removes ambiguity about file organization |
| Package names | Gets the right dependencies from the start |
| Module system (ESM/CJS) | Prevents inconsistency across files |
| Naming conventions | Ensures consistency (camelCase, kebab-case, etc.) |
| Language features | TypeScript vs JavaScript, Python version, etc. |
Different frameworks have specific conventions and required configurations. Codex knows these patterns and can generate framework-idiomatic code.
React with TypeScript:
> Scaffold a React project with TypeScript. Don't use create-react-app.
> Set up Vite as the bundler. Include:
> - src/components/ with a Header, Footer, and Layout component
> - src/pages/ with Home and About pages
> - src/hooks/ with a useLocalStorage custom hook
> - src/types/ with shared TypeScript interfaces
> - Vite config with path aliases (@ → src/)
> - tsconfig.json with strict mode
> - ESLint + Prettier configs for React/TS
Flask API:
> Scaffold a Flask REST API with:
> - app/ package with __init__.py (app factory pattern)
> - app/routes/ with auth.py and users.py blueprints
> - app/models/ with User model (SQLAlchemy)
> - app/schemas/ with Marshmallow schemas for validation
> - config.py with environment-based configuration
> - requirements.txt with Flask, SQLAlchemy, Marshmallow
> - tests/ with conftest.py and pytest fixtures
> - Makefile with common commands (run, test, lint)
Express + TypeScript:
> Scaffold an Express.js API in TypeScript with:
> - Strict tsconfig
> - src/routes, controllers, services layers
> - Dependency injection pattern
> - Request validation with Zod
> - Error handling middleware with typed errors
> - Jest config for TypeScript tests
> - nodemon config for development
Key framework patterns Codex handles well:
| Framework | Patterns Codex Knows |
|---|---|
| React | Hooks, context, component composition, routing |
| Next.js | App router, server components, API routes |
| Express | Middleware chain, router separation, error handling |
| Flask | Blueprints, app factory, extensions |
| Django | Apps, models, views, serializers, URL routing |
| FastAPI | Pydantic models, dependency injection, routers |
Configuration files are often the most tedious part of project setup. Codex can generate them with appropriate defaults and comments explaining each option.
TypeScript configuration:
> Create a tsconfig.json for a Node.js 20 backend project using
> ES modules. Enable strict mode, path aliases, and generate
> source maps. Target ES2022.
{
"compilerOptions": {
"target": "ES2022",
"module": "NodeNext",
"moduleResolution": "NodeNext",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"outDir": "./dist",
"rootDir": "./src",
"sourceMap": true,
"declaration": true,
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
ESLint + Prettier:
> Create ESLint and Prettier configs that work together for a
> TypeScript React project. Use flat config format for ESLint.
> Enforce consistent semicolons, double quotes, and 2-space indent.
Docker configuration:
> Create a Dockerfile for a Node.js 20 application with:
> - Multi-stage build (builder + production)
> - Non-root user for security
> - .dockerignore file
> - docker-compose.yml with app + PostgreSQL + Redis
> - Health check endpoint configuration
CI/CD configuration:
> Create a GitHub Actions workflow that:
> - Runs on push to main and pull requests
> - Installs Node.js 20
> - Caches node_modules
> - Runs lint, type-check, and tests in parallel
> - Builds the project
> - Only deploys on push to main (not on PRs)
Environment configuration:
> Create a .env.example file with all the environment variables
> this project needs, based on reading the config files. Add
> comments explaining each variable. Don't include actual secrets.
Generic scaffolding is useful, but most teams have specific conventions. You can teach Codex your preferences within a prompt.
Embedding conventions in your prompt:
> Scaffold a new microservice following our team conventions:
>
> Conventions:
> - File naming: kebab-case (user-controller.ts, not userController.ts)
> - Exports: named exports only (no default exports)
> - Error handling: all errors use our AppError class
> - Logging: use structured JSON logging with pino
> - Testing: colocate tests (user.service.ts + user.service.test.ts)
> - No classes: use functions and closures for everything
>
> The microservice handles payment processing with Stripe.
Using an existing file as a template:
> Look at src/services/user.service.ts as a reference for our
> service pattern. Create a new product.service.ts following
> the exact same structure, error handling approach, and
> documentation style.
Using a conventions file:
Create a .codex-conventions or CONVENTIONS.md in your project:
> Read CONVENTIONS.md and then scaffold a new module for
> inventory management following all the rules described there.
Customizing after generation:
> The scaffold looks good, but make these adjustments:
> 1. Rename all controller files from *.controller.ts to *.ctrl.ts
> 2. Add our standard license header to every file
> 3. Use our team's database connection helper instead of direct
> mongoose.connect calls
Company boilerplate:
> We start every service with this boilerplate structure. Generate
> it for a new "notifications" service:
>
> - health check endpoint at /health
> - metrics endpoint at /metrics
> - graceful shutdown handler
> - structured request logging middleware
> - correlation ID propagation
> - OpenAPI spec file
After scaffolding, you need to verify that the generated project actually works. Codex can help with this too.
Step 1: Check for completeness
> Review the project structure we just created. Are there any
> missing files that would be needed to run this project?
> (Missing imports, undefined references, etc.)
Step 2: Verify imports and dependencies
> Check all import statements across the project. Are there any
> imports that reference files that don't exist or exports that
> aren't defined?
Step 3: Install and test
# For Node.js projects
codex "Run npm install and report any peer dependency warnings"
# For Python projects
codex "Create a virtual environment, install requirements.txt, and verify imports"
# For Node.js projects
codex "Run npm install and report any peer dependency warnings"
# For Python projects
codex "Create a virtual environment, install requirements.txt, and verify imports"
Step 4: Run the linter
> Run the linter we configured and fix any issues it reports.
Step 5: Run initial tests
> Run the test suite. If there are failures from the scaffold
> (missing implementations, etc.), that's expected — but there
> shouldn't be import errors or configuration issues.
Step 6: Commit the scaffold
> Everything looks good. Stage all files and create an initial
> commit with the message "feat: scaffold payment service"
Common post-scaffold issues:
| Issue | Solution |
|---|---|
| Missing dependency in package.json | Ask Codex to scan imports and update package.json |
| Circular imports | Ask Codex to identify and resolve import cycles |
| Incorrect path aliases | Verify tsconfig paths match actual directory structure |
| Wrong Node.js version | Check engines field in package.json |
| Test config doesn't match structure | Verify jest.config or pytest.ini matches file layout |
Questions & Answers
Key Takeaways
- Be explicit in scaffolding prompts: Specify directory structure, packages, module system, and naming conventions
- Framework patterns work well: Codex knows standard patterns for popular frameworks — leverage that knowledge
- Configuration files save the most time: Let Codex generate tsconfig, ESLint, Docker, and CI/CD configs with comments
- Reference existing code: Point Codex at existing files as templates for consistent scaffolding
- Verify after generating: Check imports, run the linter, install dependencies, and run tests
- Commit the scaffold immediately: Keep a clean snapshot before any manual modifications
Next Steps: In Lesson 7 — Testing with Codex, you'll learn how to generate comprehensive test suites and adopt TDD workflows with Codex CLI.