Smart AI Collaborative URL Bookmark Manager - Next.js, TanStack React Query, Prisma, PostgreSQL, Upstash, QStash, Cloudinary, Google Gemini, Groq, OpenRouter, Hugging Face FullStack Project
A production-ready, full-stack URL bookmarking and sharing platform built with Next.js 15, React, TypeScript, and PostgreSQL. Features AI-powered enhancements, real-time collaboration, vector search, and intelligent URL organization.
- Live-Demo: https://daily-urlist.vercel.app/
- Overview
- Features
- Technology Stack
- Project Structure
- Getting Started
- Environment Variables
- Project Walkthrough
- Components Documentation
- API Endpoints
- Reusable Components Guide
- Code Examples
- Keywords
- Conclusion
The Daily Urlist is a modern, full-featured URL bookmark manager that goes beyond simple link saving. It combines powerful organization tools, AI-powered enhancements, real-time collaboration, and intelligent features to create a comprehensive solution for managing and sharing web resources.
- π Production-Ready: Optimized for performance with React Query caching, Infinity cache strategy, and instant rendering
- π€ AI-Powered: URL enhancement, smart collections, duplicate detection, and semantic search
- π₯ Real-Time Collaboration: Live updates, comments, activity feeds, and role-based permissions
- β‘ Lightning Fast: Zero API calls until database changes, instant navigation with cached data
- π Intelligent Organization: Vector-based semantic search, smart collections, and automatic categorization
- π Business Insights: Analytics, activity tracking, and performance metrics
- π Import/Export: Support for Pocket, Pinboard, and Chrome bookmarks
-
URL Management
- Create, edit, delete, and organize URLs in lists
- Rich metadata extraction (title, description, images)
- Drag-and-drop reordering
- Favorites, pins, and reminders
- Archive and restore URLs
- URL health monitoring
-
List Management
- Multiple lists per user
- Public/private visibility controls
- Custom slugs for easy sharing
- List-level descriptions and metadata
- Bulk import/export (Pocket, Pinboard, Chrome)
-
AI-Powered Enhancements
- Automatic URL enhancement with AI
- Smart collection suggestions
- Duplicate URL detection
- Semantic search across all URLs
- Automatic categorization and tagging
-
Collaboration
- Role-based permissions (Owner, Editor, Viewer)
- Real-time activity feeds
- Comments on URLs
- Live updates via Server-Sent Events (SSE)
- Collaborative editing
-
Search & Discovery
- Vector-based semantic search
- Filter by tags, category, favorites
- Sort by date, alphabetically, favorites
- Browse public lists
- Smart search with AI
-
Business Insights
- Activity timelines
- Popular content analytics
- Performance metrics
- Global statistics
- API status monitoring
-
Developer Features
- RESTful API with comprehensive endpoints
- API documentation page
- Real-time event streaming
- Scheduled background jobs
- Next.js 15.5.7 - React framework with App Router
- React 18.3.1 - UI library
- TypeScript 5.7.3 - Type safety
- TanStack React Query 5.90.6 - Data fetching and caching
- Tailwind CSS 3.4.1 - Utility-first styling
- ShadCN UI - Reusable component library
- @dnd-kit - Drag-and-drop functionality
- NanoStores - Lightweight state management
- Recharts - Data visualization
- Next.js API Routes - Serverless API endpoints
- Prisma 6.19.0 - Database ORM
- PostgreSQL - Primary database (Neon)
- Upstash Redis - Caching and real-time features
- Upstash Vector - Vector database for semantic search
- QStash - Scheduled jobs and background tasks
- Google Gemini - AI enhancement
- Groq (Llama 3) - Fast AI inference
- OpenRouter - Multi-model AI access
- Hugging Face - AI inference
- Cloudinary - Image optimization and CDN
- Resend - Transactional emails
- Nodemailer - SMTP email support
- Gmail SMTP - Alternative email provider
- Turbopack - Fast bundler (development)
- Jest - Testing framework
- ESLint - Code linting
- TypeScript - Static type checking
daily-urlist/
βββ prisma/
β βββ schema.prisma # Database schema
β βββ migrations/ # Database migrations
βββ public/ # Static assets
βββ src/
β βββ app/ # Next.js App Router
β β βββ api/ # API routes
β β β βββ auth/ # Authentication endpoints
β β β βββ lists/ # List management endpoints
β β β βββ ai/ # AI enhancement endpoints
β β β βββ business-insights/ # Analytics endpoints
β β β βββ metadata/ # URL metadata extraction
β β β βββ realtime/ # Server-Sent Events
β β β βββ ...
β β βββ list/[slug]/ # Individual list pages
β β βββ lists/ # Lists overview page
β β βββ browse/ # Public lists browser
β β βββ business-insights/ # Analytics dashboard
β β βββ ...
β βββ components/ # React components
β β βββ ui/ # Reusable UI components (ShadCN)
β β βββ pages/ # Page-level components
β β βββ lists/ # List-related components
β β βββ collaboration/ # Collaboration features
β β βββ ai/ # AI-powered components
β β βββ business-insights/ # Analytics components
β β βββ ...
β βββ hooks/ # Custom React hooks
β β βββ useListQueries.ts # List data hooks
β β βββ useSession.ts # Session management
β β βββ useUrlMetadata.ts # URL metadata hooks
β β βββ useBrowseQueries.ts # Browse page hooks
β β βββ ...
β βββ lib/ # Utility libraries
β β βββ ai/ # AI providers and logic
β β βββ auth.ts # Authentication logic
β β βββ db.ts # Database utilities
β β βββ email/ # Email services
β β βββ import/ # Bookmark importers
β β βββ export/ # Export functionality
β β βββ react-query.ts # React Query configuration
β β βββ ...
β βββ stores/ # State management
β β βββ urlListStore.ts # URL list state (NanoStores)
β β βββ dragOrderCache.ts # Drag-and-drop cache
β βββ utils/ # Utility functions
β β βββ queryInvalidation.ts # Cache invalidation
β β βββ urlMetadata.ts # Metadata extraction
β β βββ ...
β βββ types/ # TypeScript type definitions
βββ package.json # Dependencies and scripts
βββ next.config.js # Next.js configuration
βββ tailwind.config.js # Tailwind CSS configuration
βββ tsconfig.json # TypeScript configuration- Node.js 18+ (recommended: 20+)
- PostgreSQL database (Neon, Supabase, or self-hosted)
- npm or yarn package manager
- Git for version control
-
Clone the Repository
git clone <repository-url> cd daily-urlist
-
Install Dependencies
npm install
-
Set Up Environment Variables
Create a
.env.localfile in the root directory (see Environment Variables section below). -
Set Up Database
# Generate Prisma Client npm run db:generate # Run database migrations npm run db:migrate
-
Start Development Server
npm run dev
The application will be available at
http://localhost:3000
Create a .env.local file in the root directory with the following variables:
# Base URL Configuration
NEXT_PUBLIC_BASE_URL=http://localhost:3000
# For production: https://your-domain.com
# Database Configuration (PostgreSQL)
DATABASE_URL="postgresql://user:password@host:port/database?sslmode=require"
# Session Secret
NEXTAUTH_SECRET=your-secret-key-here-change-in-production
NEXTAUTH_URL=http://localhost:3000# Email Configuration (Choose one)
# Option 1: SMTP (Gmail)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=your-email@gmail.com
SMTP_PASS=your-app-password
SMTP_FROM_EMAIL=your-email@gmail.com
SMTP_FROM_NAME=The Daily Urlist
# Option 2: Resend
RESEND_API_KEY=re_your_resend_api_key
# Redis & Real-time Features (Upstash)
UPSTASH_REDIS_REST_URL=https://your-redis.upstash.io
UPSTASH_REDIS_REST_TOKEN=your-redis-token
# Vector Database for Semantic Search (Upstash)
UPSTASH_VECTOR_REST_URL=https://your-vector.upstash.io
UPSTASH_VECTOR_REST_TOKEN=your-vector-token
# Scheduled Jobs (QStash)
QSTASH_TOKEN=your-qstash-token
# Image Optimization (Cloudinary)
CLOUDINARY_CLOUD_NAME=your-cloud-name
CLOUDINARY_API_KEY=your-api-key
CLOUDINARY_API_SECRET=your-api-secret
# AI Services (At least one recommended)
GOOGLE_GEMINI_API_KEY=your-gemini-api-key
GROQ_LLAMA_API_KEY=your-groq-api-key
OPENROUTER_API_KEY=your-openrouter-api-key
HUGGING_FACE_INFERENCE_API_KEY=your-huggingface-api-keyDATABASE_URL: PostgreSQL connection string- Format:
postgresql://user:password@host:port/database?sslmode=require - Get from: Neon, Supabase, or your PostgreSQL provider
- Format:
Choose one email service:
SMTP (Gmail):
SMTP_HOST: Usuallysmtp.gmail.comSMTP_PORT:587for TLSSMTP_USER: Your Gmail addressSMTP_PASS: Gmail App Password (not your regular password)SMTP_FROM_EMAIL: Sender emailSMTP_FROM_NAME: Sender display name
Resend:
RESEND_API_KEY: Get from Resend.com
UPSTASH_REDIS_REST_URL: Get from Upstash RedisUPSTASH_REDIS_REST_TOKEN: Get from Upstash dashboard
UPSTASH_VECTOR_REST_URL: Get from Upstash VectorUPSTASH_VECTOR_REST_TOKEN: Get from Upstash dashboard
At least one AI provider recommended:
- Google Gemini:
GOOGLE_GEMINI_API_KEY- Get API Key - Groq:
GROQ_LLAMA_API_KEY- Get API Key - OpenRouter:
OPENROUTER_API_KEY- Get API Key - Hugging Face:
HUGGING_FACE_INFERENCE_API_KEY- Get API Key
CLOUDINARY_CLOUD_NAME: Get from CloudinaryCLOUDINARY_API_KEY: From Cloudinary dashboardCLOUDINARY_API_SECRET: From Cloudinary dashboard
QSTASH_TOKEN: Get from Upstash QStash
- User signs up/signs in through the
Authcomponent - Session token stored in httpOnly cookie
- Session validated on each API request
- React Query caches session data with Infinity cache
// Session is cached forever until logout
const { user, isLoading } = useSession();- Users create lists with title, description, and slug
- Lists stored in PostgreSQL with JSON URL arrays
- React Query caches lists data for instant loading
- Real-time updates via SSE for collaborative editing
- URLs added to lists with automatic metadata extraction
- Metadata cached in React Query with Infinity cache
- Drag-and-drop reordering with optimistic updates
- Health monitoring for URL status
- Server-Sent Events (SSE) for live updates
- Redis pub/sub for broadcasting changes
- Activity feed shows all list changes
- Comments system for URL discussions
- AI providers (Gemini, Groq, etc.) enhance URLs
- Smart collections suggest related URLs
- Duplicate detection finds similar URLs
- Semantic search uses vector embeddings
- Infinity Cache: Data cached forever until invalidated
- Centralized Invalidation: Single source of truth
- Optimistic Updates: UI updates immediately
- Placeholder Data: Shows cached data while fetching
Landing page with features showcase and authentication.
Location: src/components/HomePage.tsx
Features:
- Hero section with call-to-action
- Features grid
- How it works section
- Conditional rendering based on auth state
Usage:
import HomePage from "@/components/HomePage";
export default function Page() {
return <HomePage />;
}Displays all user lists with search, filtering, and management options.
Location: src/components/pages/ListsPage.tsx
Features:
- Lists grid with React Query caching
- Search and filter functionality
- Delete lists with confirmation
- Public/private indicators
- Collaboration indicators
Hooks Used:
useAllListsQuery()- Fetches all lists with Infinity cache
Individual list view with URLs, activities, and collaboration.
Location: src/components/pages/ListPage.tsx
Features:
- Unified list data (list + activities + collaborators)
- Real-time updates via SSE
- Activity feed
- Collaboration management
- Smart collections sidebar
Hooks Used:
useUnifiedListQuery(slug)- Fetches complete list data
Browse public lists with pagination and search.
Location: src/components/pages/BrowsePage.tsx
Features:
- Public lists pagination
- Search functionality
- List preview cards
Hooks Used:
usePublicListsQuery(page, search)- Fetches public lists
Analytics dashboard with charts and metrics.
Location: src/components/pages/BusinessInsightsPage.tsx
Features:
- Activity timeline charts
- Popular content analytics
- Performance metrics
- Global statistics
Hooks Used:
useBusinessOverviewQuery()useBusinessActivityQuery(days)useBusinessPopularQuery()useBusinessPerformanceQuery()useBusinessGlobalQuery()
All UI components are located in src/components/ui/ and follow ShadCN patterns:
Reusable button component with variants and link support.
import { Button } from "@/components/ui/Button";
// Primary button
<Button>Click Me</Button>
// Link button
<Button href="/lists">Go to Lists</Button>
// Variants
<Button variant="outline">Outline</Button>
<Button variant="ghost">Ghost</Button>Card component for content containers.
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/Card";
<Card>
<CardHeader>
<CardTitle>Title</CardTitle>
</CardHeader>
<CardContent>Content here</CardContent>
</Card>;Dynamic toast notifications.
import { useToast } from "@/components/ui/Toaster";
const { toast } = useToast();
toast({
title: "Success!",
description: "Operation completed",
variant: "success",
});Input.tsx- Text input fieldsTextarea.tsx- Multi-line text inputBadge.tsx- Status badgesAlertDialog.tsx- Confirmation dialogsTabs.tsx- Tab navigationSkeleton.tsx- Loading skeletonsTooltip.tsx- Hover tooltips
Main component for displaying and managing URLs in a list.
Location: src/components/lists/UrlList.tsx
Features:
- Drag-and-drop reordering
- URL cards with metadata
- Search and filtering
- Bulk operations
- Real-time updates
Key Props:
- None (uses
currentListstore)
Usage:
import { UrlList } from "@/components/lists/UrlList";
<UrlList />;Individual URL card component.
Location: src/components/lists/UrlCard.tsx
Features:
- URL preview with metadata
- Actions (edit, delete, favorite, pin)
- Click tracking
- Health indicator
Props:
interface UrlCardProps {
url: UrlItem;
metadata?: UrlMetadata;
isLoadingMetadata?: boolean;
onEdit: (url: UrlItem) => void;
onDelete: (id: string) => void;
// ... other handlers
}AI-powered collection suggestions and duplicate detection.
Location: src/components/collections/SmartCollections.tsx
Features:
- Smart collection suggestions
- Duplicate URL detection
- Collection creation from suggestions
Props:
interface SmartCollectionsProps {
listId: string;
listSlug: string;
}Role-based collaboration management.
Location: src/components/collaboration/PermissionManager.tsx
Features:
- Add/remove collaborators
- Role management (Owner, Editor, Viewer)
- Permission indicators
Props:
interface PermissionManagerProps {
listId: string;
listTitle: string;
listSlug: string;
onUpdate?: () => void;
}Real-time activity feed for list changes.
Location: src/components/collaboration/ActivityFeed.tsx
Features:
- Real-time activity updates
- Activity icons and labels
- Time-based formatting
Props:
interface ActivityFeedProps {
listId: string;
limit?: number; // Default: 50
}Comment system for URLs.
Location: src/components/collaboration/Comments.tsx
Features:
- Add/edit/delete comments
- Real-time comment updates
- User attribution
Props:
interface CommentsProps {
listId: string;
urlId: string;
currentUserId?: string;
}Create a new user account.
Request:
{
"email": "user@example.com",
"password": "securepassword"
}Response:
{
"user": {
"id": "uuid",
"email": "user@example.com"
}
}Sign in an existing user.
Request:
{
"email": "user@example.com",
"password": "securepassword"
}Response:
{
"user": {
"id": "uuid",
"email": "user@example.com"
}
}Get current user session.
Response:
{
"user": {
"id": "uuid",
"email": "user@example.com"
}
}Sign out current user.
Get all lists for current user.
Response:
{
"lists": [
{
"id": "uuid",
"title": "My List",
"slug": "my-list",
"description": "Description",
"isPublic": false,
"createdAt": "2025-01-01T00:00:00Z"
}
]
}Create a new list.
Request:
{
"title": "New List",
"description": "Description",
"slug": "new-list",
"isPublic": false,
"urls": []
}Get a specific list by slug.
Response:
{
"id": "uuid",
"title": "List Title",
"slug": "list-slug",
"urls": [...],
"userId": "uuid",
"isPublic": false
}Unified endpoint for list data, activities, and collaborators.
Query Parameters:
activityLimit: Number of activities to fetch (default: 30)
Response:
{
"list": { ... },
"activities": [ ... ],
"collaborators": [ ... ]
}Update list metadata.
Request:
{
"title": "Updated Title",
"description": "Updated Description",
"isPublic": true
}Delete a list.
Add URLs to a list.
Request:
{
"urls": [
{
"url": "https://example.com",
"title": "Example",
"description": "Description"
}
]
}Update or reorder URLs.
Request (Reorder):
{
"action": "reorder",
"urls": [ { "id": "...", "position": 0 }, ... ]
}Request (Update):
{
"action": "update",
"urlId": "uuid",
"updates": {
"title": "New Title",
"tags": ["tag1", "tag2"]
}
}Delete a URL from a list.
Fetch metadata for a URL.
Query Parameters:
url: The URL to fetch metadata for
Response:
{
"title": "Page Title",
"description": "Page description",
"image": "https://example.com/image.jpg",
"siteName": "Site Name"
}Enhance URL with AI (category, tags, summary).
Request:
{
"url": "https://example.com",
"title": "Page Title",
"description": "Description",
"provider": "gemini"
}Response:
{
"category": "Technology",
"tags": ["web", "development"],
"summary": "AI-generated summary",
"confidence": 0.95
}Get AI-generated collection suggestions.
Query Parameters:
includeDuplicates: Include duplicate detection (default: false)minGroupSize: Minimum URLs per collection (default: 2)maxCollections: Maximum collections to return (default: 10)
Semantic search across URLs.
Request:
{
"query": "search query",
"listId": "uuid"
}Get list collaborators.
Add a collaborator.
Request:
{
"email": "collaborator@example.com",
"role": "editor"
}Update collaborator role.
Remove a collaborator.
Server-Sent Events stream for real-time updates.
Usage:
const eventSource = new EventSource(`/api/realtime/list/${listId}/events`);
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
// Handle update
};All UI components in src/components/ui/ are fully reusable and follow consistent patterns.
import { Button } from "@/components/ui/Button";
function MyComponent() {
return (
<div>
{/* Primary button */}
<Button onClick={() => console.log("Clicked")}>Primary Action</Button>
{/* Link button */}
<Button href="/lists" variant="outline">
View Lists
</Button>
{/* Loading state */}
<Button disabled={isLoading}>
{isLoading ? "Loading..." : "Submit"}
</Button>
</div>
);
}import { useToast } from "@/components/ui/Toaster";
function MyComponent() {
const { toast } = useToast();
const handleSuccess = () => {
toast({
title: "Success!",
description: "Operation completed successfully",
variant: "success",
});
};
const handleError = () => {
toast({
title: "Error",
description: "Something went wrong",
variant: "error",
});
};
return <Button onClick={handleSuccess}>Show Toast</Button>;
}import { useUnifiedListQuery } from "@/hooks/useListQueries";
import { useUrlMetadata } from "@/hooks/useUrlMetadata";
function MyComponent({ listSlug }: { listSlug: string }) {
// Fetch list data with Infinity cache
const { data, isLoading } = useUnifiedListQuery(listSlug);
// Fetch URL metadata with caching
const { data: metadata } = useUrlMetadata("https://example.com");
if (isLoading) return <div>Loading...</div>;
return (
<div>
<h1>{data?.list?.title}</h1>
<p>{metadata?.description}</p>
</div>
);
}import { invalidateListQueries } from "@/utils/queryInvalidation";
import { useQueryClient } from "@tanstack/react-query";
function MyComponent({ listSlug, listId }: Props) {
const queryClient = useQueryClient();
const handleUpdate = async () => {
// Perform update
await updateList(listId, { title: "New Title" });
// Invalidate cache to trigger refetch
invalidateListQueries(queryClient, listSlug, listId);
};
}import { useRouter } from "next/navigation";
import { useAllListsQuery } from "@/hooks/useListQueries";
function CreateListForm() {
const router = useRouter();
const { refetch } = useAllListsQuery();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const formData = new FormData(e.target);
const response = await fetch("/api/lists", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
title: formData.get("title"),
slug: formData.get("slug"),
description: formData.get("description"),
}),
});
if (response.ok) {
await refetch(); // Refresh lists
router.push(`/list/${formData.get("slug")}`);
}
};
return <form onSubmit={handleSubmit}>...</form>;
}import { useUrlMetadata } from "@/hooks/useUrlMetadata";
import { useToast } from "@/components/ui/Toaster";
function AddUrlForm({ listId }: { listId: string }) {
const [url, setUrl] = useState("");
const { data: metadata } = useUrlMetadata(url);
const { toast } = useToast();
const handleAdd = async () => {
const response = await fetch(`/api/lists/${listId}/urls`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
urls: [
{
url,
title: metadata?.title,
description: metadata?.description,
},
],
}),
});
if (response.ok) {
toast({
title: "Success!",
description: "URL added successfully",
variant: "success",
});
}
};
return (
<div>
<input value={url} onChange={(e) => setUrl(e.target.value)} />
{metadata && <img src={metadata.image} alt={metadata.title} />}
<button onClick={handleAdd}>Add URL</button>
</div>
);
}import { UrlEnhancer } from "@/components/ai/UrlEnhancer";
function EnhancedUrlForm({ url }: { url: string }) {
const [enhancementResult, setEnhancementResult] = useState(null);
return (
<div>
<input value={url} readOnly />
<UrlEnhancer
url={url}
onEnhance={(result) => {
setEnhancementResult(result);
// Use result.category, result.tags, result.summary
}}
/>
{enhancementResult && (
<div>
<p>Category: {enhancementResult.category}</p>
<p>Tags: {enhancementResult.tags.join(", ")}</p>
</div>
)}
</div>
);
}import { useEffect } from "react";
import { useQueryClient } from "@tanstack/react-query";
function useRealtimeUpdates(listId: string) {
const queryClient = useQueryClient();
useEffect(() => {
const eventSource = new EventSource(`/api/realtime/list/${listId}/events`);
eventSource.onmessage = (event) => {
const data = JSON.parse(event.data);
// Invalidate cache to trigger refetch
queryClient.invalidateQueries({
queryKey: ["unified-list", listId],
});
};
return () => eventSource.close();
}, [listId, queryClient]);
}- Next.js 15 - React framework with App Router
- React Query - Data fetching and caching
- TypeScript - Type-safe JavaScript
- PostgreSQL - Relational database
- Prisma - Database ORM
- Redis - Caching and real-time features
- Vector Search - Semantic search with embeddings
- AI Enhancement - URL enhancement with AI
- Real-Time Collaboration - Live updates and SSE
- Role-Based Access - Permission system
- Drag-and-Drop - URL reordering
- Metadata Extraction - Automatic URL metadata
- Smart Collections - AI-powered grouping
- Business Analytics - Insights and metrics
- Server-Sent Events - Real-time updates
- Infinity Cache - Persistent caching strategy
- Turbopack - Fast bundler
- Tailwind CSS - Utility-first styling
- ShadCN UI - Component library
-
React Query Caching Strategy
- Infinity cache until invalidation
- Centralized invalidation patterns
- Optimistic updates
-
Real-Time Updates
- Server-Sent Events (SSE)
- Redis pub/sub
- Event-driven architecture
-
State Management
- NanoStores for client state
- React Query for server state
- Local storage for persistence
-
AI Integration
- Multiple AI provider support
- Fallback mechanisms
- Error handling
-
Performance Optimization
- Lazy loading
- Code splitting
- Image optimization
- Metadata caching
The Daily Urlist is a comprehensive, production-ready URL bookmark manager that demonstrates modern web development best practices. It combines powerful features like AI enhancements, real-time collaboration, and intelligent organization with optimized performance and developer-friendly architecture.
- Full-Stack Development: Next.js App Router, API routes, database design
- State Management: React Query, NanoStores, local storage
- Real-Time Features: Server-Sent Events, Redis pub/sub
- AI Integration: Multiple AI providers, semantic search
- Performance Optimization: Infinity caching, lazy loading, code splitting
- Type Safety: Comprehensive TypeScript usage
- UI/UX: ShadCN components, responsive design, accessibility
β
Production-Ready: Optimized for performance and scalability
β
Fully Typed: Comprehensive TypeScript coverage
β
Well-Documented: Clear code comments and structure
β
Modular Architecture: Reusable components and hooks
β
Real-Time: Live collaboration and updates
β
AI-Powered: Smart features and enhancements
Feel free to use this project repository and extend this project further!
If you have any questions or want to share your work, reach out via GitHub or my portfolio at https://arnob-mahmud.vercel.app/.
Enjoy building and learning! π
Thank you! π










