Alto
How To Use Alto
Install the npm package, import the CSS, then let Alto replace failed images or render loaded pixels as sized, colored ASCII.
Install
npm install alto-ascii
LLM Skill
Give this file to an agent so it has the package-specific integration rules, resolution guidance, and browser constraints up front.
---
name: alto-ascii
description: Alto ASCII image fallback guidance for accessible alt-text-to-ASCII rendering. Use when integrating, debugging, documenting, or building with the alto-ascii package, including broken-image replacement, local image conversion, React or Next usage, CSS imports, resolution controls, and accessible fallback behavior.
metadata:
priority: 4
docs:
- "https://mootbing.github.io/Alto/"
- "https://github.com/Mootbing/Alto"
pathPatterns:
- "package.json"
- "src/**"
- "examples/**"
bashPatterns:
- "\\bnpm\\s+(?:install|add)\\s+alto-ascii\\b"
- "\\bpnpm\\s+add\\s+alto-ascii\\b"
- "\\byarn\\s+add\\s+alto-ascii\\b"
---
# Alto ASCII
Use Alto to turn broken images, planned image fallbacks, or local image previews into accessible ASCII renderings driven by meaningful alt text.
## Install
```bash
npm install alto-ascii
```
Import the stylesheet once in the application entrypoint.
```js
import "alto-ascii/style.css";
```
## Automatic broken-image fallbacks
Use `installAlto()` when ordinary image elements should be observed and replaced only after they fail to load.
```js
import "alto-ascii/style.css";
import { installAlto } from "alto-ascii";
const stopAlto = installAlto({
resolution: "1x"
});
```
- Keep the original `alt` text specific and human-readable.
- Prefer explicit `data-alto-columns` and `data-alto-rows` when a fallback must match a fixed slot.
- Call the returned cleanup function before tearing down a routed page or temporary preview.
## Planned local conversion
Use `imageToAscii()` when an image loads successfully and the UI intentionally wants an ASCII version.
```js
import { createAltoFallback, fitAltoFallback, imageToAscii } from "alto-ascii";
const image = document.querySelector("img");
const frame = await imageToAscii(image, {
colorMode: "color",
columns: 120,
rows: 64,
maxColumns: 520,
maxRows: 340,
output: "frame"
});
const fallback = createAltoFallback(image.alt, {
ascii: frame.ascii,
aspectRatio: image.naturalWidth / Math.max(1, image.naturalHeight)
});
image.replaceWith(fallback);
fitAltoFallback(fallback);
```
## Resolution guidance
- Use `resolution` for source-relative scales such as `"4x"`, `"2x"`, `"1x"`, `"0.5x"`, and `"0.25x"`.
- Use explicit `columns` and `rows` for container-aware demos or responsive slots.
- Clamp high-resolution conversions with `maxColumns` and `maxRows`.
- Recompute ASCII after layout changes when the fallback must adapt to the rendered element size.
## Color guidance
- `imageToAscii()` returns plain text with no per-cell color metadata by default.
- Use `output: "frame"` plus `colorMode: "color"` to receive per-cell sampled RGB colors.
- Use `output: "frame"` plus `colorMode: "black-and-white"` when metadata is useful but binary black/white colors are preferred.
- Render `frame.ascii` for text-only output, or render `frame.cells` as character spans with `--alto-cell-color` for colored demos.
## Accessibility and browser constraints
- Preserve useful alt text; Alto uses it as the accessible label for the fallback.
- Treat decorative images as decorative and avoid inventing meaningful labels for them.
- Import the CSS so `.alto-fallback` receives the package styling.
- Convert local assets or CORS-safe remote images; browser canvas pixel reads fail for tainted cross-origin images.
Automatic Broken Image Fallbacks
<link rel="stylesheet" href="/node_modules/alto-ascii/src/alto.css" />
<img
src="/missing-photo.jpg"
alt="A yellow kayak crossing a blue alpine lake at sunrise"
data-alto-resolution="high"
/>
<script type="module">
import { installAlto } from "alto-ascii";
installAlto();
</script>
Keep alt text readable and meaningful. Alto uses that same text as the accessible label for the generated fallback.
Use Exact Dimensions
<img
src="/missing-photo.jpg"
alt="Glass building at night"
data-alto-columns="80"
data-alto-rows="48"
/>
Exact columns and rows override density presets.
Use Source Scale
const ascii = await imageToAscii(imageElement, {
resolution: "0.5x"
});
For image conversion, use 4x, 3x, 2x, 1x, 0.75x, 0.5x, or 0.25x.
Color Frame Output
const frame = await imageToAscii(imageElement, {
colorMode: "color",
output: "frame",
resolution: "0.5x"
});
frame.ascii;
frame.cells;
Use frame.ascii for plain text, or render frame.cells as spans with --alto-cell-color for sampled per-character colors.
Convert An Image To ASCII
import { createAltoFallback, fitAltoFallback, imageToAscii } from "alto-ascii";
import "alto-ascii/style.css";
const image = document.querySelector("img");
const frame = await imageToAscii(image, {
colorMode: "color",
maxColumns: 4800,
maxRows: 3600,
output: "frame",
resolution: "1x"
});
const fallback = createAltoFallback(image.alt, {
ascii: frame.ascii,
aspectRatio: image.naturalWidth / image.naturalHeight
});
document.body.append(fallback);
fitAltoFallback(fallback);
Usage
import { AltoImage } from "alto-ascii/react";
import "alto-ascii/style.css";
export function Example() {
return (
<AltoImage
src="/missing-photo.jpg"
alt="Portrait of Jules in a green jacket"
fallbackResolution="high"
/>
);
}
Use the alto-ascii/next export when you want Alto fallback behavior on top of next/image. The component is marked as a Client Component internally because it listens for image errors.
// app/layout.tsx
import "alto-ascii/style.css";
import type { ReactNode } from "react";
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
// app/components/hero-image.tsx
import { AltoNextImage } from "alto-ascii/next";
export function HeroImage() {
return (
<AltoNextImage
src="/apollo-aldrin.jpg"
alt="Buzz Aldrin standing on the lunar surface during Apollo 11"
width={1200}
height={900}
fallbackResolution="high"
/>
);
}
Import Alto's Tailwind layer stylesheet when your app is already organized around Tailwind layers.
@import "tailwindcss";
@import "alto-ascii/tailwind.css";
Use Tailwind classes for sizing and arbitrary CSS variables for Alto tokens.
<AltoImage
src="/missing-photo.jpg"
alt="Concert poster with bold diagonal lettering"
className="h-64 w-full rounded-none [--alto-padding:0] [--alto-bg:#ffffff] [--alto-fg:#111827] [--alto-muted:#d1d5db]"
fallbackResolution="high"
/>
Accessibility Notes
- Do not put ASCII art inside the
altattribute. Keep the alt text human-readable. - Use empty
alt=""only for decorative images. - The ASCII output is visual decoration. The accessible label remains the original alt description.