Manifest 1.0 • Updated when assets change

Trinix PFP Asset Documentation

The Trinix PFP site serves a static library of avatars, banners, and GIFs through a JSON manifest and a lightweight browser client. This guide explains how to load the manifest, interpret the structure, and work with the helper utilities provided in client-api.js.

📦 Static JSON manifest
🔓 No authentication required
🧰 Built-in JavaScript client

Getting Started

The asset catalogue is exposed through the assets.json manifest that ships with the site. The manifest lives at https://pfp.trinix.gg/assets.json in production and mirrors the repository's assets.json file. The bundled client-api.js helper wraps the manifest with convenient filtering, search, and favorite helpers.

1. Reference the manifest

Serve assets.json alongside the static assets. If you host the site elsewhere, keep the relative folder structure (pics/, gifs/, AI/, banners/) intact so the manifest paths remain valid.

2. Load client-api.js

Include the script on any page that needs programmatic access to the manifest. The module exposes a global TrinixPFP object with a createClient factory.

3. Instantiate a client

Create a client with optional baseUrl and manifestPath overrides to support custom deployments. The client fetches and transforms the manifest into rich asset objects.

4. Render assets

Use helpers such as listAll(), filterByTag(), and search() to drive galleries, download lists, or custom browsing experiences.

Access

No authentication or tokens are required. The manifest and all media files are publicly readable static assets. Standard HTTPS requests and browser fetch calls are sufficient.

Direct download

Request the manifest or any asset with a simple HTTP GET. CDN caching is handled automatically by the hosting platform.

curl https://pfp.trinix.gg/assets.json

Custom deployments

If you mirror the repository, configure the client with your base URL so generated asset links stay correct.

const client = TrinixPFP.createClient({
  baseUrl: 'https://cdn.example.com/pfps/'
});
const response = await fetch('https://pfp.trinix.gg/assets.json');
const manifest = await response.json();

console.log(`Loaded ${manifest.pics.length} profile pictures`);
import fs from 'node:fs/promises';

const response = await fetch('https://pfp.trinix.gg/assets.json');
const manifest = await response.json();

await fs.writeFile('assets.json', JSON.stringify(manifest, null, 2));
import requests

resp = requests.get('https://pfp.trinix.gg/assets.json', timeout=10)
resp.raise_for_status()
manifest = resp.json()

print('Total assets:', sum(len(v) for v in manifest.values()))
package main

import (
    "encoding/json"
    "fmt"
    "net/http"
)

func main() {
    resp, err := http.Get("https://pfp.trinix.gg/assets.json")
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    var manifest map[string][]string
    if err := json.NewDecoder(resp.Body).Decode(&manifest); err != nil {
        panic(err)
    }

    fmt.Println("GIF count:", len(manifest["gifs"]))
}

Caching & Limits

The manifest is static and served from a CDN. There are no application-level rate limits, but browsers and CDNs may cache responses aggressively. When iterating locally you can append a cache-busting query parameter or enable the built-in cache bust options on the client.

  • Use forceRefresh with listAll() to bypass the cached manifest.
  • The client automatically appends a cache-busting token if cacheBust is enabled in the constructor options.
  • Respect CDN bandwidth limits by avoiding unnecessary polling—mirror the JSON locally when doing bulk processing.

Error Handling

The client surfaces plain JavaScript errors. Network failures reject with the underlying fetch error and HTTP status, while manifest parsing issues emit a descriptive message. Wrap async calls in a try/catch to provide user-friendly fallbacks.

try {
  const items = await client.listAll();
  render(items);
} catch (error) {
  console.error('Unable to load PFPs', error);
  showOfflineState();
}

When favorites cannot be written to localStorage (for example in private browsing modes) the client logs a warning but continues operating in memory.

Manifest Schema

The manifest is a single JSON document that groups asset file names by category. Each file name corresponds to a relative path inside the repository. The client converts these entries into richer objects with derived tags, alt text, and fully qualified URLs.

Key Type Description
pics Array<string> Static PNG/JPG profile images located under pics/.
gifs Array<string> Animated GIF/WebP avatars stored in gifs/.
ai Array<string> AI-generated artwork located in the AI/ directory.
bannerPics Array<string> Static profile banners under banners/pics/.
bannerGifs Array<string> Animated banners hosted inside banners/gifs/.
{
  "pics": ["000ca56d...png", "00187d8...jpg"],
  "gifs": ["anime-loop.gif"],
  "ai": ["futuristic-avatar.png"],
  "bannerPics": ["galaxy-banner.png"],
  "bannerGifs": ["waves.gif"]
}

Additional fields may be added over time as new asset groups are introduced. Always treat unknown keys as optional so the manifest can evolve without breaking clients.

Client API

The TrinixPFP helper exposes a factory that returns a stateful client. It caches the manifest, derives additional metadata, and provides convenience methods for filtering and favorites. All methods are promise-based.

const client = TrinixPFP.createClient({
  baseUrl: 'https://pfp.trinix.gg/',
  cacheBust: true
});

const items = await client.listAll();
console.log(`Loaded ${items.length} assets`);
const animeGifs = await client.filterByTag('anime');
const banners = await client.filterByFolder('bannerPics');

// Search matches alt text, tags, file names, and type
const neonResults = await client.search('neon animated');
const counts = await client.getCounts();

console.log(counts.total);      // all assets
console.log(counts.byTag.ai);   // AI collection size
console.log(counts.byFolder.gifs);

Filtering & Search

The client enriches each manifest entry with tags, alt text, and type information (static vs animated). Utility methods help build curated views without manually parsing the JSON.

  • filterByTag(tag) – Matches derived tags like anime, cute, minimal, or the explicit ai folder.
  • filterByFolder(folder) – Returns assets from a specific manifest group such as gifs or bannerPics.
  • search(query) – Tokenized search across alt text, file names, tags, and asset type.
  • getRandom(count) – Retrieves a shuffled subset for quick spotlight sections.
const randomAnimated = await client.getRandom(3);
const cuteResults = await client.search('cute pastel');

renderGallery(cuteResults);
renderHighlights(randomAnimated);

Favorites

The client keeps track of favorite assets by ID. Favorites are stored in localStorage when available and fall back to an in-memory set when persistence is disabled or unsupported.

Toggle & read client.toggleFavorite(id) Returns the updated favorite list so UI state can refresh immediately.
Persist client.getFavoriteItems() Fetches the manifest and returns the matching asset objects.
Custom storage keys TrinixPFP.createClient({ storageKey: 'my-app-favs' }) Isolate favorites between different embeds or environments.
Disable persistence TrinixPFP.createClient({ persistFavorites: false }) Keep favorites session-only for ephemeral experiences.

Asset Directories

The manifest references files relative to the repository root. Maintain this structure if you host the project yourself so generated URLs stay correct.

assets.json
pics/
gifs/
AI/
banners/
  ├─ pics/
  └─ gifs/
videos/

Additional folders such as AI/ or videos/ are optional enhancements and can be excluded if you do not need them. Update the manifest accordingly when adding or removing assets.

Examples & Tutorials

These example ideas illustrate common ways to consume the manifest and client. Adapt them to your preferred framework or static site builder.

Static gallery page

Use client.listAll() to render a masonry grid with lazy-loaded images. Apply filterByTag() to drive category tabs.

Next.js build step

Fetch assets.json during getStaticProps and pre-render pages with optimized image components for instant loads.

Search-driven modal

Wire client.search() to an input field to let users quickly look up matching avatars without a page reload.

Browser extension

Bundle the manifest and reuse getRandom() to rotate avatars directly from the toolbar.

Language example
JavaScript