{"id":13425967,"url":"https://github.com/ines/termynal","last_synced_at":"2025-05-15T10:03:38.692Z","repository":{"id":41070789,"uuid":"93766944","full_name":"ines/termynal","owner":"ines","description":"⬛️ Lightweight and modern terminal animations using async/await","archived":false,"fork":false,"pushed_at":"2021-11-04T13:58:48.000Z","size":109,"stargazers_count":1754,"open_issues_count":17,"forks_count":116,"subscribers_count":14,"default_branch":"master","last_synced_at":"2025-04-14T16:57:27.622Z","etag":null,"topics":["animation","css","html-api","javascript","javascript-library","terminal"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ines.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-06-08T15:49:18.000Z","updated_at":"2025-04-08T21:39:39.000Z","dependencies_parsed_at":"2022-07-14T08:08:57.898Z","dependency_job_id":null,"html_url":"https://github.com/ines/termynal","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ines%2Ftermynal","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ines%2Ftermynal/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ines%2Ftermynal/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ines%2Ftermynal/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ines","download_url":"https://codeload.github.com/ines/termynal/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254319716,"owners_count":22051072,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["animation","css","html-api","javascript","javascript-library","terminal"],"created_at":"2024-07-31T00:01:23.150Z","updated_at":"2025-05-15T10:03:38.024Z","avatar_url":"https://github.com/ines.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# termynal.js: A lightweight and modern animated terminal window\n\nTyping animations are nothing new and Termynal isn't particularly revolutionary. I wrote it because I needed a modern and lightweight version with minimal JavaScript and without messy, nested `setTimeout` calls. Most of the existing libraries rely on JavaScript for both the rendering, styling and animation, or even require jQuery. This is inconvenient, especially if you're using the animation as part of your software's documentation. If a user has JavaScript disabled, they will only see a blank window.\n\nTermynal uses **`async` and `await`**, which is now [supported](http://caniuse.com/#feat=async-functions) pretty much across all major browsers. Termynal lets you write all input and output in **plain HTML**, and all styling in **plain CSS**. Non-JS users will still see the **complete code**, just no animation. The width and height of the terminal window is read off the original container. This means you won't have to worry about sizing or layout reflows. Termynal also comes with a **flexible HTML API**, so you can use it without having to write a single line of JavaScript yourself.\n\n![termynal](https://user-images.githubusercontent.com/13643239/26935530-7f4e1152-4c6c-11e7-9e1a-06df36d4f9c9.gif)\n\n![termynal2](https://user-images.githubusercontent.com/13643239/26937306-4d851274-4c71-11e7-94cc-015d30a92e53.gif)\n\n\n## Examples\n\n* **Simple example:** [CodePen demo](https://codepen.io/ines/full/MoaRYM/), [`example.html`](example.html)\n* **Custom example:** [CodePen demo](https://codepen.io/ines/pen/mwegrX), [`example2.html`](example2.html)\n\n## Usage\n\nFirst, you need to create a container. Each container should have a unique class or ID that tells Termynal where to find the lines to animate. Terminal will find the lines via their `data-ty` attribute and will then animate their text content. Apart from that, it won't mess with your markup – so you're free to add additional styling and attributes.\n\n```html\n\u003cdiv id=\"termynal\" data-termynal\u003e\n    \u003cspan data-ty=\"input\"\u003epip install spaCy\u003c/span\u003e\n    \u003cspan data-ty=\"progress\"\u003e\u003c/span\u003e\n    \u003cspan data-ty\u003eSuccessfully installed spacy\u003c/span\u003e\n\u003c/div\u003e\n```\n\nWhen you include [`termynal.js`](termynal.js), you can specify the container(s) as the `data-termynal-container` attribute. To initialise Termynal for more than one container, simply add the selectors separated by a `|`, for example `#termynal1|#termynal2`.\n\n```html\n\u003cscript src=\"termynal.js\" data-termynal-container=\"#termynal\"\u003e\u003c/script\u003e\n```\n\nYou also need to include the stylesheet, [`termynal.css`](termynal.css)  in your site's `\u003chead\u003e`:\n\n```html\n\u003clink rel=\"stylesheet\" href=\"termynal.css\"\u003e\n```\n\nThat's it!\n\n### Customising Termynal\n\nOn each container, you can specify a number of settings as data attributes, and overwrite the animation delay after a line on each individual element.\n\n```html\n\u003cdiv id=\"termynal\" data-ty-startDelay=\"600\" data-ty-cursor=\"▋\"\u003e\n    \u003cspan data-ty=\"input\"\u003e pip install spacy\u003c/span\u003e\n    \u003cspan data-ty data-ty-delay=\"250\"\u003eInstalling spaCy...\u003c/span\u003e\n\u003c/div\u003e\n```\n\nIf you don't want to use the HTML API, you can also initialise Termynal in JavaScript. The constructor takes two arguments: the query selector of the container, and an optional object of settings.\n\n```javascript\nvar termynal = new Termynal('#termynal', { startDelay: 600 })\n```\n\nThe following settings are available:\n\n| Name | Type | Default | Description |\n| --- | --- | --- | --- |\n| `prefix` | string | `ty` | Prefix to use for data attributes. |\n| `startDelay` | number | `600` | Delay before animation, in ms. |\n| `typeDelay` | number | `90` | Delay between each typed character, in ms. |\n| `lineDelay` | number | `1500` | Delay between each line, in ms. |\n| `progressLength` | number | `40` | Number of characters displayed as progress bar. |\n| `progressChar` | string | `'█'` | Character to use for progress bar. |\n| `cursor` | string | `'▋'` | Character to use for cursor. |\n| `noInit` | boolean | `false` | Don't initialise the animation on load. This means you can call `Termynal.init()` yourself whenever and however you want.\n| `lineData` | Object[] | `null` | [Dynamically load](#dynamically-loading-lines) lines at instantiation.\n\n## Prompts and animations\n\nEach `\u003cspan\u003e` within the container represents a line of code. You can customise the way it's rendered and animated via its data attributes. To be rendered by Termynal, each line needs at least an empty `data-ty` attribute.\n\n### `data-ty`: display and animation style\n\n| Value | Description | Example |\n| --- | --- | --- |\n| - | Simple output, no typing. | `\u003cspan data-ty\u003eSuccessfuly installed spacy\u003c/span\u003e` |\n| `input` | Simple prompt with user input and cursor | `\u003cspan data-ty=\"input\"\u003epip install spacy\u003c/span\u003e` |\n| `progress` | Animated progress bar | `\u003cspan data-ty=\"progress\"\u003e\u003c/span\u003e` |\n\n### `data-ty-prompt`: prompt style\n\nThe prompt style specifies the characters that are displayed before each line, for example, to indicate command line inputs or interpreters (like `\u003e\u003e\u003e` for Python). By default, Termynal displays a `$` before each user input line.\n\n| Attributes |  Output |\n| --- | --- |\n| `data-ty=\"input\"` | `$ hello world` |\n| `data-ty=\"input\" data-ty-prompt=\"~\"` | `~ hello world` |\n| `data-ty=\"input\" data-ty-prompt=\"\u003e\u003e\u003e\"` | `\u003e\u003e\u003e hello world` |\n| `data-ty=\"input\" data-ty-prompt=\"\u003e\"` | `\u003e hello world` |\n| `data-ty=\"input\" data-ty-prompt=\"▲\"` | `▲ hello world` |\n| `data-ty=\"input\" data-ty-prompt=\"(.env)\"` | `(.env) hello world` |\n| `data-ty=\"input\" data-ty-prompt=\"~/user \u003e\"` | `~/user \u003e hello world` |\n\nYou can also use custom prompts for non-animated output.\n\nTo make prompts easy to customise and style, they are defined as `:before` pseudo-elements. Pseudo-elements are not selectable, so the user can copy-paste the commands and won't have to worry about stray `$` or `\u003e\u003e\u003e` characters.\n\nYou can change the style by customising the elements in [termynal.css](terminal.css), or add your own rules for specific elements only.\n\n```css\n/* Default style of prompts */\n[data-ty=\"input\"]:before,\n[data-ty-prompt]:before {\n    margin-right: 0.75em;\n    color: var(--color-text-subtle);\n}\n\n/* Make only \u003e\u003e\u003e prompt red */\n[data-ty-prompt=\"\u003e\u003e\u003e\"]:before {\n    color: red;\n}\n```\n\n### `data-ty-progressPercent`: set max percent of progress\n\n| Attributes |  Output |\n| --- | --- |\n| `data-ty=\"progress\"` | `████████████████████████████████████████ 100%` |\n| `data-ty=\"progress\" data-ty-progressPercent=\"81\"` | `█████████████████████████████████ 83%` |\n\n### `data-ty-cursor`: display a cursor\n\nEach line set to `data-ty=\"input\"` will be rendered with an animated cursor. Termynal does this by adding a `data-ty-cursor` attribute, and removing it when the line animation has completed (after the delay specified as `lineDelay`). The value of the `data-ty-cursor` sets the cursor style – by default, a small unicode block is used: `▋`. You can set a custom cursor character in the global settings, or overwrite it on a particular line:\n\n```html\n\u003cdiv id=\"#termynal\" data-termynal data-ty-cursor=\"|\"\u003e\n    \u003cspan data-ty=\"input\"\u003eAnimated with cursor |\u003c/span\u003e\n    \u003cspan data-ty=\"input\" data-ty-cursor=\"▋\"\u003eAnimated with cursor ▋\u003c/span\u003e\n\u003c/div\u003e\n```\n\nYou can also change the cursor style and animation in [`termynal.css`](termynal.css):\n\n```css\n[data-ty-cursor]:after {\n    content: attr(data-ty-cursor);\n    font-family: monospace;\n    margin-left: 0.5em;\n    -webkit-animation: blink 1s infinite;\n            animation: blink 1s infinite;\n}\n```\n\n### Dynamically loading lines\n\nLines can be dynamically loaded by passing an array of line data objects, using the [attribute suffixes](#data-ty-prompt-prompt-style), as a property of the [settings](#customising-termynal) object.\n\n```javascript\nvar termynal = new Termynal('#termynal',\n    {\n        lineData: [\n            { type: 'input', value: 'pip install spacy' },\n            { value: 'Are you sure you want to install \\'spaCy\\'?' },\n            { type: 'input',  typeDelay: 1000, prompt: '(y/n)', value: 'y' },\n            { delay: 1000, value: 'Installing spaCy...' }\n        ]\n    }\n)\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fines%2Ftermynal","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fines%2Ftermynal","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fines%2Ftermynal/lists"}