npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

zephyra-codec

v0.1.3

Published

Zephyra Core SDK — deterministic export-time layer preservation and byte-exact deconstruction for video files.

Readme

@zephyra/blackvideo-codec SDK

Standalone Node.js/TypeScript library implementing Zephyra's Exporter and Deconstructor. No UI, no host assumptions — this package only knows how to turn a base video + layer instructions into a normal, playable video file with the original source embedded inside it, and how to read that back out byte-for-byte.

Install

npm install zephyra-codec
pnpm install zephyra-codec

Requires ffmpeg on PATH (or pass ffmpegPath explicitly). Node.js LTS (>=18).

Usage

import { Exporter, Deconstructor } from "zephyra-codec";

const exporter = new Exporter();
const result = await exporter.export({
  baseVideoPath: "./raw/interview.mp4",
  layers: [
    {
      id: "lower-third",
      type: "text",
      startTime: 2,
      endTime: 8,
      transform: { x: 40, y: 400, scale: 1, rotation: 0 },
      opacity: 1,
      data: { text: "Jane Doe, CTO", fontsize: 28, fontcolor: "white" },
    },
  ],
  outputPath: "./out/interview.zephyra.mp4",
});
// result.outputPath is a completely normal, playable mp4.

const deconstructor = new Deconstructor();
const restored = await deconstructor.deconstruct({
  inputPath: "./out/interview.zephyra.mp4",
  outDir: "./restored",
});
// restored.baseVideoPath is byte-identical to ./raw/interview.mp4
// restored.timeline.layers is the original layers array

How it works

  1. Exporter renders a standard flattened video with ffmpeg, then appends a single unknown-typed top-level box (zeph) to the end of the ISO-BMFF (mp4) container. Standard players and demuxers iterate the box list and skip types they don't recognize — this is the same mechanism vendor metadata boxes use today, not a hack specific to this SDK. Appending at the end never shifts the byte offsets of anything already written, so nothing inside moov needs to be rewritten.
  2. The zeph box payload is the original base video's raw bytes plus the layer instructions, MessagePack-encoded and gzip-compressed.
  3. Deconstructor never touches ffmpeg. It scans the box list, finds zeph, decompresses and decodes it, and writes the base video bytes back out untouched. This is why restoration is byte-exact — the original bytes were never re-encoded, only carried along for the ride.

Design notes / deliberate scope decisions

  • Zero runtime dependencies. The MessagePack codec (src/serialization/msgpack.ts) and the ffmpeg process wrapper (src/ffmpeg/ffmpegBinary.ts) are hand-rolled rather than pulled in via msgpackr/fluent-ffmpeg. Both are wire/behavior compatible with their namesake libraries (MessagePack is a standard spec; the ffmpeg wrapper is just spawn + arg building), so a host is free to swap them in later — but keeping the dependency tree empty removes the biggest source of friction when this package is eventually bundled into a pkg/nexe sidecar binary.
  • Core vs. I/O separation. Exporter/Deconstructor are the only filesystem-touching pieces. Everything they call — encodePayload/decodePayload, appendBox/findTopLevelBox — is a pure function operating on Buffers in memory. These are re-exported from src/index.ts specifically so a future HTTP/WebSocket wrapper can call them directly against request bodies without going through disk.
  • No AI, no approximation in Deconstructor. Restoration is pure ISO-BMFF box scanning + decompression. The round-trip test (test/roundtrip.test.ts) is the acceptance bar: export → deconstruct → Buffer.compare against the original source must be 0, every time.

Scripts

npm run build       # tsc -> dist/
npm test            # runs the full test suite (node:test via tsx), including the round-trip test
npm run typecheck   # tsc --noEmit

Public API

  • Exporter.export(options: ExportOptions): Promise<ExportResult>
  • Deconstructor.deconstruct(options: DeconstructOptions): Promise<DeconstructResult>
  • Pure helpers: encodePayload, decodePayload, appendBox, findTopLevelBox, readBoxPayload, listTopLevelBoxes, stripTopLevelBox, msgpackEncode, msgpackDecode
  • Types: LayerInstruction, ZephyraTimeline, ZephyraPayload, ExportOptions, ExportResult, DeconstructOptions, DeconstructResult, ZephyraFormatError

See src/types.ts for full type definitions.

Out of scope (by design, per the project brief)

No UI, no Tauri, no desktop shell — this package assumes nothing about who calls it. It's meant to be imported directly by a Node host, compiled into a sidecar binary, or wrapped in an HTTP/WebSocket server, none of which are implemented here.