Skip to content

About

Small, dependency-free pieces of code for single-file browser games and cleaned up so anyone, or any AI helper working with a human, can drop them into their projects. MIT Licensed.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

JS-modules

Small, dependency-free pieces for single-file browser games and apps. Copy one file, get one fix.

Pick a module · Live demos · Changelog

license MIT dependencies 0 modules and tools 49 WebAssembly first

What it is and how it works

JS-modules is a set of 49 small browser libraries and tools, each solving one problem met while building LFC Foundry's apps: Apple Press, Fancy, the Banana, Pineapple Defense, Story Editor and Netflow Map (private).

  • Each module is one file with no dependencies: copy it, load it with a script tag or require, call it.
  • Heavy work runs in WebAssembly inside the same file, usually with a JavaScript fallback.
  • Every folder has a README with limits and comparisons, a demo page, tests and a changelog.

The modules are for developers; the apps built from them need no install and no special knowledge.

<script src="modules/save-kit/save-kit.js"></script>
<script>var kit = SaveKit.create({ key: 'mygame', schema: { score: 'num' } });</script>

Why it exists

Single-file offline apps cannot load code from a server, must run on cheap phones, and every kilobyte is downloaded by everyone. Most libraries assume a build step, a network and a fast device. A module is kept only if it does something the nearest open-source option does not, or does it measurably better, and its README says where the other one wins.

Where it helps

  • Offline or single-file web apps and games.
  • One specific fix without adopting a framework.
  • Low-end phones, where memory and download size are tight.
  • Data-heavy pages (maps, charts, logs) that need compact storage.
  • Higher-end hardware and larger projects: because the code is efficient, it scales up with the project as far as modern browsers allow.

Highlights

One file each Fast by default Gives memory back Tested in three browsers
Copy only what you need. No build step. WebAssembly with SIMD, plain JavaScript fallback. Big jobs can hand memory back by trim() or an idle timer. Firefox, Chromium, WebKitGTK.

Compared with the usual choice

lfc-pack 0.4.0 on 260 MB of real FHIR records, measured 2026.10.31 in cloud Chromium 153, Firefox 158 and WebKitGTK 2.52.6 (shared 4-core machine). Parquet written natively by pyarrow 26 after a DuckDB 2.0 read (zstd 3, 4 threads).

Measure (260 MB of FHIR records) Parquet lfc-pack 0.4.0
Pack time, one thread 7.44 s 2.13 to 2.69 s
Pack time, 4 helpers 7.44 s 1.08 to 1.56 s
File size 18.74 MB 8.32 MB

Since this run, 0.4.4 packs FHIR 10 to 15% faster, and 0.4.6 makes the same file 7.30 MB, 39% of Parquet's size.

text-columns reads CSV 3 to 12 times faster than Papa Parse with typed rows: 3.2x on a laptop in Firefox 160, 7 to 12x in the cloud test browsers.

MIT License. Copyright (c) 2026 LFC Foundry. Use, change and sell anything built with it. Keeping the license line is the only ask.

All at a glance

Every piece in one place, by name. The tables below give the version, the sizes (readable and gzipped) and what each piece does.

Modules & Tools (49)

Story editor packages (10)

AI knowledge base (1)

Pick a piece

Grouped by what a piece does. The live page, with demos and a quick finder, is https://lfcfoundry.github.io/JS-modules/.

How to read the tables. Version is the label of the newest release; its first number is the API number, so the same first number means a drop-in copy. Size is the file as it sits in the repository (readable, with comments); Gzipped is that file compressed. A piece marked (tool) is for building and testing: it is not shipped inside a game or story. Story Editor packages are measured on their built global file. Every table has the same columns. Minified sizes and lean builds are in each piece's own README. Written by python3 tools/versions/versions.py sizes. Every piece has a size.

Modules & Tools (49)

Device and browser adaptation

Make a game behave on slow phones, privacy-focused browsers and power-saving screens.

Name Version Size (KB) Gzipped (KB) What it does Demo
env-probes 1.1.0 16.2 5.4 Detects privacy modes that blur timers, scramble canvas reads or block storage. Demo
field-report 1.1.1 22.7 8.0 Hidden buttons that save a speed report and an error log from a real device. No network. Demo
frame-kit 1.2.1 38.9 12.1 Frame pacing for canvas games: smooth frame time, effect governor, job pump, frame meter. Demo
fx-governor 1.1.1 6.2 2.5 Steps visual effects down when the device cannot keep up; never back up mid-play. Demo
image-decode 1.2.2 22.0 7.7 Loads pictures with no freeze at first draw, the right way per browser, plus WebP/AVIF checks. Demo
slow-note 1.0.0 9.7 3.7 A short private note of errors, slow taps and long frames, copyable as text. Demo

Saving and data safety

Keep a player's progress safe and let them move it between devices.

Name Version Size (KB) Gzipped (KB) What it does Demo
save-kit 1.6.0 45.4 13.5 Safe saves in localStorage and IndexedDB: backup slot, checksums, copy-paste save codes. Demo
tab-guard 1.1.1 9.6 3.4 Keeps one tab in charge so two tabs never overwrite each other's saves. Demo

Games - Looks and effects

Curtains, flying elements, lettering and 3D-looking sprites.

Name Version Size (KB) Gzipped (KB) What it does Demo
cartoon-3d-kit 1.3.0 50.3 20.6 A written style guide and demo for the soft, glossy cartoon 3D look in CSS and SVG. Demo
fly-to-mini 1.2.0 18.1 6.3 A big element scrolls away and a copy flies to its sticky mini version. Demo
gpu-blur 1.3.2 60.3 18.7 Blurs a picture on the card (WebGL 2), in WebAssembly or plain JavaScript; same picture every way. Demo
sprite-baker 1.7.2 54.6 18.0 Tiny software 3D rasterizer that bakes shaded sprites to canvases. Demo
stage-curtains 1.4.2 47.5 17.0 Velvet stage curtains that slide shut over a page and fly open. Demo
sticker-text 1.1.0 5.0 2.1 Die-cut sticker lettering in plain CSS, no images. Demo

Games - Controls

Let players hold a button, or play with a gamepad.

Name Version Size (KB) Gzipped (KB) What it does Demo
back-close 1.2.0 9.1 3.1 Makes the phone's back swipe close the top panel instead of leaving the page. Demo
hold-press 1.1.0 13.0 4.1 Hold-to-repeat buttons that survive Android Chrome's pointercancel. Demo
pad-nav 1.1.0 29.2 9.6 Gamepad to focus: move through buttons, menus and sliders with a controller. Demo
wake-keeper 1.1.0 8.2 2.7 Keeps the screen awake only while a game wants it. Demo

Games - Assist

Show a new player around, and keep small children away from the buttons that matter.

Name Version Size (KB) Gzipped (KB) What it does Demo
grown-ups-door 1.0.1 14.8 5.1 A hold-and-drag task a young child will not finish, in front of grown-up buttons. Demo
spotlight-tour 1.1.1 12.8 4.9 A first-visit tour: dimmed page, bright window, Skip and Back, remembers who saw it. Demo

Games - Math

The numbers behind idle and clicker games.

Name Version Size (KB) Gzipped (KB) What it does Demo
idle-core 1.2.0 22.8 7.7 Tested maths for idle and clicker games: costs, buy-max, away income, number format. Demo

Games - Testing

Test a game by playing it at random, shrinking any failure to a short replay, counting what it draws and driving real browsers.

Name Version Size (KB) Gzipped (KB) What it does Demo
canvas-probe (tool) 1.1.1 28.8 8.8 Test-build counter for canvas 2D games: calls per frame, leaks, repeated style writes. —
firefox-stand-in (tool) 1.1.0 14.5 5.0 Runs a Playwright-for-Python test in stock Firefox without rewriting it. —
fuzz-kit (tool) 1.3.4 81.5 26.3 Seeded random-input fuzzer for games, with failure shrinking and browser runners. —
speed-guard (tool) 1.0.0 7.4 2.9 Flags speed-history steps over 5% slower than the last release; lists the browser checks to re-run. —
speed-lab (tool) 1.1.1 20.5 7.4 A one-button speed test on the device: switches parts off and says what costs time. Demo
storage-probe (tool) 1.1.0 19.4 7.2 A one-button page that says whether copies of a page share their saved data. Demo
test-isolation (tool) 1.1.0 6.5 2.4 Prefixes every localStorage key on a test page so tests never touch the real save. —
test-runner (tool) 1.4.0 49.0 16.5 Warm browsers, fair timing, skipped rebuilds, wasm-vs-JS twin test, picture gate and bisect. —
webkit-driver (tool) 1.4.1 23.6 8.6 Drives WebKitGTK or GNOME Web from Node with Playwright-style calls, no dependencies. —

App - Efficiency

Keep a one-file app small and light: smaller data in memory, smaller pages on the wire.

