Skip to content

Repository files navigation

RepoAssets

RepoAssets is a self-hostable asset management dashboard that stores files and metadata in your own GitHub repository. It is built for small image/audio libraries, prototypes, student projects, indie games, public sample datasets, and personal media collections.

Users get a friendly browser UI for uploading, browsing, filtering, editing, and deleting assets. GitHub remains the source of truth: files are committed through the GitHub Contents API, and metadata is stored in a JSON manifest.

What It Does

  • Uploads images, audio, and other files to configurable GitHub folders.
  • Stores asset metadata in a configurable JSON manifest such as data/assets.json.
  • Supports configurable fields through dam.config.json.
  • Provides search, type filters, collection filters, tag filters, and audio filters.
  • Supports metadata edits, file replacement, linked audio replacement/removal, and asset deletion.
  • Falls back to a read-only demo dataset when the API is offline.

Tech Stack

  • React 19 + Vite
  • TypeScript
  • Express 5
  • GitHub Contents API via Octokit
  • Multer for multipart file uploads

Repository Layout

.
+-- src/ # React dashboard
+-- server/ # Express API and maintenance scripts
+-- public/demo-assets.json # Read-only demo data
+-- docs/
+-- dam.config.json # Local dashboard/schema config
+-- dam.config.example.json
+-- .env.example
+-- package.json

Prerequisites

  • Node.js 20 or newer recommended.
  • A GitHub personal access token with permission to write to the target asset repository.
  • A GitHub repository that will store uploaded files and the manifest.

Setup

Install dependencies:

npm install

Create your local environment file:

cp .env.example .env

Fill in the GitHub repository settings:

GITHUB_TOKEN=ghp_exampletokenGITHUB_OWNER=owner-nameGITHUB_REPO=repoassets-libraryGITHUB_BRANCH=mainMANIFEST_PATH=data/assets.jsonIMAGE_DIR=imagesAUDIO_DIR=audioFILE_DIR=filesPORT=4000ALLOWED_ORIGINS=http://localhost:5173MAX_FILE_SIZE_BYTES=15728640

Keep .env private. It contains the token used to commit files to GitHub.

Configure The Dashboard

Edit dam.config.json to change the dashboard name, manifest path, upload folders, and fields.

{
"projectName": "My Asset Library",
"projectDescription": "Images, audio, and metadata stored in GitHub.",
"manifestPath": "data/assets.json",
"assetFolders": {
"images": "images",
"audio": "audio",
"files": "files"
},
"fields": [
{ "name": "title", "label": "Title", "type": "text", "required": true },
{ "name": "description", "label": "Description", "type": "textarea" },
{ "name": "collection", "label": "Collection", "type": "text" },
{ "name": "tags", "label": "Tags", "type": "tags" },
{
"name": "license",
"label": "License",
"type": "select",
"options": ["personal", "internal", "public", "unknown"]
}
]
}

Supported field types:

  • text
  • textarea
  • select
  • tags
  • url

Development

Run the frontend and API server in separate terminals:

npm run dev
npm run server

By default:

  • Dashboard: http://localhost:5173
  • API: http://localhost:4000
  • Health check: http://localhost:4000/health

If the API is hosted somewhere else, set VITE_API_BASE_URL for the frontend.

Available Scripts

npm run dev # Start the Vite dashboard
npm run server # Start the Express API
npm run build # Type-check and build the frontend
npm run lint # Run ESLint
npm run preview # Preview the production build
npm run migrate:manifest # Legacy Sanskrit manifest migration helper
npm run migrate:manifest:apply
npm run upload:bulk # Legacy Sanskrit bulk upload helper

Asset Schema

Manifest entries are stored as an array:

{
"id": "hero-banner",
"title": "Hero Banner",
"description": "Homepage campaign image",
"type": "image",
"tags": ["marketing", "homepage"],
"collection": "Website",
"files": {
"original": "https://raw.githubusercontent.com/owner/repo/main/images/hero-banner.png",
"audio": ""
},
"metadata": {
"license": "internal",
"altText": "Product dashboard screenshot"
},
"source": {
"fileName": "hero-banner.png",
"mimeType": "image/png",
"size": 128000
},
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-01-01T00:00:00.000Z"
}

API Overview

GET /api/config

Returns the active dashboard configuration.

GET /api/assets

Returns assets from the manifest.

Optional query params:

  • q: searches title, description, tags, collection, type, and metadata
  • type: image, audio, or file
  • collection: exact collection match
  • tag: exact tag match
  • hasAudio: true or false

POST /api/assets

Accepts multipart/form-data and creates a new asset.

Fields:

  • originalFile - required
  • audioFile - optional linked audio file
  • assetId - optional slug override
  • configured fields from dam.config.json

PATCH /api/assets/:assetId

Updates an asset's metadata. It can also replace the primary file, replace linked audio, or remove linked audio with removeAudio=true.

DELETE /api/assets/:assetId

Deletes the manifest entry and removes associated GitHub files when they can be resolved.

Public Demo Strategy

The frontend can show public/demo-assets.json when the API is offline. This is useful for a safe read-only public demo because no GitHub token is exposed and visitors cannot write to the sample repository.

For a full writable demo, host the Express API somewhere like Render, Railway, or Fly.io and add authentication before exposing it publicly.

Notes

  • Asset URLs are written as raw.githubusercontent.com links to reduce cache delay after updates.
  • GitHub tokens must stay on the server and should never be exposed to the frontend.
  • RepoAssets is intended for lightweight libraries, not unlimited storage or high-traffic media delivery.

About

React + Express dashboard for uploading and managing image/audio assets with a GitHub-backed JSON manifest.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages