Project archive

Full-stack and browser-native case studies

Detailed write-ups sourced from audited repositories — frontend architecture, API design, local runtimes, and deployment choices.

Full-stack PWALive

A production-oriented PWA demonstrating real-world product engineering: auth, RBAC, offline sync, reminders, testing, deployment, and observability.

Mobile-first PWA for logging newborn care events with multi-caregiver sync, offline outbox, and a FastAPI + MongoDB backend.

  • React
  • TypeScript
  • TanStack Router
  • FastAPI
  • +3 more
Problem

Caregivers need a fast phone-first way to log feeds, diapers, sleep, and health events—and share that timeline with partners without losing data when connectivity drops.

Frontend work
  • React 19 SPA with TanStack Router and 20+ file-based routes
  • IndexedDB offline outbox with sync-on-reconnect and client ID remapping
  • HttpOnly cookie auth client with CSRF headers and silent refresh
  • PWA install manifest, shortcuts, and service worker reminders
  • English/Hebrew i18n with RTL and voice log via Web Speech API
Backend & system work
  • FastAPI REST API with 25+ v1 route modules and OpenAPI docs
  • MongoDB repository layer with JWT cookie auth and owner/caregiver/viewer RBAC
  • Web Push reminders (VAPID) with secured external cron job endpoint
  • Production on AWS Lightsail: Docker Compose stack with Caddy reverse proxy/TLS, backend API, and Redis
  • Observability on the VPS: Prometheus, Loki/Promtail, Grafana, Node Exporter, and cAdvisor
  • GitHub Actions CI: pytest (70% coverage gate), Vitest, and Playwright E2E
Key decisions
  • HttpOnly cookie sessions instead of localStorage JWT storage
  • IndexedDB offline outbox for mutation queueing and ID remap after sync
  • Cloudflare Pages frontend with API on AWS Lightsail behind Caddy (ports 80/443 only)
  • External HTTP cron for reminder push dispatch in production
Challenges
  • Offline-first mutation queue with ordered flush and temporary ID remapping
  • Cross-origin cookie auth between Cloudflare Pages frontend and Lightsail-hosted API
  • Multi-caregiver invite flows with viewer read-only enforcement
Tech stack
Frontend
  • React 19
  • TypeScript
  • Vite
  • TanStack Router
  • TanStack Query
  • Tailwind CSS
  • Radix UI
  • i18next
  • vite-plugin-pwa
Backend
  • FastAPI
  • Motor
  • PyMongo
  • Celery
  • Redis
  • pywebpush
  • Resend
Data
  • MongoDB
  • IndexedDB
Infrastructure
  • Docker Compose
  • Cloudflare Pages
  • AWS Lightsail
  • Caddy
  • MongoDB Atlas
  • Prometheus
  • Grafana
  • Loki
  • GitHub Actions
Testing
  • Vitest
  • pytest
  • Playwright
Tooling
  • Bun
  • ESLint
  • Prettier
  • Ruff
Browser APIs
  • Web Speech API
  • Web Push
  • Service Worker
Local-first AI stackIn progress

Technical lab exploring local AI workflows, typed contracts, streaming UX, and Docker-based development environments.

Local-first AI chat monorepo: TanStack Start frontend, FastAPI backend, PostgreSQL/pgvector, MinIO, and Ollama inference via Docker Compose.

  • TanStack Start
  • React
  • FastAPI
  • PostgreSQL
  • +3 more
Problem

Most AI chat tools depend on hosted APIs. This project runs chat, persistence, and inference entirely on localhost with a one-command dev stack.

Frontend work
  • TanStack Start chat UI with session sidebar, SSE streaming, and optimistic messages
  • Three-column layout with mobile drawers and react-virtual for long transcripts
  • OpenAPI codegen into shared TypeScript contracts
  • Roleplay template management route with CRUD forms
Backend & system work
  • FastAPI layered routes, services, repositories, and Alembic migrations
  • PostgreSQL + pgvector for chat and embedding metadata; MinIO for image binaries
  • Ollama client with model allowlist and optional CrewAI orchestration backends
  • Docker Compose stack: Ollama, PostgreSQL, MinIO, API, and model pull jobs
