No description
  • Rust 84.3%
  • CSS 9%
  • HTML 2.4%
  • Shell 2.1%
  • Just 1.3%
  • Other 0.8%
Find a file
2026-06-13 19:46:41 +02:00
.cargo wip: Upgrade all dependencies and update the code 2025-11-23 18:13:41 -05:00
.claude sso progress, justfile dev-sso added 2026-04-30 11:18:57 +02:00
.devcontainer feat: Routing works 2025-11-28 18:02:37 -05:00
.forgejo/workflows fix(oci): extract index digest in verify step so attestation builds pass 2026-06-09 20:34:40 +02:00
.idea chore: Format code using rustfmt 2025-11-30 08:50:22 -05:00
assets implemented SSO, and corrections 2026-04-30 11:18:57 +02:00
docs adding SSO 2026-04-30 11:18:57 +02:00
examples ci: verify pushed OCI digest and drop dead BUILD_MODE arg 2026-06-08 18:16:11 +02:00
migrations feat: track auth_via_oidc on sessions and surface in UserInfo 2026-04-30 11:18:57 +02:00
oci-build fix(oci): pin dioxus to 0.7.7 and restore FROM to v1.0.1 2026-06-09 15:52:17 +02:00
scripts chore: move pre-commit logic from scripts/ into the justfile 2026-05-10 14:39:14 -04:00
src feat: unify standalone and saas into one runtime-mode binary 2026-06-07 12:26:35 -04:00
static fix: verify JWT with /api/auth/me to prevent stale-token redirect loop 2026-04-09 15:32:23 +02:00
tests feat: unify standalone and saas into one runtime-mode binary 2026-06-07 12:26:35 -04:00
.dockerignore feat: Sync the build process with other repos 2026-03-09 22:28:42 -04:00
.env.saas.example feat: unify standalone and saas into one runtime-mode binary 2026-06-07 12:26:35 -04:00
.env.standalone.example feat: unify standalone and saas into one runtime-mode binary 2026-06-07 12:26:35 -04:00
.gitignore chore: Sync .gitignore 2026-06-06 13:21:49 -04:00
build.rs style: apply cargo fmt 2026-05-10 12:57:06 -04: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 fix(oci): pin dioxus to 0.7.7 and restore FROM to v1.0.1 2026-06-09 15:52:17 +02:00
Cargo.toml fix(oci): pin dioxus to 0.7.7 and restore FROM to v1.0.1 2026-06-09 15:52:17 +02:00
CHANGELOG.md feat: Replace bcrypt with Argon2id, migrate legacy hashes on login 2026-03-05 21:40:05 +01:00
CLAUDE.md feat: unify standalone and saas into one runtime-mode binary 2026-06-07 12:26:35 -04:00
compose.dev.yml feat: embed version, git hash, and build date in all binaries 2026-05-07 21:12:55 +02:00
compose.yml chore: add dev- prefix to compose.yml container names 2026-05-05 16:36:44 +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 chore(build): bump rust-builder-glibc to v1.0.1 2026-06-06 22:25:29 -04:00
jetbrain.json feat: Implement prompt 47 2025-11-22 11:53:40 -05:00
justfile feat(justfile): add dev-clean / dev-clean-all teardown recipes 2026-06-13 12:55:19 -04:00
LICENSE Add LICENSE 2026-04-24 15:36:05 +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