Asciify Engine
Use the published
npm package. Tested against
4.32.8. Check the application's installed version and its public types before using newer options; a local checkout can contain unpublished changes.
sh
npm install asciify-engine@latest
Entries:
for interface components and backgrounds, one call each;
and
for media and text conversion;
for the website hovers and living-image motion;
for art styles, looks and export;
for raw GPU character fields. Each optional entry loads only when imported. GIF decoding loads
when a GIF API is called.
Start here: kit first
Most requests are a feeling ("make the loading state feel alive", "a calm background behind pricing", "like asciify.org") rather than an API. Work in this order:
- Is it a UI component or a background? Almost always, yes. Read applying-asciify.md (the house design: when characters earn a place, ink, the clear zone and veil, density, radii, motion, performance, accessibility, which background suits which surface), then take the call from components.md and its options from kit.md. Stop there unless the kit has no option for the look.
- Read the request. Subject (their media, a word, or nothing), placement (hero, card, control, background behind text), mood words, interaction, any reference site.
- Read the design. Open the project's tokens: ground and surface colours, text colours, the one accent, mono and display fonts, radii, light and dark themes, motion durations and easing, reduced-motion handling. Map the kit's ink tokens (, , , , ) onto them; never add a brand colour.
- Decide living or still. Follow the user's words; keep art behind text, in grids and in data views still; reduced motion always gets a still. See living or still.
- Say what you chose in one line and offer one alternative. Ask only when the media is missing or motion would be new to a site that has none.
design-matching.md maps mood words to settings for the lower-level APIs and media looks.
| The user wants | Use |
|---|
| A UI component in characters: button loading, status, toasts, tabs, pills, odometer, chart, AI thinking and streaming, transitions, sign-in, pricing, 404; event-site pieces (scrambling headers and headlines, morphing hatched heroes, dithered glows, a dotted globe, two-tone photos, assembling wordmarks, a spray cursor); an ASCII ocean of swimming creatures; interactive backgrounds visitors stir, grow and ripple | (applying-asciify.md, components.md, kit.md) |
| A background behind a hero, pricing, docs or a section, light or dark | Kit fieldBackground(el, { preset: 'hero', clear })
(asciify.org's hero) or background(el, { preset, clear })
with one of the 12 curated presets below |
| Their word or brand in characters | Kit , or with |
| Their video in characters on the page | Kit |
| Their photo, video or GIF converted, optionally answering the cursor | Advanced: / / , plus from |
| A full-bleed field with a look the kit has no option for | Advanced: from (glyph-field.md) |
| Their photo or video as finished artwork in a named look: a wallpaper, poster, cover, print or hero artwork ("newsprint", "riso", "phosphor", "engraving", "Lego") | / from with a look from looks.md |
| Art styles, saved looks, masks, effects, PNG/MP4/GIF export | Advanced: from (studio-workspace.md) |
| Several media and text layers in one artwork | Advanced: from (layered-projects.md) |
| A text banner or lettering | Advanced: / |
| Headline text visible through media art | Advanced: layered HTML (layered-hero.md) |
The kit in one paragraph
Each kit function mounts an
field over or inside your element, follows its size and border radius, inks it from your theme in light and dark, pauses off screen, honours reduced motion, falls back without WebGL2 to an inert handle that leaves your HTML working, and cleans up on
. components.md has 37 components as short snippets with the prompt a person gives, in categories Components, AI, Text, Transitions, Media, Pages and Backgrounds. In React, create the handle in an effect and return its
.
ts
import { beam } from 'asciify-engine/kit';
const b = beam(card, { palette: 'mono', mode: 'pulse' });
// On unmount: b.destroy();
, its presets,
,
,
and
are new in 4.14.0;
,
,
,
,
,
, the GPU
and
, and the
option are new in 4.19.0. Check that the installed
exports them; if not, upgrade (
upgrading.md).
Backgrounds
background(element, { preset })
draws every background on asciify.org/backgrounds as a scene of the GPU glyph field, in the site's graphite inks and following the global look. Import presets by name; a page pays only for those it imports.
turns the pointer response off for any of them. Which one suits which surface, and how to keep it calm, is in
applying-asciify.md.
ts
import { background, swell } from 'asciify-engine/kit';
const bg = background(pricing, { preset: swell, clear: pricingCopy });
The 12 curated presets, as export →
(name), all on the GPU glyph field (WebGL2, sharing the context budget):
(Swell, dots or characters),
(Drift),
(Halo),
(Caustics),
(Contour),
(Ripple),
(Mesh),
(Interference),
(Constellation),
(Cascade),
→
(Field),
(Fluid).
The retired presets (
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
,
) are still exported and marked
so old code runs; do not reach for them in new work.
kit.md maps each to its replacement.
is separate: its
,
and
presets are the asciify.org hero ground, the same ground in the brand colour, and the 404.
Templates already downloaded from asciify.org/backgrounds (
from a local
) keep working in apps that ship them, but the site no longer offers them; move those apps to
with the closest preset (kit.md maps each).
Install the agent skill
sh
npx skills add ayangabryl/asciify-engine --skill asciify-engine
This uses the Vercel Skills CLI to install the repository skill and its linked resources. The npm dependency and an installed agent skill update separately. When asked to update Asciify or when an integration needs newer options, follow
references/upgrading.md: check npm's current
, update with the project's package manager, then refresh only this skill in its installed scope. Do not treat this document's tested version as permanently latest, or upgrade unrelated skills/dependencies.
Verify before handing off
Run the checklist at the end of applying-asciify.md for kit work. For any integration, check the real page: readable subject and text in both themes, no stretching or unintended margins, working pointer and keyboard controls, mobile crop, reduced motion, autoplay failure, WebGL off, and cleanup after navigation. Observe several seconds of motion and a loop boundary. State the measured device and settings with any FPS figure; screenshots alone do not establish performance. What the engine guarantees a host page, and its default budgets, are in performance.md.
Do not import nonexistent helpers such as
or
.
Advanced: the lower-level APIs
Use these when the request is media conversion, art styles or export, or a field look the kit cannot give. They do not handle theme ink, posters, the context budget or fallbacks for you; the rules in applying-asciify.md still apply to the result.
Choose the integration
For a live project component, start with
project-integration.md: it maps each use case to one rendering pipeline, covers instance ownership, and keeps PNG/video export independent of live playback. Use
for a new composition with art styles, masks, backdrops and saved settings. It already owns hover/motion; do not add another
instance on top.
- Static image:
asciify(source, canvas, config)
returns . Call the cleanup on unmount, including for a still image.
- Video:
asciifyVideo(source, canvas, config)
returns . Call that function on unmount. Use and for full-bleed heroes; for a whole-subject preview.
- GIF:
asciifyGif(source, canvas, config)
returns a cleanup function asynchronously.
- Dense custom rendering: use and ; keep the same options when converting and rendering. Use object frames when per-cell mutation is required.
For a hero with HTML layered through the ASCII, read references/layered-hero.md and use the accompanying HTML, CSS, and JavaScript. These are ordinary Vite/bundler inputs, not another npm dependency. Supply your own media.
For crop, scroll, React lifecycle, and low-level API details, read references/media-api.md.
Start with a readable source
Use ordinary images or footage, then convert them with Asciify. Do not ask an image/video generator to pre-render ASCII. A dark subject with thin highlights tends to become an outline; changing to full color cannot recover missing midtones. Prefer recognizable subjects, broad illuminated surfaces, controlled highlights, and stable framing.
Choose color intentionally:
- : preserve source colors; do not grayscale source pixels first.
- : gray characters.
- : a single brand color via .
- : green treatment.
Start around
,
or
, and
. These are a starting budget, not an FPS guarantee. Increase detail only after checking the actual viewport and target hardware. Use
for flat sources when helpful; compare it against
on already graded video because frame-by-frame normalization may change the look.
js
import { asciifyVideo } from 'asciify-engine';
const stop = await asciifyVideo('/hero.mp4', canvas, {
fitTo: hero,
objectFit: 'cover',
objectPosition: 'center',
fontSize: 7,
fps: 24,
maxRenderDimension: 960,
options: {
charset: ' .:-=+*#%@',
colorMode: 'fullcolor',
normalize: false,
animationStyle: 'none',
hoverStrength: 0,
},
});
// On unmount: stop();
Custom letters
is the density ramp.
repeats a string and is a different feature. To incorporate a brand's letters while retaining shading symbols, build a ramp such as:
js
const letters = [...new Set('ASCIIFY'.toUpperCase().replace(/[^A-Z]/g, ''))].join('');
const charset = ` .:-=+${letters}#%@`;
Preview it: letter glyph densities differ, so arbitrary words are not automatically an evenly ordered ramp. When the user wants the artwork drawn in their name, the kit's
or
background does it; on raw
, put the word after a quiet ramp (
), use one ink with
, and let brightness carry the image (see
design-matching.md). Keep the leading space and the light/dense symbols. Use the curated
CHARACTER_SETS.standard.chars
,
,
, or
from
when appropriate.
Engine effects versus studio effects
The core
IDs are
,
,
,
,
,
,
,
, and
. Those remain valid APIs, but they are
not identical to the current website's enhanced interactions.
The website offers
Trail, Dissolve, Contour, Emboss, Ripple rings, Ink bleed, Water, Silk, Vortex, Magnetic Pull, Scatter, Elastic, Lens wake, Smudge, Loupe, Reveal, Repel, Tilt, Heat haze, and Off through an optional studio surface module, each with
scope: 'all' | 'subject' | 'outside'
to keep it on a cut-out subject or around it (
is retired and plays Silk). Its ten photo-aware still-image motions—Relight, Specular sweep, Highlight bloom, Glints, Parallax, Slow push, Focus pull, Mist, Drift, Develop—read the image's own light and depth (retired IDs such as
load as their closest replacement), and they and the fine-dither treatments ship in the same
module. Use its typed options rather than converting display names into engine
or
values.
To reproduce those interactions, read
references/studio-effects.md. Import
from
; no separate download is needed. Keep engine
and
when using it, to avoid applying two effects. Trail is the site's default. Prefer a stationary-grid effect such as Trail or Dissolve when the user wants a wake without spatial displacement.
For built-in hover alone, use a supported
and a restrained nonzero
; validate its behavior instead of promising that it matches the website.
Text layering over media art
For interface grounds, text sits on a clear zone and a frosted veil (applying-asciify.md). For a media hero where the headline should read through the artwork, use real HTML and a single isolated hero stacking context:
- Headline at .
- Transparent ASCII canvas/stage at .
- Description, CTA, and motion controls at or above.
Keep these as sibling layers. A transformed or isolated content wrapper can trap all its descendants below the canvas. Set decorative artwork to
; attach optional hover input to the positioned hero host. Keep controls clickable, focusable, and visually unobscured. Leave canvas background transparent; an opaque canvas or stage hides the headline beneath it. Choose artwork behind all text when it reads better.
Performance and lifecycle
- Reduce processing dimensions and cell count before dropping source playback FPS. Do not default to 60 fps on a 24 fps video.
- Start video at 24–30 fps with a 720–960px processing cap. More processing pixels do not create detail absent from the source.
- When the user asks for a smooth, high-frame-rate hero, prefer the kit or over a canvas pipeline, and keep the canvas pipeline as its fallback.
- Keep stable canvas dimensions; resize on layout changes, not on every animation frame.
- Avoid remounting the renderer on pointer movement or each React render.
- Pause media offscreen and when the document is hidden. Reduced-motion users should get a still; do not merely hide a playing video with CSS.
- Guard asynchronous setup: if a component unmounts before an API resolves, immediately call its returned cleanup. Handle loading failures without removing the HTML content or CTA.
- Compress media at a resolution appropriate to ASCII sampling, remove unused audio, use fast-start MP4, and provide a small poster. Immutable caching requires a content-hashed URL; keep this skill's URL revalidatable.
- Fine dithering can add texture but can shimmer on moving footage. Compare a still and a loop, and offer a non-dithered rendering.
- YouTube page URLs and iframe players are not direct canvas video sources. Use permitted direct media files with suitable CORS; see https://asciify.org/docs/youtube.
- For deterministic composition export, use . To record an existing interactive canvas, use a browser with a supported format and clean up its tracks; for snapshots, inspect the published / types.
Hero finish
supports text-shaped charcoal cutouts (
), peripheral scanline/fringe control (
), fixed accent ink, Prism edge softness (
), and fixed-grid fluid Trail. See the
complete API, layering example, lifecycle, and fallback limits.
Studio composition and export
For a finished artwork in a ready look (wallpaper, poster, cover, print), start from
references/looks.md: 22 looks, each with the prompt, exact settings, and wallpaper/poster/loop export sizes. For optional wallpaper/backdrops, alternate renderers, palettes, masks, saved looks, text fonts, or deterministic MP4/GIF export, read
references/studio-workspace.md.
is separate from
and
; do not replace an existing hero pipeline just to add a backdrop.
GPU glyph fields
The kit is built on
from
. Use it directly only for a look the kit has no option for, and read
references/glyph-field.md and the raw-field helper at the end of
components.md. It draws glyph ramps (including words and braille) from images, video or generated motion on WebGL2 with a fluid wake. It does not replace
for the 24 render styles, dither, print styles, effects or export. Check
, provide a poster and a fallback, honour reduced motion, and call
on unmount. To build your own component with the kit's plumbing instead, use
(
kit.md).
Current catalogs
For multiple media/text layers in one live component, use 4.8+
and read
layered-projects.md. It shares one playback loop and rendering budgets across up to eight independently styled layers. Persist source keys separately from media, and use
for independent exports. Do not create one mounted Studio instance per layer or rasterize accessible interface text.
Legacy
,
,
,
and their key types are removed. Do not import them or generate old names such as Katakana, Binary, Waves or Smoke. Use the 24
for render-style selectors and
rendering. For ASCII-only character ramps use
from
or
from
; custom Unicode and user-provided frame arrays remain supported. Core
only accepts
; use explicit options instead of preset shortcuts. Despite the requested 4.1.0 version number, migrating these removed APIs is a breaking change.
Version notes
Read these when the installed version is older than the tested one, or when a user names a specific feature.
Fine dither and creative controls (4.2)
Studio adds
,
, and
render styles, directional/radial dither patterns, additional palettes, luminance mapping, RGB split, sharpening, and adjustable still-image motion strength. Read
studio-workspace.md for exact options, density budgets and preview/export consistency. These are local Canvas/WebGL effects, not AI generation or a claim of parity with every competing catalog.
From 4.5,
dither.algorithm: 'blue-noise'
uses a precomputed dispersed threshold tile, separate from white
. Studio
also accepts
,
,
,
and
to shape detail before conversion. All are neutral by default. Read
tonal detail and blue noise before adding these controls; they belong to
, not core
.
From 4.6, Studio adds
(RGB, red, green, blue) and optional edge-preserving
.
returns a detached snapshot for saving or exporting after updates. Read
channel curves and source noise for point limits, update semantics and the processing budget. Do not turn noise reduction on by default or apply it again to the already-rendered characters.
From 4.7, Studio supports up to eight ordered source warps: Twirl, Pinch, Spherize, Ripple, Zigzag, Shear, Smudge, Polar and Fragment. Build controls from
, retain array order, and read
source shaping for bounds, alpha/edge policy and cached-map performance. These shape the source; use
to bring a still image to life and
for pointer interaction. Keep them independent, with an empty warp stack by default.
From 4.9, optional Studio adds Stipple, Engraving, Crosshatch, Woodblock, Risograph and Pointillism with a shared
settings group. Read
print and illustration for exact controls, light-ink versus dark-ink polarity, still-motion integration and dense-render limits. These are genuine additional render paths; do not substitute dither presets for their IDs.
Lively images and interaction starting points (4.10)
provides six editable motion/hover pairings through
and
. Apply
and
to an existing Studio player to keep the source and art style; do not treat the pairings as additional art styles. Read
studio-effects.md for exact new IDs, loop limits and the live component example.
GPU glyph fields (4.11) and the kit (4.13)
adds
,
and
in 4.11;
,
and
in 4.12.
arrives in 4.13;
and its presets,
,
, the context budget and the global look follow it. Older installs do not have these entries; upgrade before using them.
Scenario prompts
Use scenario-prompts.md for copyable briefs covering images, heroes, characters, all styles, dither, backgrounds, video/GIF, scroll, layers, text, export, frameworks, procedural trails, reference matching, troubleshooting, upgrades, saved looks and accessibility. Adapt the prompt to the user's intent; do not add unrelated features. Use the published renderer's native Trail; do not add a separate tonal ribbon overlay.