Oculus is a production-ready, AI-powered knowledge management system that helps you curate, analyze, and explore your personal knowledge library. It uses advanced AI to extract mental models, generate semantic embeddings, and provide intelligent search across your saved resources.
- Save articles, videos, papers, and tweets
- Automatic content scraping via Jina Reader
- AI-powered analysis extracts summaries, tags, and mental models
- Beautiful masonry layout with rich preview cards
- Chat-based interface for knowledge exploration
- Semantic search across your entire library
- Generate curated learning paths from your resources
- Powered by NVIDIA NIM for fast inference
- Google Gemini embeddings for semantic understanding
- Pinecone vector database for lightning-fast similarity search
- Find related resources based on meaning, not just keywords
- Inngest-powered background jobs
- Multi-step agentic workflow for content ingestion
- Handles scraping, analysis, embedding, and storage
| Category | Technology |
|---|---|
| Framework | Next.js 16 (App Router) |
| Styling | Tailwind CSS v4 |
| Database | PostgreSQL with Drizzle ORM |
| Vector DB | Pinecone |
| AI/LLM | Vercel AI SDK, NVIDIA NIM |
| Embeddings | Google Gemini text-embedding-004 |
| Scraping | Jina Reader |
| Background Jobs | Inngest |
| UI Components | Custom shadcn/ui components |
- Node.js 18.18+ or 20+
- PostgreSQL database (Supabase recommended)
- API keys for: Pinecone, Google AI, NVIDIA NIM, Jina AI
-
Clone and install dependencies
git clone <your-repo-url> cd oculus npm install
-
Configure environment variables
Copy
.env.exampleto.env.localand fill in your API keys:cp .env.example .env.local
Required variables:
DATABASE_URL=postgresql://... PINECONE_API_KEY=pcsk_... PINECONE_INDEX_NAME=oculus NIM_API_KEY=nvapi-... GOOGLE_GENERATIVE_AI_API_KEY=AIza... JINA_API_KEY=jina_...
-
Set up the database
# Generate Drizzle migrations npm run db:generate # Push schema to database npm run db:push
-
Create Pinecone index
Create an index in your Pinecone dashboard with:
- Dimensions: 768 (for text-embedding-004)
- Metric: Cosine
- Name:
oculus(or match your PINECONE_INDEX_NAME)
-
Start the development server
npm run dev
Open http://localhost:3000 in your browser.
For background job processing during development:
npx inngest-cli@latest devThis opens the Inngest dashboard at http://localhost:8288.
┌─────────────────────────────────────────────────────────────────┐
│ FRONTEND │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ Sidebar │ │ Library │ │ Curator Chat │ │
│ │ Navigation │ │ Cards │ │ AI Interface │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ API ROUTES │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ /api/chat │ │/api/resources│ │ /api/inngest │ │
│ │ AI Streaming │ │ CRUD + Queue │ │ Background Jobs │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
┌───────────────────┴───────────────────┐
▼ ▼
┌──────────────────┐ ┌──────────────────┐
│ PostgreSQL │ │ Pinecone │
│ (Drizzle ORM) │ │ (Vector Store) │
│ │ │ │
│ • Resources │ │ • Embeddings │
│ • Metadata │ │ • Similarity │
│ • Full Content │ │ Search │
└──────────────────┘ └──────────────────┘
When you add a new resource:
- Scrape – Jina Reader fetches and converts content to markdown
- Analyze – NVIDIA NIM extracts title, summary, tags, and mental models
- Embed – Google Gemini generates 768-dim vector embedding
- Store – Data saved to PostgreSQL, vector indexed in Pinecone
| Command | Description |
|---|---|
npm run dev |
Start development server |
npm run build |
Build for production |
npm run start |
Start production server |
npm run lint |
Run ESLint |
npm run db:generate |
Generate Drizzle migrations |
npm run db:push |
Push schema to database |
npm run db:studio |
Open Drizzle Studio |
oculus/
├── src/
│ ├── app/ # Next.js App Router
│ │ ├── api/ # API routes
│ │ │ ├── chat/ # AI streaming endpoint
│ │ │ ├── resources/ # Resource CRUD
│ │ │ └── inngest/ # Background jobs handler
│ │ ├── globals.css # Tailwind v4 styles
│ │ ├── layout.tsx # Root layout
│ │ └── page.tsx # Main page
│ ├── components/ # React components
│ │ ├── ui/ # shadcn/ui components
│ │ ├── sidebar.tsx # Navigation sidebar
│ │ ├── resource-card.tsx # Resource display cards
│ │ ├── curator-view.tsx # AI chat interface
│ │ └── ...
│ └── lib/ # Utilities & integrations
│ ├── db/ # Drizzle ORM setup
│ ├── inngest/ # Background job functions
│ ├── pinecone.ts # Vector DB client
│ └── utils.ts # Helper functions
├── public/ # Static assets
├── drizzle.config.ts # Drizzle configuration
├── next.config.ts # Next.js configuration
├── package.json
└── tsconfig.json
- Push your code to GitHub
- Import project in Vercel
- Add environment variables
- Deploy!
All .env.local variables should be set in your deployment platform.
- Create an Inngest account at inngest.com
- Get your signing key
- Set
INNGEST_SIGNING_KEYin production environment - Inngest will automatically discover your
/api/inngestendpoint
MIT
Built with ❤️ using Next.js, Tailwind CSS, and AI