ascii README

The project's README from github.com/bas3line/ascii. As one markdown file: README.md.

ascii.rest

A lit donut turning, drawn in ascii

Thanks to the sponsors who make running ascii.rest possible

Command Code        Cloudflare


Animated ascii art for web pages.
216 pieces for React, Next.js, Astro or plain HTML.

ascii.rest · install · pieces · contributing

by @bas3line CI npm MIT TypeScript


Written in TypeScript by @bas3line. 216 pieces, from full-colour scenes to loaders, charts, language logos, Linux distros, spinning shapes and physics. The donut above turns on a page with one tag: <ascii-art piece="donut"></ascii-art>. See them all at ascii.rest.

night coast aurora fjord earthrise kyoto dusk torus knot taj dawn

Why

I've always been a fan of Markdown files and terminal-style websites: plain text, one monospace face, nothing that moves without a reason. The kind of quiet web that planetscale.com does well. So I made this, a way to put a little motion on pages like that without giving up the style. If you like minimalism, this library is for you.

Install

npm install ascii.rest

Or skip installing: the HTML tag loads everything from ascii.rest.

React and Next.js

import { Ascii } from "ascii.rest/react";
import { donut } from "ascii.rest/pieces";

<Ascii piece={donut} />
<Ascii piece="night-coast" />                          // fetched by name when it mounts
<Ascii piece={donut} options={{ fps: 12 }} className="art" />
<Ascii piece="rust" mono />                            // a logo in one ink

Ascii is a client component ("use client"), so it goes straight into the Next.js app router. Text pieces draw into a <pre> in its colour and font size; the coloured ones, scenes, logos, companies and distros, draw onto a <canvas> as wide as its container, or into a <pre> in one ink with mono.

Astro

---
import Ascii from "ascii.rest/astro";
---

<Ascii piece="donut" />
<Ascii piece="big-text" options={{ text: "hello" }} class="banner" />

The first frame is rendered on the server, so the page is whole before any script runs; the piece starts playing once the page loads.

HTML, no build step

<script type="module" src="https://ascii.rest/ascii.js"></script>

<ascii-art piece="donut"></ascii-art>

Style it like text: ascii-art { font-size: 10px; color: teal; }. The logos, companies and distros come in their own colours; add mono, <ascii-art piece="rust" mono>, to draw one in the text's colour instead. In a bundled app, import "ascii.rest/element" defines the same tag.

In a GitHub README

A README runs no script, so every logo, company and distro also comes as an animated SVG, one loop of its glint or scan, at https://ascii.rest/svg/<name>.svg for light pages and <name>.dark.svg for dark ones:

<picture>
  <source media="(prefers-color-scheme: dark)" srcset="https://ascii.rest/svg/rust.dark.svg">
  <img alt="rust" src="https://ascii.rest/svg/rust.svg" width="320">
</picture>

GitHub shows the dark one in its dark theme. Each piece's page on ascii.rest has its snippet under readme.

In a terminal

npx ascii.rest rust                        # plays until you press a key
npx ascii.rest night-coast --seconds 10
npx ascii.rest list                        # every piece's name, by category

The logos, companies, distros and scenes play in their own colours, in 24-bit colour. A scene is shrunk to fit the terminal, whatever its size, and drawn in tones, two of its rows in each of the terminal's as half blocks, so the dots it is made of blend as they do on a page. --mono draws a coloured piece in the terminal's own colour, for a terminal without 24-bit colour, and --light takes the colours meant for a light background. --fps and --seconds set the speed and the length. The piece plays centred; any other piece wider or taller than the terminal shows only its middle, and it says so when it stops. Piped or redirected, it prints its first frame as text.

As a splash screen

import { play } from "ascii.rest/terminal";

const { interrupted } = await play("command-code", { seconds: 2 });
if (interrupted) process.exit(130);

play(piece, options?) takes a piece module or a name and resolves when the piece stops: after seconds, on any key, or on Ctrl+C, which sets interrupted. It plays on the alternate screen with the cursor hidden, and puts the terminal back however it stops, on an error too. When the output is not a terminal it draws nothing and resolves at once, so a pipe or a CI log never gets a splash. It uses only Node's own modules.

option
seconds how long it plays; until a key is pressed by default
mono draws a coloured piece in the terminal's own colour
light for a light terminal: the light colours, and shaded pieces flipped
fps frames a second, instead of the piece's own
options the piece's option overrides: { text: "hello" }
out where it draws: process.stdout by default

It resolves with { interrupted, cropped, piece, terminal }: cropped is true when the terminal was smaller than the piece, whose size and the terminal's are in piece and terminal.

TypeScript, anywhere

import { mount } from "ascii.rest";
import { donut } from "ascii.rest/pieces";

const stop = mount(document.querySelector("pre")!, donut, { fps: 12 });

API

mount(element, piece, options?)

Plays piece in element and returns a function that stops it.

load, names, canvas, isPiece

From ascii.rest. load["night-coast"]() imports any piece by name, names lists every name, canvas is the set of pieces drawn on a canvas, and isPiece(name) narrows a string to a piece name.

<Ascii> (React)

prop type
piece piece module or name a module is bundled, a name is fetched when it mounts
options object option overrides, and fps
label string what it shows, for screen readers; the piece's name by default
mono boolean draws a coloured piece in one ink, in a <pre>
className, style passed to the <pre> or <canvas>

<Ascii> (Astro)

piece (a name), options, fps, label, mono and class.

<ascii-art>

attribute
piece a piece's name: donut, night-coast
src or the URL of any module that follows the piece contract
fps overrides the frame rate
options JSON overriding the option defaults: '{"text":"hello"}'
label what it shows, for screen readers
mono draws a coloured piece in one ink, the text's colour

Browser support

Any current browser: it needs ES modules, custom elements and IntersectionObserver, plus ResizeObserver for the coloured pieces. Importing any module on a server, for server rendering, is safe: nothing touches the DOM until a piece is mounted.

Many pieces draw with box drawing and block glyphs (─ │ ╭ █ ▄ ░). Where the system monospace face has none, as on Android, the tag and the Astro component take them from "ascii.rest mono", a 3 KB cut of JetBrains Mono (OFL) served by ascii.rest, so every row keeps its width. Only a browser that lacks the glyphs fetches it. With React, put it in your own <pre>'s font stack:

@font-face {
  font-family: "ascii.rest mono";
  src: url("https://ascii.rest/fonts/ascii-rest-mono.woff2") format("woff2");
  unicode-range: U+00B0, U+00B7, U+2022, U+2500-259F, U+25CF;
}
pre.art { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", "ascii.rest mono", monospace; }

Pieces

category pieces
scenes alpine dawn, aurora fjord, deep reef, desert night, earthrise, kyoto dusk, lantern lake, marine drive, misty forest, night coast, ocean sunset, storm plains, taj dawn, tokyo rain, varanasi ghats
ui boot log, box frames, calendar, digital clock, dividers, file tree, form controls, not found, progress bar, skeleton, spinners, terminal
data bar chart, candlesticks, cpu meters, equalizer, gauge, heartbeat, heatmap, radar, sparkline, uptime bar
type big text, dissolve, glitch, marquee, morse, scramble, split-flap, typewriter, wave text
logos c, c#, c++, clojure, css, dart, elixir, elm, erlang, go, haskell, html, java, javascript, julia, kotlin, lua, ocaml, perl, php, python, r, ruby, rust, scala, svelte, swift, typescript, zig
companies a0, agentmail, apple, autumn, cloudflare, coderabbit, collabute, command code, databuddy, greptile, helium, keiki, mintlify, orchid, planetscale, playstation, polar, supabase, supermemory, vercel
distros almalinux, alpine linux, arch linux, centos, debian, deepin, elementary os, endeavouros, fedora, gentoo, kali linux, linux mint, manjaro, nixos, omarchy, opensuse, pop!_os, red hat, rocky linux, tux, ubuntu, void linux, zorin os
shapes cube, dna helix, donut, glxgears, gyroscope, heart, icosahedron, mobius strip, spring, tesseract, torus knot, twisted ring
space black hole, earth, eclipse, galaxy, moon phases, planet, rocket, saptarishi, solar system, starfield, three-body
physics bouncing balls, chladni plate, double pendulum, falling sand, flag, fountain, harmonograph, lorenz attractor, newton's cradle, pendulum wave, plucked string, pond ripples, smoke, wave interference
nature aurora, bonsai, campfire, cherry blossom, contour map, fern, fireflies, fractal tree, landscape, lightning, rain, ruled mountains, sea swell, snowfall, sunrise, wind
creatures aquarium, butterfly, cat, fox, jellyfish, owl, snake, spider, starlings, whale
objects analog clock, candle, coffee, ferris wheel, hawa mahal, hourglass, kite, lava lamp, lighthouse, skyline, sundial, train, vinyl, windmill
generative epicycles, flow field, glider gun, hilbert curve, julia set, langton's ant, mandelbrot, maze, plasma, reaction diffusion, rule 30, sierpinski, voronoi
effects doom fire, fireworks, matrix rain, rotozoomer, sparks, synthwave, tunnel, tv static

The logos and distros are drawn from devicon (MIT) and Simple Icons (CC0); omarchy's mark there is its own, MIT licensed, from omarchy.org. The companies are drawn from Simple Icons too, and a0, agentmail, autumn, coderabbit, collabute, command code, databuddy, greptile, keiki, orchid, polar and supermemory from their own marks on a0.dev, agentmail.to, useautumn.com, coderabbit.ai, collabute.ai, commandcode.ai, databuddy.cc, greptile.com, onkeiki.com, orchid.ai, polar.sh and supermemory.ai. Each is a trademark of its owner, shown here to name the language, the distribution or the company.

Contributing

New pieces, fixes and ideas are welcome. CONTRIBUTING.md covers the piece contract, the checks and how to open a pull request, and the code of conduct applies everywhere. Found a security problem? See SECURITY.md.

Author

Made by @bas3line. If you use it, a link back is appreciated, and so is a star.

To support it: GitHub Sponsors, Buy Me a Coffee or PayPal.

License

MIT, © @bas3line

ascii (bas3line/ascii)

ascii-art
Searching Database…

910 ·GitHub
What is this?ascii is a TypeScript library of 216 animated ASCII art pieces for web pages, usable in React, Next.js, Astro, plain HTML, terminals, and GitHub READMEs.
How do I add a piece to my page?Drop in the plain HTML custom element which loads everything from ascii.rest with zero install, or install the package and use the mount() API, the React component, or the Astro component.
Do I need a bundler or build step?No. The HTML custom element works with no build step and fetches pieces by name at runtime; bundled apps can import the element or framework wrappers if preferred.
Does the animation always play right away?No. Pieces hold their first frame by default for readers who prefer reduced motion, and only animate when motion:true is set behind a control the reader explicitly chooses.
Can I run these pieces in a terminal, not just a browser?Yes, a CLI plays logos, scenes, and shapes directly in 24-bit terminal color, with --mono, --light, --fps and --seconds flags, and a play() function can show any piece as a splash screen.
What browsers does this support?Any current browser with ES modules, custom elements, and IntersectionObserver; colored pieces also need ResizeObserver, and importing on the server for SSR is safe since nothing touches the DOM until mount.
Is everything in the library freely usable?The code is MIT licensed, but the bundled company and logo marks are trademarks of their respective owners, included only to represent the language, distro, or company they belong to.
What categories of pieces are included?216 pieces span scenes, UI elements, data charts, text effects, language and distro logos, company logos, 3D shapes, space scenes, physics simulations, nature, creatures, objects, generative art, and screen effects.
Why did the author build this instead of a generic animation library?The author likes minimalist, terminal-style sites with plain monospace text (like planetscale.com) and wanted a way to add subtle motion to that aesthetic without abandoning it.
Can I embed an animated piece in a GitHub README?Yes, logos, companies, and distros are also provided as animated SVGs with separate light and dark versions, and GitHub automatically picks the dark one in dark theme.
What happens if a terminal lacks the right font glyphs?Many pieces use box-drawing and block glyphs; on systems like Android that lack them, the library automatically serves a 3KB cut of JetBrains Mono so rows keep consistent width.
Creator
bas3line
Size
3.3 MB
Stars
910
Updated
CommitOct 17
Age
10d
Commits · 90 Days