Name Version Size (KB) Gzipped (KB) What it does Demo
elias-fano 1.8.1 74.2 24.5 Packs sorted number lists small and searches them without unpacking. Demo
lfc-pack 0.4.15 353.8 187.8 Packs NDJSON into small column files and reads the rows back, exactly if you ask. Demo
memory-compression 2.10.1 401.6 116.8 Keeps big arrays, bytes and lists of objects packed in memory and brings them back exactly. Demo
single-file-tools (tool) 1.3.0 28.7 10.8 Font subsetting, safe inline-SVG tightening and a Zopfli self-extracting packer. —
text-columns 0.6.5 62.9 21.4 Reads CSV and TSV into number and text columns, 3 to 12 times faster than Papa Parse. Demo

Graphs and simulation

Walk graphs (shortest paths, centrality, communities) and simulate random walkers over them.

Name Version Size (KB) Gzipped (KB) What it does Demo
graph-walk 0.11.2 98.1 30.9 Graph walks in typed arrays: distances, loops, shortest paths, centrality, communities. —
walker-sim 2.4.1 73.6 24.1 Simulates random walkers on a network: seeded runs, 95% ranges, exact odds. Demo

Visualization

Draw maps, flow charts and animated pictures from data.

Name Version Size (KB) Gzipped (KB) What it does Demo
clip-writer 1.3.0 30.9 9.7 Turns pictures into an MP4 or WebM video file. Demo
gif-writer 1.6.2 44.2 17.2 Writes animated GIFs from canvas frames with one shared palette. Demo
netflow-engine 2.2.3 205.4 64.3 Netflow Map's engine as an adaptable module: nine views, network layouts, add-on hand-over. Demo
netflow-layers 1.7.2 55.9 19.6 Lays out a graph in rows, with tags for long links and tall maps cut into columns. Demo
netflow-sankey 2.4.1 63.2 22.6 Lays out a Sankey flow chart from a list of links, with an SVG drawer. Demo
netflow-scene 1.3.2 114.7 36.8 Turns a laid-out map into plain drawing lists for Canvas, WebGL or SVG. Demo

Size and packaging

Open zip and Excel files safely, and pack a finished page into a smaller file that unpacks itself.

Name Version Size (KB) Gzipped (KB) What it does Demo
lzma-decode 1.3.1 22.3 8.7 LZMA decoder: WebAssembly first, small readable JavaScript fallback; tested against Python's lzma. Demo
lzma-pack (tool) 2.0.2 29.0 11.0 Packs one HTML file into a smaller self-unpacking file with LZMA (Python 3). —
pcodec-js 1.6.3 105.8 60.5 Pcodec number compression for web pages: unpack, and optionally pack, big lists of numbers. Demo
ppmd-decode 1.3.1 45.5 16.3 A PPMd (7-Zip PPMd7) decoder: WebAssembly first, JavaScript fallback; smaller than LZMA. Demo
ppmd-pack (tool) 2.0.2 48.0 14.7 Packs one HTML file into a self-unpacking file with PPMd (pure Python). —
zip-open 1.14.3 114.3 40.1 Opens .zip and .xlsx files safely, with limits counted on what really unpacks. Demo

Story editor packages (10)

Packages for interactive stories. They live with the Story Editor they are generated from, under packages/.

Story data

Create, clean, import and save stories in one shared file format.

Name Version Size (KB) Gzipped (KB) What it does Demo
story-diff 1.0.0 6.1 2.0 Says in plain words what one edit did to a story. —
story-format 2.0.0 49.4 14.0 Create, clean, search, import and export interactive stories as JSON, with a schema. —
story-outline 1.0.0 25.7 7.9 Turns an indented outline into pages and choices, or a whole branching story. —
twine-import 1.0.1 93.8 25.1 Reads Twine stories (Twine 2 HTML, Twee 3, Twine 1) and turns their code into rules. —

Story validation

Find dead ends and endings nobody can reach before a reader does.

Name Version Size (KB) Gzipped (KB) What it does Demo
story-check 1.0.0 73.9 20.5 Exact checker for branching stories: dead ends and endings no player can reach. —

Story flow

See a story's shape: maps of its pages and simulated readers.

Name Version Size (KB) Gzipped (KB) What it does Demo
story-map 1.0.0 61.0 18.1 Layered, arc and matrix drawings of a story graph, plus simulated players. —

Story build and distribute

Turn a story into a game, or play it from code or a terminal.

Name Version Size (KB) Gzipped (KB) What it does Demo
story-player 1.0.1 73.3 24.2 Builds one offline HTML game from a story, or plays a story from code or a terminal. —

Story packaging

Pack a finished story page into a smaller page.

Name Version Size (KB) Gzipped (KB) What it does Demo
zip-page 1.0.0 6.5 2.7 Shrinks a finished HTML page into a self-unzipping page. —

Story testing

Run tests on stock Firefox, generate random stories and keep two implementations in step.

