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

@funeste38/freeland

v0.2.2

Published

Typed normalization hub for heterogeneous values across prefixes, files, runtimes and platforms (json:, b64:, file:, exe:, zip:, nez:, ...).

Readme

freeland

Freeland is the neutral normalization layer of the Funesterie ecosystem.

v1 was a prefix decoder. v2 keeps that compatibility, but upgrades Freeland into a typed hub:

heterogeneous input -> Freeland parse -> typed canonical object -> runtime adaptation

That means Freeland can now be the place where text, JSON, files, images, executables, archives, URLs and secrets all pass through the same language before they hit A11, Qflush, Spyder or deployment runtimes.

Install

npm install @funeste38/freeland

The unscoped freeland package is deprecated. Use the scoped package directly.

Legacy v1 API

The original API still works:

import { registerSystem, decodeSystemValue } from "@funeste38/freeland";

registerSystem("upper:", (raw) => raw.toUpperCase());

const shout = await decodeSystemValue("upper:funesterie");

Built-in legacy prefixes:

  • json:
  • b64: / base64:
  • file:
  • nez:

Typed v2 API

The new API resolves an input into a canonical object:

import { resolveFreelandValue } from "@funeste38/freeland";

const value = await resolveFreelandValue("b64:SGVsbG8=");

Example result:

{
  "kind": "text",
  "format": "base64",
  "encoding": "utf8",
  "value": "Hello",
  "state": "compatible",
  "runtime": "node",
  "platform": "linux"
}

Main exported concepts

  • resolveFreelandValue(input, options)
  • adaptFreelandValue(value, runtime)
  • registerFormat(prefix, handler)
  • registerAdapter(runtime, adapter)
  • parseFreelandInput(input)
  • toFreelandCube(value, runtime?)

Canonical value shape

type FreelandValue = {
  kind:
    | "text"
    | "json"
    | "binary"
    | "image"
    | "audio"
    | "executable"
    | "archive"
    | "path"
    | "url"
    | "secret"
    | "identifier"
    | "unknown";
  format?: string;
  platform?: "windows" | "linux" | "mac" | "any";
  runtime?: "windows" | "linux" | "mac" | "docker" | "railway" | "local" | "browser" | "node" | "any";
  mime?: string;
  encoding?: string;
  value: unknown;
  state?: "raw" | "decoded" | "normalized" | "resolved" | "compatible" | "incompatible";
  meta?: Record<string, unknown>;
};

Composition

Freeland supports nested prefixes:

b64:file:./hello.b64.txt
exe:json:{"windows":"path:./bin/piper.exe","linux":"path:./bin/piper"}
zip:file:./artifacts/release.zip
manifest:json:{"kind":"executable","variants":{"windows":"path:./bin/piper.exe","linux":"path:./bin/piper"}}

Resolution happens from inside to outside:

  • file: first
  • then b64:
  • then runtime adaptation if requested

Built-in format families

  • text: text:
  • structured: json:
  • binary: b64:, base64:, hex:, bin:
  • filesystem: file:, path:
  • identity/transport: url:, id:, secret:, nez:
  • assets: img:, image:, audio:
  • containers: zip:, tar:, archive:
  • runtime artifacts: exe:

Runtime-aware executables

Freeland now has a first-class way to describe executables by target:

const ffmpeg = await resolveFreelandValue(
  'exe:json:{"windows":"path:./bin/ffmpeg.exe","linux":"path:./bin/ffmpeg","default":"path:./bin/ffmpeg"}',
  { runtime: "railway" }
);

Freeland will:

  • pick the best variant for the runtime/platform
  • mark the result compatible or incompatible
  • refuse browser execution targets for native executables

Manifests

Freeland now supports lightweight manifests for runtime-aware resources:

const runtimeTool = await resolveFreelandValue(
  'manifest:json:{"kind":"executable","variants":{"windows":"path:./bin/piper.exe","linux":"path:./bin/piper"},"meta":{"name":"piper"}}',
  { runtime: "railway" }
);

This is the cleanest way to describe:

  • runtime-specific executables
  • portable bundles
  • future image/audio/archive variants
  • metadata-rich resources without inventing more one-off prefixes

Zip and archive support

Yes: archives should be first-class.

Freeland should not treat zip as "just another string prefix". It should treat it as a container family:

  • zip: for zip-specific tagging
  • archive: as the neutral umbrella kind
  • later: optional unpack/list/inspect adapters without bloating the core

That gives you room for:

  • release bundles
  • embedded assets
  • portable module packs
  • hand-off between local, CI and Railway

RGBA / Rubik / Morphing

My recommendation:

  • keep freeland as the typed normalization core
  • keep morphing as the low-level 4-byte transport primitive
  • keep RGBA / Rubik visualization as a separate layer above the core

In practice:

  • freeland answers: "what is this value?"
  • morphing answers: "how do I pack or move this compactly?"
  • freeland-bros or another addon can answer: "how do I visualize or solve compatibility as RGBA / cube rotations?"

That is why v2 exports toFreelandCube() already: it gives you a stable bridge toward the Rubik/RGBA idea without forcing the core to depend on image semantics too early.

CLI

Freeland now ships a real CLI:

freeland --pretty "b64:SGVsbG8="
freeland --runtime railway --pretty "exe:json:{\"windows\":\"path:./bin/piper.exe\",\"linux\":\"path:./bin/piper\"}"
freeland --legacy "file:./.env"

Suggestions for the next step

The best next upgrade is not "more prefixes". It is:

  1. freeland-core
  2. freeland-adapters
  3. freeland-bros

Concretely:

  1. Keep freeland small, typed and deterministic.
  2. Put heavy or optional adapters behind opt-in packages.
  3. Build RGBA / cube solving on top of the canonical object, not inside the parser.

Development

npm install
npm run build
npm test

License

MIT