# crisp-game-lib makes a browser mini-game a single HTML file

> crisp-game-lib is a small JavaScript library for classic arcade-like mini-games in the browser, and its pitch is that the whole game fits into one page, with a step-by-step guide, live reload while you write, a TypeScript option, and an agent skills bundle that lets a coding assistant pick up the library on its own. The collision model is unusual enough to be worth understanding before you write anything with it.

**abagames/crisp-game-lib** — Minimal JavaScript library for creating classic arcade-like mini-games running in the browser

- Repository: https://github.com/abagames/crisp-game-lib
- Stars: 650 · Forks: 74
- Language: TypeScript
- License: MIT
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/abagames-crisp-game-lib

## A game is a file you can email

crisp-game-lib is a JavaScript library for creating browser games quickly and easily, and the description calls it a minimal JavaScript library for creating classic arcade-like mini-games running in the browser.

The getting started instructions are four steps and they are the whole design in miniature. Download the getting_started index.html file. Open index.html in a text editor and write the code of your game in the `<script>` element. Open index.html in a browser and play the game. And you can publish the game by putting index.html on your web server.

There is no build step, no package manager and no asset pipeline in that flow. A game is an HTML file with a script element in it, and it runs from the file system.

That constraint is the point rather than a limitation to work around. A mini-game you can send to someone, host on a static host or drop into an itch.io page is a different kind of artefact from a project with a build directory, and the library is designed so that the small case stays small.

The screenshots at the top of the README make the other half of the pitch concrete. They are animated gifs of games like pakupaku, timbertest, boxsnake, up1way, dinos, jugglingchain, pillars3d and thunder, and each one is a link that launches and plays that game instantly in your browser.

The project is TypeScript as its primary language, MIT licensed, with the package published as crisp-game-lib at version 1.5.0 and the author recorded as abagames. The last push was on 2026-06-20 and there are no GitHub releases, so the npm version is the number to track.

## Two workflows, one library

There are two ways to work with the library, and they suit different people.

The first is the script-in-a-page workflow above, which needs nothing but a text editor and a browser.

The second is the development workflow, and it is the one to use if you are writing a game properly or working with an agent. Clone or download the repository, run `npm install`, copy the `docs/_template` directory and rename it to `docs/[your own game name]`, open the `docs/[your own game name]/main.js` in the editor, with VSCode recommended, and write the game code. Then run `npm run watch_games` and open `http://localhost:4000?[your own game name]`, where the page is live-reloaded when the code is rewritten.

The live reload is the part that changes how fast you work. The package file shows what is behind it, and the script is `light-server -s docs -w "docs/**/* # # reload"`, so a static server watches the docs directory and triggers a reload on change. There is a second watch script for the library itself, `watch_lib`, which runs rollup in watch mode with the bundle config as CommonJS.

The bundler route is the third option, and it is for when you want to use a tool like Vite. Run `npm install crisp-game-lib` at your project directory, copy the `docs/_template_bundler/index.html` and `docs/_template_bundler/main.js` files to your project directory, write the game code in main.js and build with the bundler.

And there is a TypeScript option on top of that. If you want to describe the game using TypeScript, rename main.js to main.ts. The package ships type definitions, with the typings field pointing at `docs/bundle.d.ts`, and the reference documentation is generated by typedoc from the source into `docs/ref_document/`.

So the same library serves a beginner with a text editor and a professional with a bundler, a type checker and hot reload.

## Collision detection is based on drawing history

The tips section contains a set of behaviours that are unusual enough that a reader should know about them before writing a game, and the collision model is the most important.

By drawing with `color("transparent")`, you can get the result of collision detection without drawing any shape on the screen. So a collision test can be performed by drawing an invisible shape rather than by asking about an object.

And the reason that works is the second tip. The collision detection is based on the drawing history of the shape. Therefore, even if a drawn shape is overwritten with a background-colored shape, the collision detection in that area will not disappear.

That is a genuinely unusual design, and it has consequences in both directions. The upside is that the collision surface is exactly what was drawn, which means there is no separate collision shape to maintain, and a shape that is invisible still collides. The downside is that a shape you have painted over still collides, because the drawing history is not the same as the visible result.

For most arcade games this is a feature. A player sprite, a bullet and a wall are all shapes, and if the shape you drew is the shape that collides, there is no chance of a mismatch between the artwork and the hitbox. The trade only bites when you deliberately paint over something and expect it to stop colliding, and the tip is telling you that it does not.

The other tips are smaller but the same kind of detail. The base value for the random seed for sound generation is generated from the `title` and `description` strings, so if you want to use `seed` in `options` to adjust the generated sound, it is better to do so after the title and description are fixed. And for performance, mainly on mobile devices, you should use the `simple` or `dark` theme, and not specify a theme that uses pixi.js, naming `pixel`, `shape`, `shapeDark` and `crt`, because WebGL post-effects may worsen performance.

## The library is generated from TypeScript and tested with vitest

The package file describes the build pipeline, and it is worth reading because it explains what you actually install.

The `main` field points at `docs/bundle.js` and the typings at `docs/bundle.d.ts`, so the published artifact is a bundled script and a declaration file rather than a set of modules. That is consistent with the single file deployment model, and it means the library works with a plain script tag as well as with a bundler.

The build is rollup, with a rollup.config.js at the root and a separate tsconfig-rollup.json for the bundle build alongside the main tsconfig.json. The rollup plugins are the commonjs, replace and typescript ones, and the replace plugin is what lets the source substitute build-time constants into the bundle.

The test setup is vitest, with the test script running `vitest run` and a watch variant. The devDependencies include sinonjs fake-timers, which is the tool for testing time-based game logic without waiting for real time, and happy-dom, which gives the tests a DOM to run against. That is the standard combination for a browser library that has a game loop in it.

The other tooling entries are for the documentation and the dev server. typedoc generates the reference, light-server is the live reload server, and there is a generate_reference script that runs typedoc against src/main.ts and writes to the docs reference directory.

The repository structure is conventional for this kind of library. There is a src/ directory for the TypeScript source, a docs/ directory holding the reference output and, importantly, the dozens of sample game directories that the README says you can copy and tweak immediately, a test/ directory, plus AGENTS.md and CLAUDE.md at the root.

## The AI skills bundle is the newest idea here

The README points at a bundle of AI Skills for crisp-game-lib and marks it as recommended for coding agents, with a note that compatible agents can automatically discover and apply skills placed under `.agents/skills/`.

That is a significant addition for a library whose whole aesthetic is smallness. The mechanism is the skills convention, where a directory under `.agents/skills/` is picked up automatically, so an agent working in the repository finds the guidance for this particular library rather than guessing from the API surface.

The distinction with the other documentation is explicit. The skills bundle is recommended for coding agents, while the Crisp Game Lib Guide is described as a general-purpose guide for non-skill workflows, for example chat interfaces or manual reference.

So there are two ways to get the library's knowledge into a model. The skills route is for an agent that can load them. The guide markdown file is for a chat window where you paste it yourself, or for a human reading it as a reference. The step-by-step guide and the API reference are the third and fourth layers, aimed at a person learning the library rather than a model.

The samples follow the same layering. Sample games and sample codes are collected in dedicated bundles, crisp-game-lib-12-games and crisp-game-lib-11-games, and the repository itself ships dozens of sample game directories under docs/ that you can copy and tweak immediately.

The demos are also broken out by capability rather than only by game, with separate pages for drawing, collision, input and audio. That is a good structure for a library with a small API, because the four functions a new user needs to understand are not obvious from the function names alone.

## Where this sits against a general game framework

The honest comparison is with the alternatives a browser game developer would otherwise pick, and each of them buys something at the cost of something else.

A general engine, Phaser or Three.js or a canvas library of your own, gives you a scene graph, an asset pipeline, an animation system and a physics option. You get structure, and you get a project directory with a build step and a dependency tree. The cost is that a game you write in one of those is no longer a single file, and the whole class of small, shareable, embeddable games becomes heavier to hand around.

A code-generation approach, where you write a game in a framework like Pygame or a Rust game engine and compile it to WebAssembly, gives you the language you prefer and real performance headroom. The cost is a build step, a toolchain and a binary, and the same single-file property is lost.

crisp-game-lib is deliberately the opposite trade. The constraint is the feature: a small fixed screen, simple shapes, and collision derived from drawing. What you get in exchange is a game that is one file, that runs anywhere a browser runs, and that a beginner can finish in an afternoon.

The surrounding signal suggests the design is being taken seriously rather than treated as a toy. There is a step-by-step guide on creating a game, written by the library's author as a literate diff viewer, which is an unusual format and a good one for a library where every change is small. There are third-party write-ups, including a guide to getting started with CrispGameLib written by Juno Nguyen and a piece by Terry Cavanagh, known as the developer of Super Hexagon and VVVVVV.

The version number tells you where it is. The package is at 1.5.0, so it has had several minor releases and is past the initial churn, but there are no GitHub releases, which suggests development happens through the repository and npm rather than through a tagged release process.

## Conclusion

Adopt crisp-game-lib if you want to make small arcade games that run from a single page with no build step at all, since the deployment model is one HTML file plus one script and a bundle. Skip it if you need a larger game with a scene graph, an asset pipeline and real structure, because the library's whole appeal is its constraints. Verify first that the collision behaviour suits your game, since detection is based on drawing history rather than on shapes in the scene, that you understand the theme options and their performance cost on mobile, and whether you want the version at version 1.5.0 with typed definitions or the plain script form, since the two are deliberately different workflows.

## FAQ

### How do I make a game with crisp-game-lib?

The quickest path is to download the getting_started index.html, open it in a text editor, write the game code in the `<script>` element, and open the file in a browser. For development, clone the repository, run `npm install`, copy the `docs/_template` directory to `docs/[your own game name]`, write the code in main.js, then run `npm run watch_games` and open `http://localhost:4000?[your own game name]`, which live-reloads as you edit.

### How does collision detection work in crisp-game-lib?

It is based on the drawing history of the shape, so a shape that is overwritten with a background-colored shape still collides in that area. You can also draw with `color("transparent")` to get the result of collision detection without drawing any visible shape on screen.

### Can I use crisp-game-lib with TypeScript and a bundler?

Yes. Install the package with `npm install crisp-game-lib`, copy the `docs/_template_bundler/index.html` and `docs/_template_bundler/main.js` files to your project directory, write the game code in main.js and build with your bundler such as Vite. If you want to describe the game using TypeScript, rename main.js to main.ts, and the published package ships type definitions.

## Sources

- [abagames/crisp-game-lib on GitHub](https://github.com/abagames/crisp-game-lib)
- [Issues](https://github.com/abagames/crisp-game-lib/issues)
- [License: MIT](https://github.com/abagames/crisp-game-lib/blob/master/LICENSE)
- [README](https://github.com/abagames/crisp-game-lib/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/abagames-crisp-game-lib
