Skip to content

Conversation

Copy link

Copilot AI commented Nov 17, 2025

MVP full-stack application demonstrating modern TypeScript development setup with Express backend and Vite frontend.

Architecture

Backend (src/server.ts)

  • Express server with TypeScript, ESM modules
  • /api/hello{ message: "Hello World" }
  • /api/health → health check endpoint
  • Static file serving in production mode
  • Environment config via dotenv (PORT, NODE_ENV)

Frontend (frontend/)

  • Vite + TypeScript with zero-config setup
  • Fetches from /api/hello on load with error handling
  • Gradient UI with responsive design
  • Dev proxy to backend API

Testing & Quality

  • Vitest: 5 tests (2 backend API, 3 frontend utils)
  • ESLint + Prettier: Minimal TS-aware config
  • GitHub Actions: Node 18.x/20.x matrix (install → lint → build → test)

Docker

Multi-stage build:

# Separate builders for backend/frontend
# Final image: node:20-alpine + compiled assets
# Health check on /api/health

Run: docker-compose uphttp://localhost:3000

Scripts

Command Purpose
npm run dev Backend hot reload (tsx watch)
npm run frontend:dev Frontend dev server (port 5173)
npm run build Compile backend + bundle frontend
npm start Production server (serves both)
npm test Run all tests

Screenshot

Demo UI

Minimal friction setup for rapid full-stack TypeScript demos.

Original prompt

Crear un repositorio MVP full-stack Hello World en TypeScript para una demo rápida.
Requisitos:
Backend:

  • Node + TypeScript, sin framework pesado (usar Express o http nativo; preferible Express por rapidez).
  • Endpoint GET /api/hello que responda { message: "Hello World" }.
  • Estructura src/server.ts y configuracion tsconfig, scripts: dev (ts-node-dev), build (tsc), start (node dist/server.js).
    Frontend:
  • Carpeta frontend con index.html y main.ts.
  • Mostrar texto devuelto por /api/hello en la página (fetch al cargar) y fallback si error.
  • Empaquetado ligero: Vite (config TS) o alternativa sin build; elegir Vite para DX. Scripts: frontend:dev, frontend:build, frontend:preview.
    Infraestructura / Calidad:
  • ESLint + Prettier mínima config para TS.
  • Vitest pruebas simples: uno para backend (llamar handler directamente) y uno para frontend (funcion que formatea mensaje).
  • GitHub Actions workflow: Node matrix (18.x, 20.x) que instala, lint, build, test.
  • README conciso con pasos: instalar, dev backend, dev frontend, build, test.
  • License MIT.
    Security / Config:
  • .env.example con PORT=3000.
  • Backend lee PORT y default 3000.
  • No secretos reales.
    Opcional (si tiempo): Dockerfile multistage para backend y simple nginx para servir frontend build, docker-compose para ambos.
    Objetivo: mínima fricción para mostrar full-stack hello world.
    Entregables: código completo, README claro, scripts funcionando.
    Etiquetas: demo, hello-world, typescript, full-stack.

Related to Issue #1

Custom agent used: README Expert
Agente experto en crear READMEs atractivos, informativos y bien estructurados para proyectos de desarrollo.

Automated by Copilot MCP Server


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI self-assigned this Nov 17, 2025
Copilot AI changed the title [WIP] Create MVP full-stack Hello World in TypeScript Implement full-stack TypeScript Hello World demo with Express + Vite Nov 17, 2025
Copilot AI requested a review from svg153 November 17, 2025 19:06
Copilot finished work on behalf of svg153 November 17, 2025 19:06
@svg153 svg153 requested review from Copilot and removed request for svg153 November 17, 2025 19:06
Copilot finished reviewing on behalf of svg153 November 17, 2025 19:09
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR implements a full-stack TypeScript Hello World demo application with Express backend and Vite frontend, demonstrating modern development practices and tooling setup.

Key changes:

  • Complete backend setup with Express server, TypeScript, ESM modules, and health/hello API endpoints
  • Frontend application using Vite + TypeScript with API integration and responsive UI design
  • Comprehensive development infrastructure including Vitest testing, ESLint/Prettier, GitHub Actions CI, and Docker support

Reviewed Changes

Copilot reviewed 18 out of 21 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
src/server.ts Express server with API endpoints, static file serving, and environment configuration
src/__tests__/server.test.ts Backend API tests for hello and health endpoints using Supertest
frontend/src/main.ts Frontend application logic with API fetching and DOM manipulation
frontend/src/utils.ts Utility function for message formatting
frontend/src/__tests__/main.test.ts Frontend unit tests for utility functions
frontend/index.html HTML template with embedded styles and responsive gradient design
frontend/tsconfig.json Frontend-specific TypeScript configuration for browser environment
package.json Project dependencies, scripts, and metadata
tsconfig.json Backend TypeScript configuration with strict mode and ESM output
vite.config.ts Vite configuration with dev server proxy and build settings
vitest.config.ts Test framework configuration with coverage reporting
.eslintrc.json ESLint configuration for TypeScript with recommended rules
.prettierrc.json Code formatting rules
.env.example Environment variable template
.gitignore Git ignore patterns for dependencies, build output, and IDE files
.dockerignore Docker ignore patterns to reduce build context
Dockerfile Multi-stage Docker build for backend and frontend
docker-compose.yml Docker Compose configuration with health checks
.github/workflows/ci.yml GitHub Actions CI workflow with Node.js matrix testing
README.md Comprehensive documentation with setup instructions and architecture details

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

coverage
.git
.gitignore
README.md
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] The .dockerignore file excludes README.md on line 10 and then uses a broader pattern *.md on line 13, which also excludes README.md. The first specific exclusion is redundant. While not harmful, it's cleaner to remove line 10 since line 13 already covers it.

Suggested change
README.md

Copilot uses AI. Check for mistakes.
"@types/supertest": "^6.0.2",
"@typescript-eslint/eslint-plugin": "^6.15.0",
"@typescript-eslint/parser": "^6.15.0",
"@vitejs/plugin-react": "^4.2.1",
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The package.json includes "@vitejs/plugin-react": "^4.2.1" in devDependencies, but this plugin is not used anywhere in the codebase. The project uses vanilla TypeScript without React. This dependency should be removed to reduce bundle size and avoid confusion.

Suggested change
"@vitejs/plugin-react": "^4.2.1",

Copilot uses AI. Check for mistakes.
if: matrix.node-version == '20.x'
uses: codecov/codecov-action@v3
with:
file: ./coverage/coverage-final.json
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the CI workflow, the coverage upload step references ./coverage/coverage-final.json but Vitest with the v8 provider generates coverage in different file formats. The standard output is typically in subdirectories like ./coverage/lcov.info or the JSON files might have different names. This could cause the coverage upload to fail silently. Consider using a glob pattern or verifying the actual output path from Vitest's v8 coverage provider.

Suggested change
file: ./coverage/coverage-final.json
file: ./coverage/*.json,./coverage/lcov.info

Copilot uses AI. Check for mistakes.
Comment on lines +40 to +44
// Start server
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
console.log(`API available at http://localhost:${PORT}/api/hello`);
});
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The server exports the Express app and immediately calls app.listen(). This creates a problem: when the tests import the server module to test the endpoints, the server will start listening, which can cause port conflicts and makes tests harder to run in parallel. Consider separating the app definition from the server startup. A common pattern is to export the app without starting it, and have a separate entry point (or check for import.meta.url === process.argv[1]) that starts the server only when run directly.

Suggested change
// Start server
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
console.log(`API available at http://localhost:${PORT}/api/hello`);
});
// Start server only if this file is run directly
if (import.meta.url === `file://${process.argv[1]}`) {
app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
console.log(`API available at http://localhost:${PORT}/api/hello`);
});
}

Copilot uses AI. Check for mistakes.
COPY src ./src

# Build backend
RUN npm run build
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Dockerfile runs npm run build on line 17, but at that point only the backend source files have been copied (line 14). The frontend source files are not available yet, so npm run build which includes npm run frontend:build will fail. The backend and frontend builders should be independent, with the backend builder only running tsc to compile TypeScript.

Suggested change
RUN npm run build
RUN npx tsc

Copilot uses AI. Check for mistakes.
- NODE_ENV=production
- PORT=3000
healthcheck:
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3000/api/health"]
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The health check uses wget but the base image is node:20-alpine which doesn't include wget by default. The health check will fail. Consider using curl (which is available in alpine) or install wget in the Dockerfile, or use a Node.js-based health check command like node -e "require('http').get('http://localhost:3000/api/health')" or wget should be installed via apk add --no-cache wget.

Suggested change
test: ["CMD", "wget", "--quiet", "--tries=1", "--spider", "http://localhost:3000/api/health"]
test: ["CMD", "curl", "--fail", "http://localhost:3000/api/health"]

Copilot uses AI. Check for mistakes.
Comment on lines +21 to +22
volumes:
node_modules:
Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The volumes section at the end defines a node_modules volume but it's never used by any service. This volume declaration serves no purpose and should either be removed or actually mounted to the backend service if the intention was to persist node_modules.

Suggested change
volumes:
node_modules:

Copilot uses AI. Check for mistakes.
Comment on lines +52 to +54
# Create .env file with default values if not exists
RUN echo "PORT=3000" > .env.example

Copy link

Copilot AI Nov 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Creating a .env.example file inside the Docker image is misleading since this is runtime, not a template for users. The comment says "Create .env file with default values if not exists" but the command creates .env.example, not .env. If the intention is to provide default environment values, they should either be set as ENV variables directly or this line should be removed entirely since environment variables are already set via docker-compose.yml.

Suggested change
# Create .env file with default values if not exists
RUN echo "PORT=3000" > .env.example

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants