From Static Pages to Dynamic Applications
🚀 Building the Future of Web Development
Let's travel through time and see how web development evolved...
Press ↓ to begin the journey
Static pages with just structure and content
<html>
<body>
<h1>Welcome to the Web!</h1>
<p>This is a static page.</p>
</body>
</html>
Separation of content and presentation
body {
font-family: Arial, sans-serif;
background-color: #f0f0f0;
}
h1 {
color: #333;
text-align: center;
}
Dynamic behavior and user interactions
function showMessage() {
alert('Hello, Interactive Web!');
}
document.getElementById('button')
.addEventListener('click', showMessage);
Structured applications with MVC architecture
angular.module('myApp', [])
.controller('MyController', function($scope) {
$scope.message = 'Hello Angular World!';
});
Reusable components and virtual DOM
function Welcome({ name }) {
return <h1>Hello, {name}!</h1>;
}
function App() {
return <Welcome name="React World" />;
}
Server-side rendering, API routes, and more!
// pages/api/hello.js
export default function handler(req, res) {
res.status(200).json({ message: 'Hello from Next.js!' });
}
// pages/index.js
export default function Home({ data }) {
return <h1>{data.message}</h1>;
}
Building both ends of the application spectrum
👆 Frontend (What users see)
⚡
👇 Backend (What powers it all)
User Interface & Experience
Visual design • User interactions • Data presentation
HTML, CSS, JavaScript, ReactLogic, Data & Infrastructure
Business logic • Database operations • API endpoints
Node.js, Express, Databases, APIs
UI/UX Design
Component Architecture
State Management
API Development
Database Design
Server Management
A stack is your chosen set of technologies that work together
Think of it like choosing your tools for a specific job
The foundation where all your data lives and breathes
The brain that processes logic and handles requests
The beautiful face users interact with every day
The environment where everything comes alive
Different combinations for different needs
Linux, Apache, MySQL, PHP
Traditional web developmentMongoDB, Express, React, Node.js
Modern JavaScript ecosystemDjango, PostgreSQL, Python
Rapid development with PythonRails, PostgreSQL, Ruby
Convention over configurationWhat are you building?
What does your team know?
How fast does it need to be?
How will it grow?
How quickly do you need to ship?
What can you afford?
Let's see what each layer looks like in practice
import React, { useState, useEffect } from 'react';
import './UserProfile.css';
// UserProfile component with full CRUD functionality
function UserProfile({ userId }) {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
// Fetch user data on component mount
useEffect(() => {
const fetchUser = async () => {
try {
const response = await fetch(`/api/users/${userId}`);
if (!response.ok) throw new Error('User not found');
const userData = await response.json();
setUser(userData);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchUser();
}, [userId]);
// Handle user data updates
const updateUser = async (updatedData) => {
try {
const response = await fetch(`/api/users/${userId}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(updatedData)
});
const updatedUser = await response.json();
setUser(updatedUser);
} catch (err) {
setError('Failed to update user');
}
};
if (loading) return <div className="spinner">Loading...</div>;
if (error) return <div className="error">Error: {error}</div>;
return (
<div className="user-profile">
<div className="profile-header">
<img src={user.avatar} alt={user.name} className="avatar" />
<h2>{user.name}</h2>
<p className="email">{user.email}</p>
</div>
<div className="profile-details">
<p><strong>Joined:</strong> {new Date(user.joinDate).toLocaleDateString()}</p>
<p><strong>Posts:</strong> {user.postCount}</p>
<p><strong>Status:</strong> {user.isActive ? 'Active' : 'Inactive'}</p>
</div>
<button onClick={() => updateUser({ ...user, lastSeen: new Date() })}>
Mark as Seen
</button>
</div>
);
}
export default UserProfile;
const express = require('express');
const cors = require('cors');
const helmet = require('helmet');
const rateLimit = require('express-rate-limit');
const User = require('./models/User');
// Initialize Express app with middleware
const app = express();
app.use(helmet()); // Security headers
app.use(cors()); // Enable CORS
app.use(express.json({ limit: '10mb' })); // Parse JSON bodies
app.use(express.static('public')); // Serve static files
// Rate limiting middleware
const limiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 100 // limit each IP to 100 requests per windowMs
});
app.use('/api/', limiter);
// GET user by ID with full profile data
app.get('/api/users/:id', async (req, res) => {
try {
const userId = req.params.id;
const user = await User.findById(userId)
.populate('posts')
.select('-password'); // Exclude sensitive data
if (!user) {
return res.status(404).json({
error: 'User not found',
code: 'USER_NOT_FOUND'
});
}
// Add computed fields
const userWithStats = {
...user.toObject(),
postCount: user.posts.length,
isActive: user.lastSeen > new Date(Date.now() - 24 * 60 * 60 * 1000)
};
res.json(userWithStats);
} catch (error) {
console.error('Database error:', error);
res.status(500).json({
error: 'Internal server error',
code: 'DATABASE_ERROR'
});
}
});
// PUT update user profile
app.put('/api/users/:id', async (req, res) => {
try {
const userId = req.params.id;
const updates = req.body;
// Validate and sanitize updates
const allowedUpdates = ['name', 'email', 'bio', 'lastSeen'];
const filteredUpdates = Object.keys(updates)
.filter(key => allowedUpdates.includes(key))
.reduce((obj, key) => ({ ...obj, [key]: updates[key] }), {});
const updatedUser = await User.findByIdAndUpdate(
userId,
filteredUpdates,
{ new: true, runValidators: true }
).select('-password');
if (!updatedUser) {
return res.status(404).json({ error: 'User not found' });
}
res.json(updatedUser);
} catch (error) {
res.status(400).json({ error: error.message });
}
});
// Start server
const PORT = process.env.PORT || 3001;
app.listen(PORT, () => {
console.log(`🚀 Server running on port ${PORT}`);
});
-- Create users table with constraints and indexes
CREATE TABLE users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL CHECK(length(name) > 0),
email TEXT UNIQUE NOT NULL CHECK(email LIKE '%@%.%'),
bio TEXT DEFAULT '',
avatar_url TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP,
last_seen DATETIME DEFAULT CURRENT_TIMESTAMP,
is_active BOOLEAN DEFAULT 1
);
-- Create posts table with foreign key relationship
CREATE TABLE posts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id INTEGER NOT NULL,
title TEXT NOT NULL,
content TEXT NOT NULL,
published BOOLEAN DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
);
-- Create indexes for better query performance
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_active ON users(is_active, last_seen);
CREATE INDEX idx_posts_user ON posts(user_id);
CREATE INDEX idx_posts_published ON posts(published, created_at);
-- Insert sample data with transaction
BEGIN TRANSACTION;
INSERT INTO users (name, email, bio) VALUES
('John Doe', 'john@example.com', 'Full-stack developer'),
('Jane Smith', 'jane@example.com', 'UI/UX Designer'),
('Bob Johnson', 'bob@example.com', 'DevOps Engineer');
INSERT INTO posts (user_id, title, content, published) VALUES
(1, 'Getting Started with React', 'React is a powerful...', 1),
(1, 'Advanced Node.js Patterns', 'In this post...', 1),
(2, 'Design Systems 101', 'Creating consistent...', 1);
COMMIT;
-- Complex query: Get user with post statistics
SELECT
u.id,
u.name,
u.email,
u.created_at,
COUNT(p.id) as post_count,
MAX(p.created_at) as latest_post,
CASE
WHEN u.last_seen > datetime('now', '-1 day') THEN 'active'
ELSE 'inactive'
END as status
FROM users u
LEFT JOIN posts p ON u.id = p.user_id AND p.published = 1
WHERE u.is_active = 1
GROUP BY u.id, u.name, u.email, u.created_at, u.last_seen
ORDER BY post_count DESC, u.created_at DESC;
-- Update user last seen timestamp
UPDATE users
SET last_seen = CURRENT_TIMESTAMP,
updated_at = CURRENT_TIMESTAMP
WHERE id = ?;
Next.js + Turborepo + Express + SQLite
Full-Stack React Framework
Utility-First CSS Framework
Monorepo Build System
JavaScript Runtime
Database API Server
Embedded Database
Next.js provides full‑stack capabilities out of the box
Turborepo accelerates builds with smart caching
Tailwind CSS enables instant UI development
SQLite works immediately — no setup required
Scales from prototype to enterprise architecture
Battle‑tested tools used worldwide
UI, API routes, and server‑side rendering
Dedicated database API server
Efficient multi‑package coordination
Add, edit, and complete tasks
Organize by lists or tags
Local DB via Express API
Ready to build something amazing? 🚀
Let's build our full stack application!
🎯 Next: Live Coding Session
⏱️ Duration: 45 minutes
🚀 From zero to deployed app!
📱 Scan the QR code
💻 Or visit the repo directly
github.com/MelodicAlbuild/
hackuta-website-template