Key decisions
  • Docker Compose brings up the full backend stack with one `bun run local:start` command
  • Shared `@local/shared` package keeps frontend and backend request shapes aligned
  • SSE streaming with optimistic UI instead of waiting for full completion responses
Challenges
  • SSE client parsing with optimistic pending/streaming/failed message states
  • Orchestration trace storage separate from user-visible chat messages
  • Local-only security tradeoffs documented (no auth in default configuration)
Tech stack
Frontend
  • TanStack Start
  • React 19
  • TanStack Router
  • TanStack Query
  • Vite
  • Tailwind CSS
Backend
  • FastAPI
  • SQLAlchemy
  • Alembic
  • Uvicorn
Data
  • PostgreSQL
  • pgvector
  • MinIO
Infrastructure
  • Docker Compose
  • Bun workspaces
Testing
  • Vitest
  • Playwright
  • pytest
AI / ML
  • Ollama
  • CrewAI (optional)
Local ML workspaceIn progress

Local image-generation lab combining a React studio UI, FastAPI GPU orchestration, canvas preprocessing, and typed multipart API flows.

Local Stable Diffusion workspace with a React dashboard, FastAPI orchestration, and a dedicated GPU subprocess for text-to-image and image-to-image generation.

  • React
  • TypeScript
  • FastAPI
  • Stable Diffusion
  • +3 more
Problem

Running image models locally means juggling checkpoints, Python environments, GPU diagnostics, and a usable UI. This project wraps that into one coordinated app.

Frontend work
  • React dashboard for generation, gallery, runtime diagnostics, and image-to-image editor
  • Canvas-based crop/color preprocessing plus server-side Pillow tool endpoints
  • Typed API client for JSON and multipart flows with Vitest component coverage
Backend & system work
  • FastAPI routes with subprocess `diffusers` runner in a dedicated model venv
  • Generation lock and CUDA OOM retry with smaller preset sizes
  • Optional API key, CORS origin checks, and upload validation for local-but-exposed use
  • Filesystem output storage under `outputs/generated`
Key decisions
  • Isolate GPU inference in a subprocess/venv so the API stays fast and testable
  • Allowlisted model IDs instead of arbitrary filesystem paths from the client
  • Split instant browser edits from heavier Pillow tools before image-to-image runs
Challenges
  • Orchestrating reliable local GPU pipelines across two Python environments and a web UI
  • Canvas mask retouch workflow with backend blur/median fill
  • Keeping frontend types aligned with Pydantic schemas across JSON and multipart routes
Tech stack
Frontend
  • React 19
  • TypeScript
  • Vite
  • Vitest
  • Testing Library
Backend
  • FastAPI
  • Uvicorn
  • Pydantic Settings
  • Pillow
Data
  • Local filesystem
Infrastructure
  • PowerShell dev scripts
Testing
  • Vitest
  • pytest
AI / ML
  • Stable Diffusion 1.5
  • diffusers
  • Realistic Vision checkpoint
Browser APIs
  • Canvas
  • Fetch
  • FormData
Links
Browser utilityLive

Browser hardware-control experiment using Web Bluetooth, serialized GATT commands, and accessible UI states.

Single-file browser app that pairs with generic BLE LED strips over Web Bluetooth—color, brightness, power, and multi-protocol debugging with no native app or backend.

  • Web Bluetooth
  • Petite-Vue
  • Tailwind CSS
  • iro.js
  • +2 more
Problem

Generic BLE LED strips often ship with closed or mobile-only vendor apps. This utility talks to compatible strips from Chromium on HTTPS with runtime protocol tuning.

Frontend work
  • Petite-Vue reactive UI with iro.js color wheel and responsive glassmorphism layout
  • Web Bluetooth pairing, GATT discovery, throttled writes, and serialized command chain
  • Pluggable protocol profiles, channel order, and debug panel with storage CRUD
  • Accessibility hooks: aria-live, aria-label, labeled inputs
Backend & system work
  • No backend — GitHub Actions CI with zero npm install static tests
  • GitHub Pages deploy publishes `src/` directly with no build step
Key decisions
  • Single HTML file with no build step for trivial static hosting and direct device control
  • Throttled and serialized BLE writes to avoid overlapping GATT operations
