No description
  • Rust 83.9%
  • CSS 9.6%
  • HTML 2.6%
  • Shell 2.2%
  • Just 0.7%
  • Other 1%
Find a file
2026-04-16 18:38:48 +02:00
.cargo wip: Upgrade all dependencies and update the code 2025-11-23 18:13:41 -05:00
.claude styling 2026-04-01 03:14:14 +02:00
.devcontainer feat: Routing works 2025-11-28 18:02:37 -05:00
.forgejo/workflows chore: Sync release process 2026-04-16 18:38:04 +02:00
.idea chore: Format code using rustfmt 2025-11-30 08:50:22 -05:00
assets fix: prevent FOUC by applying high-contrast class before first paint 2026-04-02 21:55:33 +02:00
docs docs: add high contrast mode implementation plan 2026-04-02 21:47:10 +02:00
examples feat: Change the Docker port and sync with other repos 2026-03-15 22:55:46 +01:00
migrations feat: Replace session-based auth with JWT authentication system 2026-02-12 18:34:02 +01:00
oci-build feat: Sync the build process with other repos 2026-03-09 22:28:42 -04:00
scripts feat: Implement prompt 55 2025-11-22 12:50:10 -05:00
src fix: block auth form submission until WASM hydrates 2026-04-09 16:16:45 +02:00
static fix: verify JWT with /api/auth/me to prevent stale-token redirect loop 2026-04-09 15:32:23 +02:00
tests fix: Gate integration tests behind server feature and update cleanup for JWT tables 2026-02-12 18:59:52 +01:00
.dockerignore feat: Sync the build process with other repos 2026-03-09 22:28:42 -04:00
.env.saas.example chore: untrack env files, add .example templates 2026-04-01 02:41:08 +02:00
.env.standalone.example fix: align setup page validation with server and add SETUP_DEFAULT_ADMIN env vars 2026-04-08 22:36:31 +02:00
.gitignore chore: untrack env files, add .example templates 2026-04-01 02:41:08 +02:00
bun.lock added justfile functionality to rusty-links, first launch is of course slow, however after that its normal speed 2026-03-12 11:41:04 +01:00
Cargo.lock feat: Change the Docker port and sync with other repos 2026-03-15 22:55:46 +01:00
Cargo.toml feat(saas): Add maintenance mode with webhook toggle and admin bypass 2026-03-13 15:08:48 +01:00
CHANGELOG.md feat: Replace bcrypt with Argon2id, migrate legacy hashes on login 2026-03-05 21:40:05 +01:00
CLAUDE.md refactor: rename compose.local.yml back to compose.yml 2026-04-01 20:49:11 +02:00
compose.dev.yml feat: add SETUP_DEFAULT_ADMIN env vars to dev compose 2026-04-08 22:52:18 +02:00
compose.yml refactor: rename compose.local.yml back to compose.yml 2026-04-01 20:49:11 +02:00
CONTRIBUTING.md docs: Fix outdated references across all documentation 2026-03-05 20:37:48 +01:00
Dioxus.toml feat: Add favicon.ico 2026-02-23 16:59:00 -05:00
Dockerfile fix: bind dx serve to 0.0.0.0 and fix clean recipe for Traefik routing 2026-04-01 21:04:15 +02:00
jetbrain.json feat: Implement prompt 47 2025-11-22 11:53:40 -05:00
justfile chore: Sync release process 2026-04-16 18:38:04 +02:00
LICENSE.md feat: Implement prompt 50 2025-11-22 12:09:18 -05:00
package.json feat: Handle the case where the logo is missing 2025-11-30 12:37:57 -05:00
README.md feat: Replace bcrypt with Argon2id, migrate legacy hashes on login 2026-03-05 21:40:05 +01:00
stylelint.config.mjs feat: Handle the case where the logo is missing 2025-11-30 12:37:57 -05:00
tailwind.css fix: add missing text-secondary override and use btn-icon class 2026-04-02 21:51:41 +02:00
test_config.sh feat: Implement prompt 2 2025-11-20 14:47:53 -05:00

Rusty Links

A self-hosted bookmark manager built with Rust and Dioxus. Organize, search, and manage your links with automatic metadata extraction and GitHub integration.

Features | Quick Start | Documentation | Contributing


Features

  • JWT authentication with Argon2id password hashing and refresh tokens
  • Link management with full CRUD operations
  • Automatic metadata extraction - titles, descriptions, logos
  • GitHub integration - stars, languages, licenses auto-detected
  • Hierarchical categories (up to 3 levels)
  • Tags, languages, and licenses for organization
  • Full-text search with advanced filtering
  • Scheduled updates to keep metadata fresh
  • Responsive UI - works on mobile, tablet, and desktop
  • Docker ready - one command deployment
  • Two build modes - standalone (self-hosted) and SaaS (parent app auth)

Quick Start

  1. Clone the repository

    git clone https://git.a8n.run/a8n-tools/rusty-links.git
    cd rusty-links
    
  2. Configure environment

    cp .env.standalone .env
    # Edit .env and set a secure database password
    
  3. Start services

    docker compose up -d
    
  4. Access the application

From Source

See Building from Source below.


Configuration

Build Modes

