Chalice is a modern, full-stack real-time chat application built with React, Node.js, TypeScript, and Azure WebPubSub. This project demonstrates professional-grade development practices and serves as an excellent learning resource for developers transitioning from Vue.js/Laravel to React/Node.js ecosystems.
- Real-time messaging with WebSocket connectivity
- Dual-mode architecture (Azure WebPubSub + Mock WebSocket)
- Responsive design with modern UI components
- Type-safe development with comprehensive TypeScript
- Monorepo structure with separate frontend/backend
- Production-ready patterns with error handling and optimization
- Educational codebase with detailed documentation and comments
βββββββββββββββββββββββ βββββββββββββββββββββββ βββββββββββββββββββββββ
β β β β β β
β React Frontend βββββΊβ Express Backend βββββΊβ Azure WebPubSub β
β β β β β (or Mock Server) β
β β’ TypeScript β β β’ TypeScript β β β
β β’ Styled Comps β β β’ WebSocket β β β’ Managed Service β
β β’ Custom Hooks β β β’ Dual Mode β β β’ Auto Scaling β
β β’ Vite Bundler β β β’ REST API β β β’ Group Messaging β
β β β β β β
βββββββββββββββββββββββ βββββββββββββββββββββββ βββββββββββββββββββββββ
Port 5173 Port 3001 Azure Cloud
- React 19 with TypeScript
- Vite for fast development and building
- Styled Components for CSS-in-JS styling
- Custom Hooks for WebSocket management
- Azure WebPubSub Client for real-time messaging
- Node.js 18+ with Express.js
- TypeScript for type safety
- Azure WebPubSub SDK for managed WebSocket service
- Native WebSocket fallback for local development
- CORS configured for cross-origin requests
- ESLint for code quality
- TypeScript compiler with strict mode
- tsx for development with hot reload
- Comprehensive documentation and code comments
- Node.js 18+
- npm or yarn
- Git for version control
- Optional: Azure WebPubSub service for cloud mode
# Clone the repository
git clone <repository-url>
cd chalice
# Install root dependencies
npm install
# Install server dependencies
cd server && npm install && cd ..
# Install web dependencies
cd web && npm install && cd ..# Server configuration
cd server
cp .env.example .env
# For local development (mock mode), comment out Azure connection:
# AZURE_WEB_PUBSUB_CONNECTION=Endpoint=...;AccessKey=...;Version=1.0;
HUB=chat
PORT=3001
WS_PORT=3002# Terminal 1: Start backend server
cd server
npm run dev
# Terminal 2: Start frontend server
cd web
npm run dev- Frontend: http://localhost:5173
- Backend API: http://localhost:3001
- Mock WebSocket: ws://localhost:3002
chalice/
βββ server/ # Backend Express.js application
β βββ src/
β β βββ index.ts # Main server file with dual-mode support
β βββ dist/ # Compiled JavaScript output
β βββ package.json # Server dependencies and scripts
β βββ tsconfig.json # TypeScript configuration
β βββ .env # Environment variables
β βββ README.md # Server-specific documentation
β
βββ web/ # Frontend React application
β βββ src/
β β βββ App.tsx # Main React component
β β βββ main.tsx # React app entry point
β β βββ hooks/
β β β βββ useWebPubSub.ts # Custom WebSocket hook
β β βββ types.ts # Shared TypeScript types
β β βββ assets/ # Static assets
β βββ public/ # Public static files
β βββ dist/ # Production build output
β βββ package.json # Frontend dependencies and scripts
β βββ vite.config.ts # Vite bundler configuration
β βββ tsconfig.json # TypeScript configuration
β βββ README.md # Frontend-specific documentation
β
βββ package.json # Root package.json for monorepo
βββ INTERVIEW_GUIDE.md # Comprehensive interview preparation
βββ README.md # This file - project overview
# Install all dependencies
npm install
# Start both server and web in development mode
npm run dev
# Build both applications for production
npm run buildnpm run dev # Start development server with hot reload
npm run build # Compile TypeScript to JavaScript
npm start # Run production server
npm test # Run test suite (when implemented)npm run dev # Start Vite development server
npm run build # Build production bundle
npm run preview # Preview production build locally
npm run lint # Run ESLint for code quality- Hot Module Replacement for instant updates
- TypeScript compilation with strict type checking
- Auto-reconnection for WebSocket connections
- CORS configuration for cross-origin development
- Environment-based configuration for different deployment targets
- Uses native WebSocket server on port 3002
- No external dependencies or cloud services required
- Perfect for local development and testing
- Create Azure WebPubSub service in Azure Portal
- Get connection string from service keys
- Set
AZURE_WEB_PUBSUB_CONNECTIONenvironment variable - Deploy applications to preferred hosting service
# Example Dockerfile for server
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY dist/ ./dist/
EXPOSE 3001
CMD ["npm", "start"]- Frontend: Vercel, Netlify, Azure Static Web Apps
- Backend: Azure App Service, AWS Lambda, Railway, Heroku
- WebSocket: Azure WebPubSub, AWS API Gateway WebSocket, self-hosted
This project is designed to teach modern web development concepts:
- Functional components with hooks
- Custom hooks for reusable logic
- State management patterns
- TypeScript integration with React
- Performance optimization techniques
- Real-time data handling
- Express.js REST API development
- WebSocket server implementation
- Azure cloud services integration
- Environment-based configuration
- Error handling and resilience patterns
- API design and consumption
- Real-time communication patterns
- Type safety across frontend/backend
- Development vs production configuration
- Monorepo project structure
This project includes extensive comparisons and explanations for developers transitioning from:
- Composition API β React Hooks patterns
- Template syntax β JSX differences
- Reactivity β State management approaches
- Component architecture comparisons
- Routing pattern differences
- Middleware implementation
- Environment configuration
- API development practices
- INTERVIEW_GUIDE.md - Comprehensive technical interview preparation
- server/README.md - Backend architecture and Express.js patterns
- web/README.md - Frontend architecture and React patterns
- Inline comments - Detailed explanations throughout the codebase
// Automatic environment detection
if (process.env.AZURE_WEB_PUBSUB_CONNECTION) {
// Production: Use Azure WebPubSub
azureService = new WebPubSubServiceClient(connectionString, hubName);
} else {
// Development: Use mock WebSocket server
mockWebSocketServer.start();
}// Encapsulates WebSocket logic in reusable hook
function useWebPubSub(room: string) {
const [connected, setConnected] = useState(false);
const [messages, setMessages] = useState<ChatMsg[]>([]);
useEffect(() => {
// Connection setup and cleanup
}, [room]);
return { connected, messages };
}// Shared types ensure consistency
type ChatMsg = {
user: string;
text: string;
ts: number;
};
// Used across frontend, backend, and WebSocket messages- React components with React Testing Library
- Custom hooks with testing utilities
- API endpoints with supertest
- WebSocket functionality with mock clients
- Full chat flow end-to-end
- Connection fallback testing
- Error scenarios validation
# Test REST endpoints
curl http://localhost:3001/negotiate
curl -X POST http://localhost:3001/chat -d '{"room":"test","user":"Test","text":"Hello"}'
# Test WebSocket with wscat
npm install -g wscat
wscat -c "ws://localhost:3002?user=TestUser"- useMemo for expensive computations
- Component memoization for stable renders
- Bundle splitting with Vite
- Tree shaking for minimal bundle size
- Connection pooling for WebSocket clients
- Memory-efficient data structures (Set/Map)
- Automatic cleanup of dead connections
- Horizontal scaling ready architecture
- Automatic reconnection on connection loss
- Message queuing during disconnections
- Connection state management
- Graceful error handling
- JWT token support in negotiate endpoint
- User identity validation
- Rate limiting for API endpoints
- CORS properly configured
- TypeScript compile-time validation
- Runtime validation for API inputs
- XSS prevention with proper escaping
- Message sanitization
- Environment variables for secrets
- HTTPS/WSS for encrypted communication
- Azure managed identity for cloud resources
- Access key rotation best practices
Connection Refused
# Check if servers are running
curl http://localhost:3001/negotiate
lsof -i :3001 # Check port usageWebSocket Connection Failed
# Verify mock server
lsof -i :3002
# Check browser console for connection errorsTypeScript Compilation Errors
# Check TypeScript configuration
npm run build
# Verify all imports and type definitionsAzure WebPubSub Issues
- Verify connection string format
- Check service status in Azure Portal
- Validate access key permissions
- Review service logs
# Enable verbose logging
DEBUG=* npm run dev
# TypeScript watch mode
npx tsc --watchWe welcome contributions! This project serves as a learning resource, so contributions that improve documentation, add educational value, or demonstrate best practices are especially appreciated.
- Fork the repository
- Create a feature branch
- Make your changes with proper TypeScript types
- Add/update documentation and comments
- Test your changes thoroughly
- Submit a pull request
- Use TypeScript with strict mode
- Follow ESLint recommendations
- Add comprehensive comments for educational value
- Include type definitions for all interfaces
- Write self-documenting code with clear naming
This project is open source and available under the MIT License.
- Clone repository and install dependencies
- Start both servers (backend + frontend)
- Open application in browser (localhost:5173)
- Send first message to test real-time functionality
- Review code structure and documentation
- Explore INTERVIEW_GUIDE.md for technical deep-dive
- Experiment with features and code modifications
- Deploy to cloud (optional) with Azure WebPubSub
Welcome to Chalice - your gateway to modern full-stack development with React and Azure!
This project is designed to be educational, production-ready, and a great addition to your portfolio. Happy coding!