MarketMind: A Project Story
The Inspiration
It all started with a simple realization: the stock market feels intimidating to beginners. Every time we talked to our friends about investing, the conversation would end the same way "I'd love to invest, but I'm terrified of losing money." They weren't afraid of the concept of investing; they were afraid of the cost of learning. I watched tutorial videos on YouTube where people would explain stock trading principles, and I thought: What if they could practice without the real money? What if there was a place where anyone from a curious teenager to a career-shifter could learn the fundamentals of stock trading risk-free?
That's when MarketMind was born. Not just as an app, but as a learning platform with zero stakes and maximum insight.
The mission was clear: democratize financial literacy by removing the barrier to entry. No account verification. No real money. Just $10,000 in virtual cash and real market prices.
What we have Learned
Building MarketMind taught us far more than we expected. Here are the key lessons:
1. API Integration is More Complex Than It Looks
Initially we thought connecting to Finnhub's stock API would be straightforward. It wasn't.
- Rate limiting was my first wake-up call. Free tier limits meant I had to implement intelligent caching strategies.
- Error handling became critical what happens when the API goes down? When a user searches for an invalid ticker? These edge cases are what separate rough prototypes from production-ready apps.
- I learned to implement exponential backoff for retries and cache data for 30 minutes to optimize API calls.
2. State Management in Vanilla JavaScript is Underrated
Coming from a world where frameworks handle state, managing application state in vanilla JavaScript was humbling. Without Redux or Context API, I had to build my own system:
$$\text{Portfolio State} = { \text{holdings}, \text{transactions}, \text{balance}, \text{lastUpdated} }$$
This meant:
- Carefully designing data structures from the start
- Implementing localStorage persistence
- Building a manual "event system" to keep the UI in sync with data changes
It made me appreciate how much work frameworks do behind the scenes.
3. Design Systems Matter More Than I Realized
When I started, I just picked random colors. But as the project grew with 7 pages, inconsistency became a nightmare. Implementing Material Design 3 principles changed everything:
The 60-30-10 color rule became my North Star:
$$\text{Color Distribution} = 60\% \text{ (Primary)} + 30\% \text{ (Secondary)} + 10\% \text{ (Accent)}$$
Where:
- 60% = White space (breathing room, clarity)
- 30% = Dark Blue #003285 (headers, navigation, key sections)
- 10% = Green #4CAF50 (CTAs, highlights, interactions)
This single principle transformed the UI from chaotic to cohesive.
4. User Experience is About Friction
The smallest details matter:
- Material Symbols icons make the interface feel polished
- Smooth transitions and hover states feel responsive
- Clear error messages prevent confusion
- A $10,000 starting balance feels realistic without being overwhelming
How We Built It
Phase 1: Foundation (Concept → MVP)
started with the core question: What does a minimal stock trading app need?
Core MVP Features:
- Create an account (localStorage-based for simplicity)
- Search for a stock by ticker
- Buy/sell at current market price
- View portfolio with P&L calculations
// The heart of it all - calculating portfolio performance
function calculatePortfolioMetrics() {
let totalValue = accountBalance;
let totalCost = 0;
holdings.forEach(holding => {
totalValue += holding.quantity * holding.currentPrice;
totalCost += holding.quantity * holding.avgCost;
});
const totalGainLoss = totalValue - (initialBalance + totalCost);
const returnPercentage = (totalGainLoss / (initialBalance + totalCost)) * 100;
return { totalValue, totalGainLoss, returnPercentage };
}
Phase 2: Scaling (MVP → Full Feature Set)
Once the core worked, I added:
- Dashboard - dedicated trading interface with real-time price updates
- Portfolio page - detailed holdings analysis + Chart.js visualization
- Markets page - market exploration and stock discovery
- Settings/Profile - future user customization
- Mobile responsiveness - Tailwind's responsive utilities made this manageable
Phase 3: Polish (Visual & UX Refinement)
This is where MarketMind went from "functional" to "delightful":
- Designed the landing page - told the story of why MarketMind exists
- Implemented Material Design 3 - consistent color scheme, typography, spacing
- Refined the trading experience - clear buy/sell flows, instant confirmation feedback
- Optimized for beginners - tooltips, quick tips, demo mode with pre-loaded data
Technical Stack Decisions
| Layer | Choice | Why |
|---|---|---|
| Frontend | Vanilla JS + HTML + CSS | No build step needed, ultimate transparency |
| Styling | Tailwind CSS | Utility-first approach = fast iteration |
| Data | localStorage | No backend required, data persists across sessions |
| API | Finnhub | Free tier, reliable, covers 100+ stocks |
| Charts | Chart.js | Lightweight, straightforward API |
| Design Icons | Material Symbols | Google's comprehensive, well-maintained |
Challenges Faced
Challenge 1: The API Cost vs. Performance Trade-off
The Problem: Every search required an API call to Finnhub, and I had limited free tier requests.
The Solution: Implement aggressive caching with smart invalidation:
- Cache prices for 30 minutes
- Only fetch new data when cache expires
- Batch multiple requests when possible
- Show cached price with a "last updated" timestamp
Lesson Learned: Sometimes the best optimization is knowing when not to fetch data.
Challenge 2: State Management Complexity
The Problem: With multiple pages sharing state (balance, holdings, transactions), keeping everything in sync became complicated.
Without a centralized state management solution, I faced:
- Stale data across pages
- Inconsistent balance calculations
- Bug-prone manual syncing
The Solution: Built a simple event-driven architecture:
class StateManager {
constructor() {
this.state = this.loadState();
this.listeners = [];
}
updateState(changes) {
this.state = { ...this.state, ...changes };
this.saveState();
this.notifyListeners();
}
subscribe(callback) {
this.listeners.push(callback);
}
notifyListeners() {
this.listeners.forEach(callback => callback(this.state));
}
}
This single-source-of-truth pattern eliminated entire categories of bugs.
Challenge 3: Responsive Design Complexity
The Problem: Creating 7 pages that worked flawlessly on mobile, tablet, and desktop seemed daunting.
The Solution: Embraced Tailwind's mobile-first responsive utilities:
md:breakpoint for tabletslg:breakpoint for desktopshidden md:flexpatterns for conditional rendering- CSS Grid with
grid-cols-1 md:grid-cols-2 lg:grid-cols-3
This systematic approach meant I could design once and it worked everywhere.
Challenge 4: The "No Backend" Limitation
The Problem: Without a backend/database:
- Prices don't update automatically (requires page refresh or manual search)
- No user persistence across devices
- No analytics or historical data (except in localStorage)
- Data resets if browser data is cleared
The Tradeoff: This limitation was also a feature—zero infrastructure costs, zero deployment complexity. Perfect for learning.
The Workaround: I documented this clearly. For a real-world version, adding a simple Node.js backend with WebSockets would fix the real-time updates problem.
Challenge 5: Making It Beginner-Friendly Without Being Condescending
The Problem: Educational apps often over-explain or under-explain. Finding the sweet spot was tricky.
The Solution:
- Quick Tips on the getting started section
- Demo Mode that pre-populates with sample trades
- Color-coded performance (green for gains, no red for scary losses)
- Named buttons with clear CTAs ("BUY 10 SHARES" not just "SUBMIT")
The goal: intuitive without hand-holding.
Challenge 6: Calculation Accuracy Under Pressure
The Problem: Financial calculations require absolute precision. Off-by-a-cent errors destroy trust.
Portfolio gain/loss calculation:
$$P&L = \left(\sum_{i=1}^{n} Q_i \times P_i^{\text{current}}\right) - \left(\sum_{i=1}^{n} Q_i \times P_i^{\text{avg_cost}}\right)$$
Where: $$Q_i \text{ = quantity of stock } i$$ $$P_i^{\text{current}} \text{ = current price of stock } i$$ $$P_i^{\text{avg cost}} \text{ = average cost basis of stock } i$$
The Solution:
- Used
toFixed(2)consistently for money - Tested with edge cases (0 holdings, negative P&L, fractional prices)
- Built unit tests for core calculations
- Documented the calculation logic in comments
Key Takeaways
What Went Right
✅ Core functionality works flawlessly - buying, selling, portfolio tracking all reliable
✅ Beginner-friendly UI - friends without tech backgrounds understand it immediately
✅ Zero infrastructure costs - pure client-side app means hosting is trivial
✅ Extensible architecture - easy to add new features or integrate a real backend
What I'd Do Differently
❌ Start with design system earlier - color/typography consistency would have saved time ❌ Build state management from day 1 - retrofitting it was painful ❌ Add unit tests sooner - manual testing doesn't scale ❌ Document edge cases upfront - building incrementally meant discovering gotchas late
The Impact
MarketMind exists to answer one question: How do you learn to invest without losing real money?
At its core, it's not about the technology. It's about removing friction from financial education. It's about a 16-year-old exploring investing strategies. It's about someone switching careers learning market dynamics. It's about anyone curious enough to click "Sign Up."
Every feature, every color choice, every animation—they all serve that mission.
What's Next?
The roadmap includes:
- 📱 Mobile app (React Native)
- 💬 Community features (leaderboards, strategy sharing)
- 🤖 AI-powered stock recommendations
- 📊 Advanced analytics (beta distribution, Sharpe ratio calculations)
- 🌐 Backend integration (persistent accounts, cloud sync)
But for now, MarketMind stands as proof that sometimes the best projects start with a simple idea and a willingness to learn every step of the way.
Built with curiosity, refined through challenges, and designed for everyone who's ever wanted to learn investing without the real stakes.
MarketMind: Where concepts become confidence.
Built With
- api
- html
- javascript
- vanilla
Log in or sign up for Devpost to join the conversation.