kjanat/glb-compressor · Archived

glb-compressor-server

HTTP server for compressing GLB/glTF 3D models via REST API and SSE streaming. Use when building web integrations, setting up a compression microservice, or adding real-time compression progress to a frontend.

First seen Feb 20, 2026

Installation

$ npx skills add kjanat/glb-compressor --skill glb-compressor-server

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from kjanat/glb-compressor.

npx skills add kjanat/glb-compressor

Browse all from kjanat/glb-compressor

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

License LICENSE
Default branch master
Open issues 0
Status Archived

Skill metadata

Parsed from SKILL.md frontmatter.

LicenseMIT
CompatibilityRequires Bun >= 1.3 or Node.js >= 22.22.2. Optional gltfpack binary for best compression.

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 4,662 B
  • docs SUMMARY.md 238 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 7 installs

SKILL.md

glb-compressor Server

HTTP compression server built on Bun.serve(). Provides synchronous and streaming (SSE) compression endpoints with full CORS support.

Starting the Server

# Production (from installed package)
glb-server

# Development (hot reload)
bun run dev

# Custom port
PORT=3000 bun run start

Default port: 8080 (override via PORT env var).

Endpoints

GET /healthz

Health check. Returns 200 ok.

POST /compress

Synchronous compression. Returns compressed GLB binary.

Accepts: multipart/form-data (field: file) or raw application/octet-stream.

Query params / form fields:

  • preset - Compression preset: default, balanced, aggressive, max
  • simplify - Mesh simplification ratio (0, 1), e.g. 0.5

Form fields override query params when both are provided.

Response headers:

Header Description
X-Request-ID UUID tracking this request
X-Original-Size Input file size in bytes
X-Compressed-Size Output file size in bytes
X-Compression-Method gltfpack or meshopt
X-Compression-Ratio Percentage reduction (e.g. 84.1)
Content-Disposition Suggested download filename

Example:

# Multipart upload
curl -X POST -F "[email protected]" \
  "http://localhost:8080/compress?preset=aggressive" \
  -o compressed.glb

# Raw binary upload
curl -X POST --data-binary @model.glb \
  -H "Content-Type: application/octet-stream" \
  "http://localhost:8080/compress?preset=balanced" \
  -o compressed.glb

POST /compress-stream

SSE streaming compression with real-time progress. Multipart only.

Content-Type: text/event-stream

SSE events:

Event Data shape
log { message: string }
result { requestId, filename, data (base64), originalSize, compressedSize, ratio, method }
error { message, requestId, code }

Stream closes after result or error event.

Example (JavaScript):

const form = new FormData();
form.append('file', glbFile);

const response = await fetch(
	'http://localhost:8080/compress-stream?preset=aggressive',
	{ method: 'POST', body: form },
);

const reader = response.body.getReader();
const decoder = new TextDecoder();

// Parse SSE events from the stream
while (true) {
	const { done, value } = await reader.read();
	if (done) break;
	const text = decoder.decode(value);
	// Parse "event: <type>\ndata: <json>\n\n" format
	console.log(text);
}

Error Responses

All errors return structured JSON:

{
	"error": { "code": "ERROR_CODE", "message": "Human-readable message" },
	"requestId": "uuid"
}

Error codes:

Code HTTP Description
NOFILEPROVIDED 400 No file in form data
INVALID_GLB 400 Failed GLB magic byte validation
FILETOOLARGE 413 Exceeds 100 MB limit
INVALIDCONTENTTYPE 415 Non-multipart on streaming endpoint
COMPRESSION_FAILED 500 Pipeline error during compression

CORS

Full CORS enabled on all endpoints. Exposed headers: X-Request-ID, X-Original-Size, X-Compressed-Size, X-Compression-Method, X-Compression-Ratio.

Limits

  • Max file size: 100 MB
  • gltfpack timeout: 60 seconds per file

Architecture Notes

  • import.meta.main guard: safe to import server/main.ts as a library without

starting the server.

  • Request ID (X-Request-ID) is generated per request and logged server-side.
  • The /compress-stream endpoint sends the compressed GLB as base64 in the

result SSE event (~33% larger than binary). For large files near the 100 MB limit, prefer /compress.