All projects
Developer Tool / Asset Management
2026 Actively maintained

Vault

A private, self-hosted asset vault that optimizes images in the browser, stores files in GitHub repositories, and returns immutable jsDelivr URLs pinned to commit SHAs.

Manage isolated GitHub-backed storage vaults and monitor their capacity from one dashboard.

Project overview

Vault grew from a recurring need across frontend projects: static hosts either cache public assets briefly, consume deployment bandwidth, or require hashed build imports that are inconvenient for reusable media URLs.

The application creates isolated GitHub-backed vaults, optimizes images in the browser, commits files through the GitHub REST API, and returns permanent jsDelivr URLs pinned to the resulting commit SHA.

A private single-user deployment keeps credentials and the GitHub token server-side while providing a focused interface for managing reusable project assets.

Objectives

  1. 01

    Reduce media hosting costs

    Use GitHub repositories and jsDelivr delivery instead of consuming storage and bandwidth quotas on application hosts.

  2. 02

    Create cache-safe asset URLs

    Pin every CDN URL to an exact commit SHA so uploaded files remain immutable and never serve stale revisions.

  3. 03

    Optimize before upload

    Resize, convert, and compress images in the browser before they consume repository storage or serverless payload capacity.

  4. 04

    Keep self-deployment simple

    Provide a private serverless application without dedicated object-storage infrastructure or a user database.

Key features

GitHub-backed vaults

Create isolated vaults backed by automatically provisioned personal or organization repositories.

Client-side image optimization

Convert PNG and JPEG images, adjust quality, and resize with a locked aspect ratio through the Canvas API.

Immutable CDN delivery

Generate jsDelivr URLs pinned to the commit SHA returned by each GitHub upload.

Searchable file browser

Browse files with infinite pagination, debounced search, sorting, previews, and one-click CDN URL copy.

Collision-safe uploads

Detect duplicate filenames and append numeric suffixes rather than overwriting existing assets.

Protected private access

Combine signed JWT session cookies with an IP-aware Netlify Edge rate limit on login attempts.

Challenges and decisions

Avoiding stale CDN assets

Challenge

Reusing a filename and path can leave consumers receiving an older aggressively cached asset.

Decision

Build every jsDelivr URL with the exact commit SHA returned by GitHub, making each uploaded revision immutable.

Serverless payload size limits

Challenge

Base64 encoding increases request size while serverless platforms impose strict body limits.

Decision

Enforce a 4 MB ceiling on both client and server, with browser-side optimization available before upload.

Handling browser image capabilities

Challenge

Canvas export support varies between browsers and unsupported formats can fail silently.

Decision

Check supported formats at runtime, then hide or disable unavailable conversion options before processing begins.

Protecting a private serverless tool

Challenge

The application needed secure access without the overhead of a user database or stateful sessions.

Decision

Use signed HttpOnly JWT cookies for stateless sessions and a Netlify Edge Function to rate-limit login attempts.

My contribution

  • Designed and implemented the full-stack SvelteKit application and its responsive interface.
  • Architected the vault-per-repository storage model and GitHub REST API integration.
  • Built the Canvas-based image conversion, resizing, quality control, and upload-progress workflow.
  • Designed the Drizzle and Turso data model for vault and immutable file metadata.
  • Implemented JWT session protection, GitHub rate-limit handling, and Netlify deployment configuration.

Lượng Đức Trọng

© 2026. Made with ❤️ by Duc Trong Luong