Challenges
  • Web Bluetooth requires HTTPS, user gesture, and Chromium — with clear unsupported-context warnings
  • Protocol fragmentation across command families, channel orders, and write modes
  • Characteristic discovery across many known service/characteristic pairs
Tech stack
Frontend
  • HTML5
  • Petite-Vue
  • Tailwind CSS (CDN)
  • iro.js
  • Font Awesome
Infrastructure
  • GitHub Pages
  • GitHub Actions
Testing
  • Node.js built-in test runner
Browser APIs
  • Web Bluetooth
  • localStorage
  • Clipboard API
Full-stack prediction markets UIIn progress

A Polymarket-style markets browser built on Next.js 16, wiring real Gamma/CLOB/Data API feeds through server caches into a Jotai + React Query frontend with WebSocket live prices and Recharts history.

Bolymarket is a Next.js 16 Polymarket-style prediction markets UI that proxies Polymarket’s Gamma, CLOB, and Data APIs through cached BFF routes, streams live outcome prices over WebSocket with simulation fallback, and splits structural data (React Query) from tick-level prices (Jotai).

  • Next.js
  • React
  • TypeScript
  • Tailwind CSS
  • +5 more

Bolymarket recreates Polymarket’s homepage and event-detail experience as a read-only Next.js app. Structural market data flows through TanStack Query (persisted to IndexedDB); live outcome probabilities update via Polymarket’s activity WebSocket into per-outcome Jotai atoms, with client-side simulation when the socket is unavailable.

Problem

Polymarket’s product surface is complex (category navigation, live odds, charts, sports, mobile chrome), and building a faithful read-only experience requires careful separation of static event data from high-frequency price updates without melting the React tree.

Frontend work
  • Built 7 App Router pages: /, /crypto, /sports, /sports/live, /politics, /event/[slug], /api-docs
  • Implemented Polymarket-faithful app chrome: TopBar, CategoryNav, Footer, MobileBottomNav, search toolbar
  • Split state: Jotai for filters/bookmarks/theme/live prices; TanStack React Query for events and chart history
  • Rendered BinaryCard, MultiOutcomeCard, SportsMatchCard, featured carousel, and category page layouts
  • Built event detail with Recharts PriceChart, timeframe toggles, related news, share/embed, visual OrderTicket
  • Wired live prices via shared livePriceEngineManager with leaf-only subscriptions and reduced-motion support
  • Styled with Tailwind CSS v4 semantic tokens, dark mode, and Motion for modal transitions
  • Added debounced client search, localStorage bookmarks, and URL-synced category navigation
Backend & system work
  • Implemented 7 Next.js BFF routes proxying Gamma, CLOB, Data API, sports live, and related news
  • Normalized all upstream responses with Zod schemas; thin route handlers delegate to lib/api modules
  • Added server-side caching with optional Redis (REDIS_URL) and in-memory fallback
  • Built GDELT news fetch with OkSurf fallback and 5-minute server cache
  • Published OpenAPI 3.0 spec at /api/openapi with Swagger UI at /api-docs
  • Configured Next.js image remotePatterns for Polymarket CDN assets
  • Deployed on Vercel (bun install --frozen-lockfile, bun run build); no CI workflow in repo
  • Env vars: REDIS_URL (optional), NEXT_PUBLIC_LIVE_PRICE_MODE (auto | websocket | simulation)
Key decisions
  • React Query for structural event data, Jotai atom families for live prices — prevents tick-driven query invalidation
  • BFF API routes instead of direct browser calls — centralizes validation, caching, and upstream shape handling
  • Polymarket activity WebSocket with 2s simulation fallback in auto mode — UX without full CLOB order book
  • Per-outcome outcomePriceAtomFamily with RAF coalescing — minimizes re-render scope on price ticks
  • Recharts fed by CLOB history with generateChartData simulated fallback when upstream is sparse
  • IndexedDB persistence for React Query via @tanstack/react-query-persist-client and idb-keyval
Challenges
  • High-frequency price updates without grid re-renders — Jotai leaf subscriptions, React.memo, documented profiler targets
  • WebSocket reliability — reconnect, ping, subscription index by event_slug, simulation engine fallback
  • Sports live complexity — separate sportsWebSocketEngine, game state atoms, league aggregation (phase in progress)
  • CLOB chart sparsity — merge logic plus simulated series; latest point synced to live atoms
  • Chrome fidelity vs. scope — many nav/footer links are visual-only placeholders