Name Version Size (KB) Gzipped (KB) What it does Demo
contract-kit 1.1.0 16.3 5.7 Keeps two implementations of one rule set in step: random inputs, side-by-side comparison. —
qa-kit 0.2.1 93.4 30.5 Tiered test runner and Playwright-style API for stock Firefox, plus a random-story generator. —

AI knowledge base (1)

Working with an AI helper

A written process for a person and an AI assistant building software together.

Name Version Size (KB) Gzipped (KB) What it does Demo
ai-collab-kit — 13.9 6.3 A written process and templates for a person and an AI assistant building software together. —

How to use a module

Every module is no dependencies and, apart from frame-kit (four small files, each usable alone), one file, and works two ways:

<script src="modules/save-kit/save-kit.js"></script>
<script>var kit = SaveKit.create({ key: 'mygame', schema: { score: 'num' } });</script>
const SaveKit = require('./modules/save-kit/save-kit.js');   // Node / bundlers

Copy just the file you need. Each folder has a README (what it does, how it differs from what already exists, limits) and a demo.html you can open straight from disk.

Why these and not others

Only parts that are not already well covered by open source were kept. Large general libraries (animation, audio, physics, fuzzers, test runners) are not repeated here. What is here are the small, specific fixes learned by shipping one real game to phones and desktops: a curtain half stuck out of place on Android, a hold that dies on pointercancel, a save that was overwritten by a NaN, Firefox privacy mode rounding the clock to about 16.67 ms. Each module README names the closest existing project and says how this one differs.

Not included, on purpose

The games' own art, characters, text, sounds and secret content stay in Apple Press and Fancy, the Banana and are not licensed here. cartoon-3d-kit teaches the technique with a generic blob character instead.

Tests

npm i playwright-core
CHROMIUM=/path/to/chrome node tests/run.js      # CHROMIUM is required: the browser tests refuse to run without it and print the real Chromium version (see Test browsers below)
npm run test:kits                               # the per-module tests of every module and tool that has a test folder, run side by side; see the top of tests/kits.js for the steps and flags such as --quick and --changed (needs python3 and Playwright for Python for the browser parts)

Checks: maths and save logic in Node, the browser pieces (curtains, hold-press, fly-to-mini, probes, governor, sticker text) in Chromium. For humans and AI helpers: read AGENTS.md, llms.txt and modules.json. What changed in each version: CHANGELOG.md (and a CHANGELOG.md in every module and tool folder).

Test browsers

Browser checks run only in the browsers kept on the browsers branch of the private knowledge-base repository: Firefox 158 (the stress test), ungoogled Chromium 155 and WebKitGTK 2.52.6, on Linux. The branch can change (a version updated, a browser added or removed), so read its README before each run and use what it says then. Every result in this repository's docs names the exact browser and version, for example "Firefox 158" or "Chromium 155 (ungoogled)".

Every module and tool says which browsers its release was tested in. The newest release's list is the Tested in line near the top of its README; each release's list is the Tested in line in its full changelog entry, which the maintainers keep privately (the repo's CHANGELOG.md files are the short end-user versions). A line names each browser with its version, says "not recorded" where the old records do not show it, and says what was not run. Older builds (Chromium 141 and 153, Firefox 155 and 157) and GNOME Web 46.5 were stand-ins before this rule; entries that were tested on them still say so, and are not re-measured unless a change needs it. versions.py set ... --tested "..." writes the line; see tools/versions/README.md.

Rules for anyone running the tests:

  • Run one browser at a time. Two at once make timing checks flaky.
  • Point the test at the browser you installed: CHROMIUM=/path/to/chrome for the Chromium checks, FIREFOX_PATH (and GECKODRIVER_PATH for firefox-stand-in) for Firefox. A bare run that falls back to some other build gives unfair timing numbers, so say which one ran.
  • WebKitGTK can only be driven through WebDriver (Playwright and Puppeteer cannot); the recipe is in the branch README. GNOME Web is no longer a test browser; older results that name it are kept as they were measured.
  • Not covered yet: Safari itself, and real phones (an Android phone and an iPhone). A passing desktop run is not a phone result.

More from LFC Foundry

  • Apple Press: a clicker game for kids (play)
  • Story Editor: an offline editor for branching stories, plus MIT packages cut from it: story format and checker, game builder and player, story map layout, a self-unzipping page packer, and a Firefox test kit (try it)
  • Fancy Banana: a one-tap flying-banana arcade game (play)
  • Pineapple Defense: a flick-to-throw pineapples-at-penguins game that uses a few of these pieces (play)
  • JS-modules: this repository (demos)

About

Small, dependency-free pieces of code for single-file browser games and cleaned up so anyone, or any AI helper working with a human, can drop them into their projects. MIT Licensed.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages