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

@kurot/atlas

v0.1.0

Published

Independent RGBA atlas packing and PNG tooling with Kurot-compatible sheet output

Readme

@kurot/atlas

Version 0.1.0 — initial local implementation, not published.

Independent, deterministic sprite-atlas tooling. Packs straight-alpha RGBA pixels and outputs the flat file/frames sheet format consumed by Kurot. No dependency on Core, UI, ui-document, ui-runtime or CLI; none of those packages depend on atlas. It can be called by Reskin, Editor, a separate atlas tool or build automation.

Entry points

  • @kurot/atlas: pixel-only packing, portable ES2022, no Node or PNG imports.
  • @kurot/atlas/png: synchronous Node.js >=20 PNG decoding/encoding through pngjs, without native binaries.

The package performs no filesystem I/O. Callers own reading, source-image storage, project-path validation, resource manifests, worker scheduling and atomic saves. The PNG functions are synchronous; run larger batches in your tool's worker.

PNG example

After installing/linking the package into a tool:

import { readFile, writeFile } from 'node:fs/promises';
import { packPNGAtlas } from '@kurot/atlas/png';

const result = packPNGAtlas([
	{ name: 'r_btn_bet', png: await readFile('src/basis/r_btn_bet.png') },
	{ name: 'r_prg_thumb', png: await readFile('src/basis/r_prg_thumb.png') },
], { file: 'r_basis.png' });

// Demonstration only: a project editor must stage and commit the pair together.
await writeFile('export/r_basis.png', result.png);
await writeFile('export/r_basis.json', JSON.stringify(result.data, undefined, 2) + '\n');

Frame names are supplied explicitly and remain stable; the library does not derive names from filesystem paths. Names start with an ASCII letter or digit, followed by letters, digits, underscores, hyphens or dots. Duplicates are errors. The file option is a PNG basename, resolved relative to the JSON by the consumer.

Pixel example

import { packAtlas } from '@kurot/atlas';

const result = packAtlas([
	{ name: 'red', width: 1, height: 1, pixels: new Uint8Array([255, 0, 0, 255]) },
]);
// result.image contains width, height and RGBA pixels; result.data contains the sheet JSON.

Pixel input is row-major, four bytes per pixel, straight alpha, 8-bit channels. Uint8Array and Uint8ClampedArray are accepted. Source arrays and buffers are not modified. RGB in fully transparent output pixels is cleared; semitransparent colors and alpha are retained without premultiplication or gamma correction.

Packing contract

One sheet, no rotation, power-of-two dimensions, not necessarily square. MaxRects placement uses a stable area/name sort and three heuristics. Candidate sizes are tried by ascending area, then closeness to square, then width. This is heuristic packing, not proof of an optimal layout; an overflow means these searches did not fit within the requested limits. It does not reproduce TexturePacker's exact placement or compressed PNG bytes.

| Option | Default | Contract | | --- | --- | --- | | file | atlas.png | PNG basename | | maxWidth, maxHeight | 2048 | Integer 1–16384; output POT axes stay within bounds | | trim | true | Crop transparent borders | | alphaThreshold | 1 | Content alpha threshold, integer 1–255 | | trimMargin | 1 | Retained source-pixel margin, clamped to original bounds | | extrude | 1 | Copies nearest edge pixels, including corners, outside the frame | | shapePadding | 0 | Empty right/bottom gap after each extruded rectangle | | borderPadding | 0 | Empty outer sheet margin | | maxPixels | 16777216 | Limits total decoded source area and output area |

Margin, extrusion and padding are integers 0–1024. maxPixels is an integer 1–67108864. Batches contain 1–4096 sources. PNG input has a 32 MiB per-file limit; dimensions are checked before decoding a batch. Static PNG input is normalized to RGBA8; APNG is rejected. The input buffers, decoder intermediates and output may coexist, so maxPixels is not a process-wide memory quota.

Trimming tests alpha >= alphaThreshold, retains trimMargin around that bounding box, then stores source offsets and original dimensions. Pixels below the threshold inside the retained rectangle are preserved. An empty cropped source becomes a clear 1×1 frame at source offset 0, retaining original logical dimensions. Set trim=false when retaining the original canvas is required.

{
	"file": "r_basis_icon.png",
	"frames": {
		"r_icon_bars": {
			"x": 1, "y": 1, "w": 56, "h": 43,
			"offX": 6, "offY": 11, "sourceW": 64, "sourceH": 64
		}
	}
}

Reported rectangles exclude extrusion and padding. Uncropped frames omit offset and original-size fields. Sheet metadata does not include TexturePacker ownership, smartupdate, pivots, rotation or multipack links.

Errors and integration boundary

AtlasError.code is invalid-input, invalid-options, invalid-png or atlas-overflow. Decode failures retain their cause. Overflow never produces a partial result or automatically enables rotation/multipack.

Resource keys and logical sprite sizes, rather than packed coordinates, connect the output to skins. Keep source files as project-owned authoring assets. Preserve manifest object-form subkeys, groups and resource-default nine-slice metadata when replacing a sheet; validate grids against original dimensions. The library does not edit these records, KUI XML, style.json or game code. A caller must commit PNG/JSON and any changed resource metadata consistently and refresh its caches.

Not included: source-folder scanning, .tps parsing, GUI, filesystem transactions, sprite deduplication, multiple pages, rotation, JPEG/WebP output, polygon meshes, automatic scaling or CLI integration.

Development and validation

pnpm --dir packages/atlas install
pnpm --dir packages/atlas build
pnpm --dir packages/atlas test

Unit tests use synthetic images and do not require the local game checkout. Initial local validation against the updated KUI sample on 2026-10-07 packed all 29 basis and 32 basis_icon sources to 1024×1024 and 256×512 respectively. All 61 frame field shapes and crop geometries match the existing export. Retained RGBA pixels and edge/corner extrusion match the sources, and reversed source order produces identical JSON and PNG bytes. CLI 3.3.0 development/release builds accept the new resources without authored skin, manifest or stylesheet changes. That validation does not promise identical layout to TexturePacker or replace future Editor/Reskin integration and rendered-game acceptance.

To repeat local reference verification, provide the sample project root and a new output directory outside that project:

pnpm --dir packages/atlas verify:reference /path/to/kurot-project-kui /tmp/atlas-new

See reference results and checks, CLI integration and optimization proposals, and architecture and API context.