Tech stack
Frontend
  • Next.js 16.2.9
  • React 19.2.4
  • Tailwind CSS v4
  • Jotai ^2.20.1
  • TanStack React Query ^5.101.0
  • Recharts ^3.8.1
  • Motion ^12.40.0
  • Lucide React ^1.18.0
Backend
  • Next.js Route Handlers (BFF)
  • redis ^6.0.0 (optional)
Data
  • Polymarket Gamma REST API
  • Polymarket CLOB /prices-history
  • Polymarket Data API /trades
  • @polymarket/real-time-data-client ^1.4.0
  • Polymarket sports WebSocket
  • GDELT + OkSurf news
  • Zod ^4.4.3
  • idb-keyval ^6.2.5
Infrastructure
  • Vercel
  • Bun (recommended runtime)
  • Optional Redis (REDIS_URL)
Testing
  • Vitest ^4.1.9
  • React Testing Library ^16.3.2
  • jsdom ^29.1.1
  • 119 Vitest test files
Tooling
  • TypeScript ^5 (strict)
  • ESLint ^9 + eslint-config-next 16.2.9
  • Prettier ^3.8.4
Browser APIs
  • WebSocket
  • IndexedDB
  • localStorage
  • Web Share API
  • prefers-reduced-motion
  • requestAnimationFrame
Previous portfolioLive

Content-first portfolio SPA demonstrating schema-validated JSON pipelines, searchable case studies, visualization galleries, and static deployment with minimal serverless routing.

A React/TypeScript portfolio SPA for data analysis case studies, using Zod-validated JSON content, searchable project pages, visualization galleries, and a minimal Vercel serverless geo-block route.

  • React
  • TypeScript
  • Vite
  • Bun
  • +10 more

An earlier personal portfolio built to present data analysis case studies as structured, searchable content — static frontend, validated data pipeline, and one serverless route for geo IP checks.

Problem

I needed a portfolio for presenting data analysis work and project visualizations without running a CMS or database. Content stays in validated JSON, deploys as a static SPA, and only uses backend code where a server-side secret is required.

Frontend work
  • React 19 + TypeScript + Vite SPA with lazy-loaded routes
  • Theme UI design system with light/dark mode
  • Searchable and filterable project grid
  • Project detail pages with case-study structure and plot carousel
  • Static content pipeline using JSON, Zod schemas, and Vite asset resolution
  • Contact page with React Hook Form, Getform submission, clipboard copy, and resume download
  • SEO metadata with react-helmet-async, sitemap, robots, and Vercel Speed Insights
  • Accessibility details including skip link, reduced-motion styles, and ARIA feedback states
Backend & system work
  • Minimal Vercel serverless handler for GET /api/geo-block
  • Abstract API IP geolocation used server-side so the API key stays private
  • Vercel routing that sends /api/* to the serverless handler and the rest to the static frontend
  • Client-side Getform submission for contact messages
Key decisions
  • Used JSON + Zod instead of a CMS/database to keep content git-reviewable and statically deployable
  • Kept backend scope intentionally minimal — only serverless code where secrets must remain server-side
  • Used Zustand as a lightweight access layer over validated static content
  • Lazy-loaded routes and heavier UI pieces to keep the SPA structure cleaner
  • Used Vercel to deploy a static frontend and one serverless route from the same repo
Challenges
  • Keeping content integrity without a CMS
  • Resolving local asset references into Vite build output
  • Coordinating static frontend routing with a minimal serverless backend
  • Keeping Theme UI and React Bootstrap components visually consistent
  • Making geo-blocking fail open so the site still renders when the external API is unavailable
Tech stack
Frontend
  • React 19
  • TypeScript
  • Vite
  • React Router
  • Theme UI
  • React Bootstrap
  • Framer Motion
  • Zustand
  • Zod
  • React Hook Form
  • react-helmet-async
Backend
  • Vercel serverless Node handler
Data
  • Local JSON content files
Infrastructure
  • Vercel
  • Vercel Speed Insights
Tooling
  • Bun
  • TypeScript
  • Vite
Browser APIs
  • Clipboard API
  • fetch