A modern, scalable Node.js backend for collecting, organizing, and sharing your digital content library. Save links, articles, videos, and more with intelligent tagging and instant sharing capabilities.
- Overview
- Key Features
- Tech Stack
- System Architecture
- Quick Start
- API Reference
- Project Structure
- Configuration
- Deployment
- Performance
- Security
- Troubleshooting
SecondBrain is a production-ready content management system designed for individuals who want to:
- π Build a personal knowledge base
- π Organize web content with smart tagging
- π₯ Share collections with others via unique links
- π Keep their content secure and private
- β‘ Access their brain from anywhere
Perfect for researchers, students, knowledge workers, and content collectors.
- JWT-based token authentication
- bcrypt password hashing with salt
- Middleware-protected routes
- Secure credential management
- Multi-format support: links, videos, articles, images, audio
- Smart tagging system with auto-tagging
- Full-text search capabilities
- Bulk operations support
- Content metadata tracking
- Generate unique shareable links
- Share entire collections with expiration
- Public/private content management
- Share analytics and access tracking
- Disable/enable sharing anytime
- Automatic health monitoring
- Keep-alive service (prevents Render cold starts)
- Graceful error handling
- Request validation with Zod
- Comprehensive logging
- Response time: <100ms average
- Database query optimization
- Efficient pagination
- Caching support ready
- Load balancer compatible
| Component | Technology | Version |
|---|---|---|
| Runtime | Node.js | 18+ |
| Language | TypeScript | 5.4+ |
| Framework | Express.js | 5.1 |
| Database | MongoDB | Latest |
| ODM | Mongoose | 8.16+ |
| Authentication | JWT + bcrypt | - |
| Validation | Zod | 4.0+ |
| Deployment | Render | - |
graph TD
Client["π₯οΈ CLIENT LAYER<br/>(Web, Mobile, 3rd-party)"]
Gateway["π RENDER API GATEWAY<br/>(Cloud Platform)"]
Server["β‘ EXPRESS.JS SERVER<br/>(PORT 3000)"]
Middleware["π MIDDLEWARE LAYER<br/>CORS β’ JWT β’ Zod β’ Error Handling"]
Routing["π£οΈ ROUTING LAYER<br/>Auth β’ Content β’ User β’ Health"]
Logic["βοΈ BUSINESS LOGIC<br/>Users β’ Content β’ Sharing"]
MongoDB["ποΈ MONGODB ATLAS<br/>Users β’ Content β’ Tags β’ Links"]
Client -->|HTTPS| Gateway
Gateway --> Server
Server --> Middleware
Server --> Routing
Server --> Logic
Server -->|Mongoose| MongoDB
graph TD
Index["π¦ INDEX.TS<br/>Main Server"]
DB["ποΈ DB Models"]
Auth["π Auth Routes"]
Content["π Content Routes"]
Middleware["βοΈ Middleware"]
KeepAlive["πͺ Keep-Alive Service<br/>Auto Ping β’ 8 min interval"]
Index --> DB
Index --> Auth
Index --> Content
Index --> Middleware
Index --> KeepAlive
sequenceDiagram
participant Client
participant Server
participant Database
Client->>Server: POST /api/v1/signin
Server->>Database: Query User
Database-->>Server: User Found
Server->>Server: Bcrypt Verify
alt Valid
Server->>Server: Create JWT
Server-->>Client: {token}
else Invalid
Server-->>Client: 401 Error
end
sequenceDiagram
participant Client
participant Middleware
participant Database
Client->>Middleware: POST /content + JWT
Middleware->>Middleware: Verify Auth & Validate
Middleware->>Middleware: Extract Tags
Middleware->>Database: Upsert Tags
Database-->>Middleware: Tags Created
Middleware->>Database: Create Content
Database-->>Middleware: Content Saved
Middleware-->>Client: Success β
sequenceDiagram
participant Owner
participant Viewer
participant Server
Owner->>Server: POST /brain/share
Server->>Server: Generate Hash
Server-->>Owner: Share Link Ready
Owner->>Viewer: Share Link
Viewer->>Server: POST /brain/{hash}
Server-->>Viewer: Return Content β
graph TD
Start["π SERVER STARTS"]
Init["π§ INITIALIZATION"]
Loop["π
SCHEDULE LOOP"]
Fetch["π FETCH /health"]
Log["π LOG RESULT"]
Wait["β³ WAIT 8 MIN"]
Start --> Init
Init --> Loop
Loop --> Fetch
Fetch --> Log
Log --> Wait
Wait --> Loop
erDiagram
USERS ||--o{ CONTENT : creates
USERS ||--o{ LINKS : owns
CONTENT }o--|| TAGS : has
USERS {
objectid _id PK
string email UK
string password
string firstName
string lastName
datetime createdAt
}
CONTENT {
objectid _id PK
string link
string type
string title
objectid userId FK
array tags FK
datetime createdAt
}
TAGS {
objectid _id PK
string title UK
datetime createdAt
}
LINKS {
objectid _id PK
string hash UK
objectid userId FK
datetime createdAt
}
graph TD
A["π¨ REQUEST ARRIVES"]
B["CORS CHECK"]
C{"PUBLIC?"}
E["JWT VERIFICATION"]
F{"VALID?"}
G["β
PASS"]
H["β 401"]
A --> B
B --> C
C -->|YES| G
C -->|NO| E
E --> F
F -->|YES| G
F -->|NO| H
sequenceDiagram
participant Client
participant Server
participant Database
Client->>Server: POST /api/v1/content
Server->>Server: Parse & Validate
Server->>Server: Verify Auth
Server->>Database: Query DB
Database-->>Server: Results
Server->>Server: Build Response
Server-->>Client: Response 200
Note over Client,Server: Total Time: <100ms
graph TD
Cloud["βοΈ RENDER PLATFORM"]
Service["π₯οΈ WEB SERVICE<br/>Node.js v22"]
Express["β‘ EXPRESS APP"]
KeepAlive["πͺ KEEP-ALIVE"]
Config["π§ ENV VARS"]
MongoDB["βοΈ MONGODB ATLAS"]
Cloud --> Service
Service --> Express
Service --> KeepAlive
Service --> Config
Service -->|HTTPS| MongoDB
| Endpoint | Time | Status |
|---|---|---|
| /health | 10ms | β |
| /api/v1/signin | 45ms | β |
| /api/v1/signup | 50ms | β |
| /api/v1/profile | 35ms | β |
| /api/v1/content | 85ms | β |
| /api/v1/brain/share | 95ms | β |
- Node.js (v18+)
- MongoDB database
- npm or yarn
# Clone the repository
git clone https://github.com/mukundjha-mj/secondBrain.git
cd secondBrain
# Install dependencies
npm install
# Create .env file
cp .env.example .env
# Add your environment variables
# - DATABASE_URL: Your MongoDB connection string
# - JWT_SECRET: Your JWT secret key
# - SERVER_URL: Your app URL (for keep-alive pings)# MongoDB connection string
DATABASE_URL=mongodb+srv://username:password@cluster.mongodb.net/secondBrain
# JWT secret for token signing
JWT_SECRET=your-super-secret-jwt-key
# Server URL for keep-alive service
SERVER_URL=https://your-app.onrender.comDevelopment:
npm run devProduction:
npm run build
npm startRender Deployment:
npm run render-deployPOST /api/v1/signup
Content-Type: application/json
{
"email": "user@example.com",
"password": "securepassword123",
"firstName": "John",
"lastName": "Doe"
}POST /api/v1/signin
Content-Type: application/json
{
"email": "user@example.com",
"password": "securepassword123"
}Response:
{
"message": "Signed IN",
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}GET /api/v1/profile
Authorization: Bearer {token}POST /api/v1/content
Authorization: Bearer {token}
Content-Type: application/json
{
"link": "https://example.com/article",
"type": "link",
"title": "Interesting Article",
"tags": ["learning", "technology"]
}GET /api/v1/content
Authorization: Bearer {token}Response:
{
"content": [
{
"_id": "...",
"link": "https://example.com",
"type": "link",
"title": "Article Title",
"tags": [
{
"_id": "...",
"title": "learning"
}
]
}
]
}DELETE /api/v1/content
Authorization: Bearer {token}
Content-Type: application/json
{
"contentId": "content-id-here"
}POST /api/v1/brain/share
Authorization: Bearer {token}
Content-Type: application/json
{
"share": true
}Response:
{
"message": "/share/abc123xyz"
}POST /api/v1/brain/:shareLink
Content-Type: application/json
{}Response:
{
"firstName": "John",
"content": [...]
}POST /api/v1/brain/share
Authorization: Bearer {token}
Content-Type: application/json
{
"share": false
}GET /healthResponse:
{
"status": "OK",
"timestamp": "2025-08-05T10:30:00.000Z",
"uptime": 3600,
"message": "Server is running and healthy"
}secondBrain/
βββ src/
β βββ index.ts # Main application file
β βββ db.ts # Database models
β βββ Middleware.ts # Authentication middleware
β βββ keepAlive.ts # Keep-alive service
β βββ utils.ts # Utility functions
β βββ etc/
β βββ secrets/
β βββ config.ts # Configuration management
βββ dist/ # Compiled JavaScript
βββ package.json # Dependencies
βββ tsconfig.json # TypeScript configuration
βββ .env # Environment variables (git ignored)
βββ .env.example # Environment template
βββ README.md # This file
- Runtime: Node.js
- Framework: Express.js
- Language: TypeScript
- Database: MongoDB with Mongoose
- Authentication: JWT + bcrypt
- Validation: Zod
- CORS: Express CORS middleware
- Deployment: Render
The application includes an automatic keep-alive service that:
- Prevents cold starts on Render by pinging the health endpoint every 8 minutes
- Automatically starts in production environments
- Monitors response times and uptime
- Logs ping results for monitoring
Console Output Example:
π Server running on port 3000
π Keep-alive service started
β
Ping successful - Response time: 150ms
- Email: 10-30 characters, must be valid email
- Password: 8-30 characters
- First Name: 5-10 characters
- Last Name: 1-10 characters
- Link: Valid URL
- Type: link, video, document, etc.
- Title: String
- Tags: Array of tag names (optional)
- JWT-based authentication
- Password hashing with bcrypt (salt rounds: 5)
- Request validation with Zod
- CORS protection
- Protected routes with middleware
- Environment variable management for sensitive data
The API returns meaningful error responses:
{
"message": "Error message",
"error": "Detailed error information"
}Status codes:
200- Success208- User already exists404- User/Resource not found411- Invalid input/validation error
- Push code to GitHub
- Create new Web Service on Render
- Connect GitHub repository
- Set environment variables in Render dashboard:
DATABASE_URL=your-mongodb-url JWT_SECRET=your-secret SERVER_URL=https://your-app.onrender.com - Deploy!
The application will automatically:
- Install dependencies
- Build TypeScript
- Start the server
- Enable keep-alive service
# Development with auto-reload
npm run dev
# Build TypeScript to JavaScript
npm run build
# Start production server
npm start
# Render deployment script
npm run render-deployFeel free to submit issues and enhancement requests!
ISC
Mukund Jha @mukundjha-mj
Happy Saving! π§ β¨