Inquisitive is a modern, structured learning workspace designed to convert user curiosity into comprehensive, actionable learning curriculums. By combining search capabilities with generative model pipelines, it transforms open-ended research topics into interactive Kanban learning boards loaded with high-quality articles, tutorial videos, and custom progress tracking.
Built as a modular monorepo using Express.js, React 18 (Vite), TypeScript, Drizzle ORM, Neon serverless PostgreSQL, and Upstash Redis, Inquisitive is engineered for rapid, structured knowledge mapping with production-grade speed, safety guardrails, and total type integrity.
The project is structured as a monorepo containing distinct, specialized packages:
| Module | Location | Primary Technologies | Purpose |
|---|---|---|---|
| Backend API | /backend |
Node.js, Express, TypeScript, Drizzle ORM, Upstash Rate Limiter | Handles the core generative pipeline, parses request payloads, manages database operations, and enforces API traffic limiters. |
| Frontend SPA | /frontend |
React 18, Vite, Zustand, Framer Motion, dnd-kit, Tailwind CSS, CSS Variables | Delivers a high-fidelity client interface with spring-loaded Kanban interactions, progress meters, and responsive layouts. |
Inquisitive is split into structured directories designed for clean decoupling, modular scaling, and type safety.
The client application utilizes a modern Feature-Based Architecture where components, views, and core assets are logically categorized by their functional domain:
frontend/
โโโ src/
โ โโโ assets/ # Brand visual assets (logos, loading animations, gifs)
โ โโโ config/ # App constants, REST base endpoints, and environment variables
โ โโโ context/ # Global React Context providers
โ โโโ features/ # Feature-Based Modules (Highly Modular & Decoupled)
โ โ โโโ auth/ # Authentication & anonymous profiling flow
โ โ โโโ LandingPage/ # Brand presentation components
โ โ โโโ dashboard/ # Core Hub Workspace
โ โ โ โโโ components/ # Sidebar, SearchSection, NotebooksSection, LoadingScreen
โ โ โโโ notebook/ # Interactive curriculum workspace
โ โ โโโ components/ # KanbanBoard, KanbanColumn, ResourceCard, StreakBadge, SkeletonCard
โ โโโ hooks/ # Shared global React hooks (e.g., useStreak)
โ โโโ layouts/ # App page structural wrappers
โ โโโ lib/ # Timezone-safe streak utility engines & helpers
โ โโโ pages/ # Top-level view router pages
โ โ โโโ HomePage.tsx # Generative prompt deck and path index overview
โ โ โโโ NotebookPage.tsx # Curated Kanban workspace page
โ โ โโโ LandingPage.tsx # Product showcase landing page
โ โ โโโ NotFoundPage.tsx # Custom 404 error handler
โ โโโ routes/ # Client-side router configuration
โ โโโ services/ # Axios API transaction wrappers
โ โโโ stores/ # Zustand global client-side state engines (e.g., kanbanStore)
โ โโโ styles/ # Global Vanilla CSS tokens, HSL typography & visual themes
โ โโโ types/ # Shared client TypeScript compiler interface definitions
โโโ index.html # Main single-page application entrypoint (contains SEO & Favicon)
โโโ package.json # Client packages, scripts index, and workspace bindings
The server-side application is built using a robust controller-service abstraction that isolates endpoints, data models, web crawlers, and AI orchestrators:
backend/
โโโ src/
โ โโโ config/ # Server setups (caching, CORS security profile, Redis rate-limiters)
โ โโโ controllers/ # HTTP request handlers & parser controllers
โ โ โโโ notebook.controller.ts
โ โ โโโ resource.controller.ts
โ โโโ db/ # Drizzle ORM database engine
โ โ โโโ index.ts # Neon Serverless postgres client connector
โ โ โโโ schema.ts # Strictly typed SQL table definitions (notebooks & resources)
โ โโโ middleware/ # CORS interceptors, IP rate-limiting guards, and logging gates
โ โโโ routes/ # Express router endpoints
โ โ โโโ index.ts # Parent route consolidator
โ โ โโโ notebook.route.ts
โ โ โโโ resource.route.ts
โ โโโ services/ # Business & orchestration workflows
โ โ โโโ ai.service.ts # Dual-stage curriculum generator prompt planner (Gemini/GROQ/OpenRouter)
โ โ โโโ search.service.ts # Parallel web search crawler & YouTube scraper API matches
โ โโโ types/ # Server-side TypeScript interface declarations
โ โโโ index.ts # Express application main runner and listener
โโโ drizzle/ # SQL schemas compiled into migration scripts
โโโ package.json # Server packaging, environment commands, and db syncs
โโโ tsconfig.json # Server TypeScript compilation parameters
Inquisitive is engineered as a serverless, decoupled monorepo designed for rapid, distributed cloud delivery. The live production environment is orchestrated across specialized high-performance platforms:
- Frontend Hosting (Vercel): Serves the highly optimized Vite single-page application React assets from Vercel's global edge network. Fully maps client-side browser routing rewrites through
vercel.json. - Backend Runtime (Render): Hosts the Express API server with automatic Git-triggered deployments, managing high-throughput traffic and parallel web-crawling/parsing operations.
- Serverless SQL (Neon Postgres): Powers the robust relational storage using Neon's serverless PostgreSQL engine, integrated with Drizzle ORM for automatic schema generation, migration mapping, and hot query execution.
- Serverless Cache (Upstash Redis): Provides low-latency key-value storing for IP-based rate limiting via the
@upstash/ratelimitorrate-limit-redislayers with elegant fail-open resiliency.
The relational database is structured around two core tables: notebook and resource.
| Field | Data Type | Constraints | Description |
|---|---|---|---|
| id | uuid |
Primary Key, defaultRandom() |
Unique identifier for each generated learning curriculum. |
| deviceId | varchar(36) |
Not Null | Identifies the client browser or machine that initiated the request. |
| createdAt | timestamp |
defaultNow(), With Timezone |
Records the execution timestamp of the planning request. |
| topic | varchar(255) |
Not Null | The primary subject or topic parsed by the AI Planner. |
| level | topic_level |
Not Null, Custom Enum | Difficulty tier: beginner, intermediate, or hard. |
| length | length |
Not Null, Custom Enum | Course depth / node count: short, medium, or long. |
| Field | Data Type | Constraints | Description |
|---|---|---|---|
| id | uuid |
Primary Key, defaultRandom() |
Unique identifier for the individual learning node. |
| notebookId | uuid |
Foreign Key, References notebook.id |
Establishes the relationship. Configured with cascading delete behavior. |
| title | text |
Not Null | Curated learning material title. |
| url | varchar(255) |
Not Null | Hyperlink leading to the video tutorial or article documentation. |
| thumbNail | text |
Nullable | Custom YouTube preview image (derived from YouTube API matches). |
| sourceType | source_type |
Not Null, Custom Enum | Type classification: article or video. |
| difficulty | difficulty |
Not Null, Custom Enum | Structural skill level ranking from 1 (simplest) to 5 (hardest). |
| status | status |
Not Null, Custom Enum | Kanban Board status state: todo, in_progress, completed, or skipped. |
| summary | text |
Nullable | Highly concise, action-focused 2-sentence curriculum description. |
| createdAt | timestamp |
defaultNow(), With Timezone |
Timestamp when resource was fetched and saved. |
| updatedAt | timestamp |
defaultNow(), With Timezone |
Tracks column transitions or manual metadata edits. |
The client interface utilizes a custom warm editorial design system mapped entirely in Vanilla CSS to avoid layout bloat.
| Token Group | Values / Variables | Application & Visual Experience |
|---|---|---|
| Background Color | #fdfbf7, bg-bento-warm |
Warm organic paper base mirroring physical textbook paper texture. |
| Typography Fonts | Outfit, Plus Jakarta Sans, Sora | Muted, high-contrast print headlines paired with readable UI labels. |
| Accents & Borders | #D4C4A8, border-bento, #7c3aed |
Golden sand borders combined with deep violet interactive icons. |
| Physics & Motion | Framer Motion, dnd-kit |
Spring-based Kanban node interactions and staggered card dealing. |
Here is an overview of the core application viewports. Keep these sections updated with screenshots of your current deployment:
The clean, minimalist landing workspace allows immediate input, structured filters, and error banner notifications if input validation fails.
When the AI orchestrator builds a notebook, resources are organized into an interactive Kanban board. Moving cards immediately recalculates the learning progress bar and syncs back to Neon.
For smaller viewports, columns smoothly stack into a responsive layout with touch-friendly dragging handles and a responsive bottom navigation.
(Screenshot Space: Place mobile_responsive_view.png here showing mobile column layouts)
Follow these steps to run a fully functional development environment locally.
| Prerequisite | Minimum Version | Required For |
|---|---|---|
| Node.js | 20.x (LTS) | Package runner, builds, and backend operations. |
| npm | 10.x | Monorepo workspaces management. |
| Docker Desktop | Latest | Running local caching/Redis clusters and emulators. |
| Variable | Recommended / Default Value | Purpose |
|---|---|---|
| PORT | 3000 |
Express API port. |
| NODE_ENV | development |
Enables debug loggers and verbose schema checking. |
| CLIENT_URL | "http://localhost:5173" |
Configures CORS allowed origin vectors. |
| DATABASE_URL | postgres://user:pass@ep-host.neon.tech/db |
Neon Serverless PostgreSQL connection string. |
| GROQ_API_KEY | your_GROQ_api_key |
Authenticates planner and enricher GROQ LLM queries (via the free tier API). |
or
| OPENROUTER_API | your_openrouter_api_key | Authenticates planner and enricher LLM queries. |
| TAVILY_API | your_tavily_api_key | Authenticates dual-source parallel web searches. |
| UPSTASH_REDIS_REST_URL | "http://upstash-local:80" | Points to Upstash emulator Rest URL inside Docker. |
| UPSTASH_REDIS_REST_TOKEN | "example_token_not_needed_locally" | Mock token for local Upstash emulator operations. |
| Variable | Default Value | Purpose |
|---|---|---|
| VITE_API_URL | "http://localhost:3000/api" |
Base client entrypoint for REST interactions. |
| VITE_PUBLIC_POSTHOG_KEY | "your_posthog_project_api_key" |
Ingestion key for PostHog client analytics. |
| VITE_PUBLIC_POSTHOG_HOST | "https://us.i.posthog.com" |
Ingestion host endpoint URL. |
The repository includes a customized Docker environment that runs a local Postgres-compatible Redis Stack (redis-stack) along with an Upstash HTTP Translator container (upstash-local), allowing @upstash/ratelimit to resolve without real Upstash Cloud credentials.
Boot all core database and caching services concurrently:
docker compose -f docker-compose.dev.yaml up --buildThis initializes:
- Redis Stack: Running on standard port
6379. - RedisInsight GUI: Available on port
8001for real-time key inspection. - Serverless Redis HTTP Emulator: Translation bridge available on port
8079(maps internal container port80).
Install all workspace dependencies from the root directory:
npm installBoot the frontend Vite server and backend Express server concurrently using workspace scripts:
npm run dev:frontend # Boots React + Vite Client (http://localhost:5173)
npm run dev:backend # Boots Express API Server (http://localhost:3000)Execute commands directly from the monorepo root:
| Command | Action | Workspace / Scope |
|---|---|---|
npm run dev:frontend |
Boots the Vite client environment with proxy mappings. | frontend |
npm run dev:backend |
Boots Express server with TS-Node-Dev live-reloading. | backend |
npm run build |
Builds and transpiles all client and backend production assets. | Monorepo Root |
The backend exposes these core routes under /api:
| Method | Route | Request Payload | Behavior / Function |
|---|---|---|---|
| GET | /getAll |
None | Retrieves all saved learning notebooks for the active device. |
| POST | /create |
{ topic: string, level: string, length: string } |
Triggers the dual-stage AI orchestrator pipeline to validate the query, plan skills, crawl the web, enrich resources, persist structures, and return the final JSON. |
| DELETE | /:id |
None | Deletes a notebook and cascades deletion to all associated resources. |
| Method | Route | Request Payload | Behavior / Function |
|---|---|---|---|
| GET | /:notebookId |
None | Retrieves all learning materials associated with a specific notebook. |
| DELETE | /:id |
None | Deletes a single learning node card. |
| PATCH | /update/:id |
{ status: string } |
Updates the card's column status (e.g. todo to in_progress, completed, or skipped) in the database. |
Inquisitive includes client-side session recording and event logging powered by PostHog to track learning behaviors and engagement milestones:
- Device Session Binding: Maps client actions to a persistent browser UUID (
posthog.identify(deviceId)) to group anonymous activities into single, continuous profiles. - Notebook Generation:
notebook_created: Logs topic name, difficulty level, and size size when a dynamic curriculum resolves.notebook_creation_failed: Logs error messages and target topic to catch generative failures.
- Engagement Signals (
card_status_changed): Logs card moves between Kanban states (e.g.todo,in_progress,completed,skipped) alongside resource media type (articlevsvideo). - Retention Signals (
notebook_completed): Fires once a learning progress meter reaches100%(i.e. all valid cards completed) with topic and card count metadata.
- Used for debugging.
- Used for web search.
- Used for AI generation (using Google's free-tier GROQ or Openrouter models).
- Used for brainstorm.
- https://cofounder.co/
- Dribble: Taqwah
- Notion for Kanban Dashboard.
- CTA.gallery for CTA inspiration.
- Framer Motion Library for animations.
Inquisitive - Made with Love: Jay Mehta