Rusty Links supports two build modes via the BUILD_MODE build argument:

  • standalone (default) - Self-hosted with built-in JWT authentication
  • saas - Authentication handled by a parent application's cookies

Environment variable templates are provided for each mode:

cp .env.standalone .env   # Standalone mode
cp .env.saas .env         # SaaS mode

Environment Variables

Core Settings

Variable Description Default
DATABASE_URL PostgreSQL connection string Required
APP_PORT Application port 8080
HOST_PORT Docker host port mapping 3003
DB_USERNAME PostgreSQL username (Docker Compose) rustylinks
DB_PASSWORD PostgreSQL password (Docker Compose) changeme
DB_NAME PostgreSQL database name (Docker Compose) rustylinks
RUST_LOG Log level (trace, debug, info, warn, error) info

Scheduler Settings

Variable Description Default
UPDATE_INTERVAL_DAYS Days between metadata updates 30
UPDATE_INTERVAL_HOURS Scheduler run frequency (hours) 24
BATCH_SIZE Links processed per batch 50
JITTER_PERCENT Update scheduling jitter (0-100) 20
GITHUB_TOKEN GitHub API token (optional, for higher rate limits) None

Standalone Mode Settings

Variable Description Default
JWT_SECRET Secret key for signing JWT tokens Random
JWT_EXPIRY Access token expiry in hours 1
REFRESH_TOKEN_EXPIRY Refresh token expiry in days 7
ACCOUNT_LOCKOUT_ATTEMPTS Failed login attempts before lockout 5
ACCOUNT_LOCKOUT_DURATION Lockout duration in minutes 30
ALLOW_REGISTRATION Allow new user registration (true/1) true

See .env.standalone and .env.saas for full documentation of all options.


Documentation


Building from Source

Prerequisites

  • Rust (latest stable recommended)
  • PostgreSQL 17+
  • Dioxus CLI (cargo install dioxus-cli or cargo binstall dioxus-cli)

Steps

  1. Install dependencies

    cargo install dioxus-cli
    rustup target add wasm32-unknown-unknown
    
  2. Set up database

    createdb rustylinks
    
  3. Configure environment

    cp .env.standalone .env
    # Edit .env with your database URL
    
  4. Run development server

    dx serve
    

    Migrations run automatically on startup.

  5. Build for production

    dx build --release
    

Architecture

  • Backend: Rust with Axum web framework
  • Frontend: Dioxus 0.7 (fullstack mode with SSR)
  • Database: PostgreSQL with SQLx (compile-time checked queries)
  • Authentication: JWT tokens with Argon2id password hashing
  • Scraping: reqwest + scraper crate
  • Styling: Tailwind CSS v4
  • Deployment: Docker + Docker Compose

Project Structure

rusty-links/
├── src/
│   ├── main.rs              # Application entry point
│   ├── lib.rs               # Library root, feature-gated modules
│   ├── config.rs            # Environment-based configuration
│   ├── error.rs             # Centralized error handling
│   ├── security.rs          # Security utilities
│   ├── api/                 # REST API endpoints
│   ├── auth/                # JWT authentication and middleware
│   ├── github/              # GitHub API integration
│   ├── models/              # Database models (User, Link, Category, Tag, etc.)
│   ├── scheduler/           # Background task runner
│   ├── scraper/             # HTML metadata extraction
│   ├── server_functions/    # Dioxus server functions (client/server bridge)
│   └── ui/                  # Dioxus frontend
│       ├── app.rs           # Root component and routing
│       ├── components/      # Reusable UI components
│       └── pages/           # Page components
├── migrations/              # Database migrations (8 files)
├── assets/                  # Static assets (generated CSS, favicon)
├── examples/                # Reverse proxy configs (nginx, Caddy)
├── docs/                    # Documentation
├── Dockerfile               # Multi-stage production build
├── compose.yml              # Docker Compose (app + PostgreSQL)
└── compose.dev.yml          # Development override (hot reloading)

Development

Running Tests

cargo test

Development with Docker

For development with hot reloading:

docker compose -f compose.yml -f compose.dev.yml up

Database Migrations

Migrations run automatically on application startup. For manual control:

cargo install sqlx-cli --no-default-features --features postgres

# Create new migration
sqlx migrate add <migration_name>

# Run migrations
sqlx migrate run

Code Quality

cargo fmt
cargo clippy
cargo check
cargo check --features server
cargo check --features web --target wasm32-unknown-unknown

Production Deployment

See docs/DOCKER.md and docs/DEPLOYMENT.md for complete instructions.

Quick production deployment:

docker compose up -d

# View logs
docker compose logs -f app

# Check status
docker compose ps

Security Considerations

  • Always set a strong DB_PASSWORD and JWT_SECRET
  • Run as non-root user (default in Docker: appuser, UID 1001)
  • Use HTTPS in production (reverse proxy recommended, see examples/)
  • Regularly backup your database

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.


License

This project is licensed under the MIT License - see LICENSE for details.


Credits

Built with Rust, Dioxus, Axum, SQLx, PostgreSQL, and Docker.


TODO

  • Delete oci-build/setup.nu — orphaned now that the Dockerfile uses the dummy-src pattern
  • Remove or update .cargo/config.toml — sets target = "x86_64-unknown-linux-gnu" (glibc), which conflicts with Alpine/musl Docker builds