Skip to content

kardelly/only-links

Repository files navigation

onlylinks.id

Social bookmarking with editorial sensibility. A modern reimagining of del.icio.us.

πŸ”– Live: https://onlylinks.id


Features

  • βœ… Save and organize links with tags (not folders)
  • βœ… Search across your entire collection
  • βœ… Follow other curators and see their bookmarks
  • βœ… Public/private bookmark visibility
  • βœ… Fast, keyboard-driven interface
  • βœ… Automatic Open Graph image fetching
  • βœ… User profiles with avatars
  • βœ… Responsive design (desktop + mobile)

Tech Stack

Backend

  • Node.js + Express
  • SQLite database
  • JWT authentication with httpOnly cookies
  • Bcrypt password hashing
  • Helmet security headers + CSP
  • Rate limiting on auth endpoints

Frontend

  • Vanilla JavaScript (ES6+)
  • Component-based architecture
  • OKLCH color system
  • CSS animations with reduced-motion support
  • No frontend framework dependencies

Quick Start

Prerequisites

  • Node.js 20+
  • npm or yarn

Development

# Clone repository
git clone https://github.com/kardelly/only-links.git
cd only-links

# Install dependencies
npm install

# Create .env file
cp .env.example .env
# Edit .env and add JWT_SECRET (generate with: node -e "console.log(require('crypto').randomBytes(64).toString('hex'))")

# Start development server
npm start

# Open browser
open http://localhost:3000

Production Deploy

See DEPLOY.md for complete VPS deployment guide.

Quick deploy checklist: START-HERE.md


Project Structure

.
β”œβ”€β”€ server.js              # Express server + API routes
β”œβ”€β”€ database.js            # SQLite database + queries
β”œβ”€β”€ public/
β”‚   β”œβ”€β”€ index.html         # Landing page
β”‚   β”œβ”€β”€ app.html           # Main application
β”‚   β”œβ”€β”€ profile.html       # User profiles
β”‚   β”œβ”€β”€ settings.html      # Account settings
β”‚   β”œβ”€β”€ app.js             # Main app logic
β”‚   β”œβ”€β”€ profile.js         # Profile page logic
β”‚   β”œβ”€β”€ settings.js        # Settings page logic
β”‚   └── components/        # Reusable UI components
β”‚       β”œβ”€β”€ header.js
β”‚       β”œβ”€β”€ header.html
β”‚       β”œβ”€β”€ sidebar-tags.js
β”‚       β”œβ”€β”€ bookmark-renderer.js
β”‚       └── *.css
β”œβ”€β”€ PRODUCT.md             # Product vision + principles
β”œβ”€β”€ DESIGN.md              # Design system tokens
β”œβ”€β”€ SECURITY.md            # Security hardening guide
β”œβ”€β”€ PRIVACY.md             # Privacy policy
β”œβ”€β”€ DEPLOY.md              # Deployment guide
└── package.json

Design Principles

  1. Speed is a feature – Every interaction feels instant
  2. Tags > folders – Multidimensional organization
  3. Public by default – Discovery through shared knowledge
  4. Keyboard > mouse – Every action has a shortcut
  5. Content first – UI recedes when not needed

Full philosophy: PRODUCT.md


Security

  • βœ… JWT tokens with 7-day expiration
  • βœ… Bcrypt password hashing (10 rounds)
  • βœ… Rate limiting (5 attempts/15min on auth)
  • βœ… Content Security Policy (CSP)
  • βœ… HTTPS-only cookies in production
  • βœ… Input validation on all endpoints
  • βœ… SQL injection prevention (parameterized queries)
  • βœ… XSS protection

See SECURITY.md for hardening guide.


API Endpoints

Authentication

  • POST /api/auth/register - Create account
  • POST /api/auth/login - Login
  • POST /api/auth/logout - Logout
  • GET /api/auth/me - Get current user

Bookmarks

  • GET /api/bookmarks - List bookmarks (with filters)
  • POST /api/bookmarks - Create bookmark
  • PUT /api/bookmarks/:id - Update bookmark
  • DELETE /api/bookmarks/:id - Delete bookmark
  • GET /api/metadata?url= - Fetch Open Graph metadata

Tags

  • GET /api/tags - Get popular tags

Social

  • GET /api/users/:username - Get user profile
  • POST /api/users/:username/follow - Follow user
  • DELETE /api/users/:username/follow - Unfollow user
  • GET /api/users/:username/followers - Get followers
  • GET /api/users/:username/following - Get following

Settings

  • GET /api/settings/preferences - Get preferences
  • PUT /api/settings/preferences - Update preferences
  • PUT /api/settings/username - Change username
  • PUT /api/settings/email - Change email
  • PUT /api/settings/password - Change password
  • POST /api/settings/avatar - Upload avatar
  • DELETE /api/settings/avatar - Remove avatar
  • DELETE /api/settings/account - Delete account

Database Schema

Tables

  • users - User accounts (username, email, password_hash, avatar)
  • bookmarks - Saved links (url, title, description, og_image, is_public)
  • tags - Tag definitions (name)
  • bookmark_tags - Many-to-many (bookmark_id, tag_id)
  • follows - Social graph (follower_id, following_id)
  • user_preferences - Settings (default_public)

All foreign keys have ON DELETE CASCADE for data integrity.


Keyboard Shortcuts

  • N - New bookmark (when not typing)
  • Esc - Close modal
  • More coming soon...

Environment Variables

# Required
NODE_ENV=production
JWT_SECRET=your-64-char-secret-here

# Optional (with defaults)
PORT=3000
ALLOWED_ORIGINS=https://onlylinks.id
RATE_LIMIT_WINDOW_MS=900000
RATE_LIMIT_MAX_REQUESTS=5

Generate strong JWT_SECRET:

node -e "console.log(require('crypto').randomBytes(64).toString('hex'))"

Contributing

This is a personal project, but feel free to:

  • Report bugs via Issues
  • Suggest features via Discussions
  • Fork and experiment

License

MIT License - See LICENSE


Acknowledgments

  • Inspired by the original del.icio.us (2003-2017)
  • Design philosophy influenced by Pinboard, Linear, and Are.na
  • Built with the impeccable design system

Contact


Made with πŸ”– by Anderson Cardelli FaΓ§anha

About

No description, website, or topics provided.

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors