A modern, interactive web application for discovering and building your ideal development technology stack. Browse through curated technologies across Frontend, Backend, Database, Language, Styling, and DevOps categories — and assemble your personalized stack with a single click.
🌐 Live Site: https://agent-6aa7a0f8c5c59a2b84dc1--dulcet-chaja-4a7ada.netlify.app/
| Tool | Purpose |
|---|---|
| React.js | UI component library |
| Vite | Lightning-fast build tool |
| Tailwind CSS v4 | Utility-first CSS framework |
| React Toastify | Toast notifications |
| Lucide React | Icon library |
| JavaScript (ES6+) | Application logic |
| JSON | Technology data source |
Browse 12 curated technologies with category badges, difficulty levels, star ratings, and color-coded chips. Each card dynamically updates to "✓ Added to Stack" once selected.
A real-time sidebar shows your selected technologies with remove buttons and a count indicator. It displays an elegant empty state when nothing is selected, and a "Remove All" button when items are present.
Uses React Toastify for contextual feedback — success toasts when adding, info toasts when removing, warning toasts for duplicate attempts, and error toasts when clearing the stack.
JSX stands for JavaScript XML. It lets you write HTML-like syntax directly inside JavaScript. React uses it because it makes UI code much easier to read and write — instead of calling React.createElement() for every element, you can write <button>Click me</button> and React converts it to the correct JavaScript under the hood.
Props are values passed into a component from its parent — they are read-only inside that component. State is data that lives inside a component and can change over time. When state changes, React re-renders the component. Think of props as function arguments and state as a component's own internal memory.
useState lets you add reactive variables to a functional component. When you call setStack(...), React re-renders the component with the new value. In this project I used it in:
App.jsx—const [stack, setStack] = useState([])to track which technologies the user has added.Navbar.jsx—const [menuOpen, setMenuOpen] = useState(false)to toggle the mobile hamburger menu.TechGrid.jsx—const [isLoading, setIsLoading] = useState(true)to show a spinner while JSON data loads.
useEffect runs a side-effect after the component renders. You need it for anything that happens outside normal rendering, like fetching data. In TechGrid.jsx, I used useEffect with an empty dependency array [] so it runs only once when the component first mounts — that's where I import() the JSON file and store the result in state.
React uses the key prop to efficiently track which items in a list changed, were added, or were removed. Without unique keys, React can't tell items apart and may re-render the wrong ones, causing bugs or slow performance. I used each technology's id field (e.g. "react", "docker") as the key since they are unique strings.
Conditional rendering means showing different UI based on a condition. In YourStack.jsx, I render the empty-state message only when the stack is empty:
{count === 0 && (
<div className="border-2 border-dashed ...">
Your stack is empty.
</div>
)}And the items list + Remove All button only appear when count > 0.
7. How do you pass data from a parent component to a child component, and how does a child send something back to the parent?
Data flows down from parent to child via props. For example, App.jsx passes stack and onAdd to TechGrid, and TechGrid passes them further down to each TechnologyCard. To send data back up, the parent passes a callback function as a prop. When the child calls onAdd(tech), it executes the function defined in the parent, which updates the parent's state. This is called "lifting state up."