{"id":20161185,"url":"https://github.com/kubetail-org/fancy-ansi","last_synced_at":"2025-09-08T06:35:03.624Z","repository":{"id":230387536,"uuid":"779234470","full_name":"kubetail-org/fancy-ansi","owner":"kubetail-org","description":"Small JavaScript library for converting ANSI to HTML","archived":false,"fork":false,"pushed_at":"2024-09-09T18:09:31.000Z","size":369,"stargazers_count":95,"open_issues_count":2,"forks_count":3,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-08-31T19:03:07.287Z","etag":null,"topics":["ansi","conversion","html"],"latest_commit_sha":null,"homepage":"https://kubetail-org.github.io/fancy-ansi/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kubetail-org.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-03-29T10:53:40.000Z","updated_at":"2025-08-28T06:03:30.000Z","dependencies_parsed_at":"2024-05-10T13:39:40.635Z","dependency_job_id":"fc32b5ea-589f-48e3-93eb-be81e2135069","html_url":"https://github.com/kubetail-org/fancy-ansi","commit_stats":null,"previous_names":["kubetail-org/fancy-ansi"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/kubetail-org/fancy-ansi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kubetail-org%2Ffancy-ansi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kubetail-org%2Ffancy-ansi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kubetail-org%2Ffancy-ansi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kubetail-org%2Ffancy-ansi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kubetail-org","download_url":"https://codeload.github.com/kubetail-org/fancy-ansi/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kubetail-org%2Ffancy-ansi/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274146174,"owners_count":25230115,"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","status":"online","status_checked_at":"2025-09-08T02:00:09.813Z","response_time":121,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["ansi","conversion","html"],"created_at":"2024-11-14T00:17:48.887Z","updated_at":"2025-09-08T06:35:03.592Z","avatar_url":"https://github.com/kubetail-org.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Fancy-ANSI\n\nFancy-ANSI is a small JavaScript library for converting ANSI to beautiful, browser-safe HTML\n\n\u003cimg width=\"536\" alt=\"Screen Shot 2024-03-30 at 1 19 54 PM\" src=\"https://github.com/kubetail-org/fancy-ansi/assets/75881/ebfaa8b4-f5d3-460e-b204-98a85285d377\"\u003e\n\nDemo: [https://www.kubetail.com/demo](https://www.kubetail.com/demo)  \nPreview: [https://kubetail-org.github.io/fancy-ansi/](https://kubetail-org.github.io/fancy-ansi/)\n\n## Introduction\n\nWhile adding ANSI markup support to [kubetail](https://github.com/kubetail-org/kubetail) we tested out several popular popular ANSI-to-html conversion libraries (e.g. [ansi-html-community](https://github.com/mahdyar/ansi-html-community), [ansi-to-html](https://github.com/rburns/ansi-to-html), [ansi_up](https://github.com/drudru/ansi_up)) and ran into a few problems:\n\n* Failure to parse some of our users' ANSI markup\n* Use of hard-coded styles that made customization more difficult\n* Lack of support for CSS variables\n\nTo solve these problems and make something that integrated nicely into our frontend stack (Tailwind, React) we created Fancy-ANSI. The library is designed to be small (~4 kb gzipped), performant, easy-to-use and safe from XSS attacks. It has the following features:\n\n* Supports easy customization using CSS variables\n* Supports almost all SGR codes\n* Includes a Tailwind plugin that enables support for easy theming\n* Includes a React component for easy use in a React environment\n* Includes useful utilities like `hasAnsi()` and `stripAnsi()` that come in handy when working with ANSI\n* Includes popular color palettes that can be swapped in easily\n\nTry it out and let us know what you think! If you notice any bugs or have any feature requests just create a GitHub Issue.\n\n## Quickstart\n\nInstall the library using your favorite package manager:\n\n```sh\n# npm\nnpm install fancy-ansi\n\n# yarn\nyarn add fancy-ansi\n\n# pnpm\npnpm add fancy-ansi\n```\n\nNow you can use it in your code with React:\n\n```jsx\n// ExampleComponent.jsx\nimport { AnsiHtml } from 'fancy-ansi/react';\n\nexport const ExampleComponent = () =\u003e {\n  const text = '\\x1b[34mhello \\x1b[33mworld\\x1b[0m';\n  return \u003cAnsiHtml className=\"font-mono whitespace-pre text-sm\" text={text} /\u003e;\n};\n```\n\nOr with Vanilla-JS:\n\n```typescript\n// example.ts\nimport { FancyAnsi } from 'fancy-ansi';\n\nconst fancyAnsi = new FancyAnsi();\n\nexport function addElementWithAnsi() {\n  const el = document.createElement('div');\n  el.innerHTML = fancyAnsi.toHtml('\\x1b[34mhello \\x1b[33mworld\\x1b[0m');\n  document.body.append(el);\n}\n```\n\nThe HTML rendered is browser-safe and ready with some sensible color choices that can be customized easily (see below).\n\n## Configuration\n\nYou can configure Fancy-ANSI using CSS variables. For example, to invert blacks in dark mode you can change the value of black when the document has a \"dark\" class:\n\n```css\n:root {\n  --ansi-black: #000;\n}\n\n.dark {\n  --ansi-black: #FFF;\n}\n```\n\nThe full list of supported variables can be found in the [SGR Parameters](#sgr-parameters) section below.\n\n## SGR Parameters\n\n| n   | Name                                     | Supported          | CSS Variables                | Default   |\n| --- | ---------------------------------------- | ------------------ | ---------------------------- | --------- |\n| 0   | Reset                                    | :heavy_check_mark: |                              |           |\n| 1   | Bold                                     | :heavy_check_mark: | --ansi-bold-font-weight      | 600       |\n| 2   | Dim                                      | :heavy_check_mark: | --ansi-dim-opacity           | 0.7       |\n| 3   | Italic                                   | :heavy_check_mark: |                              |           |\n| 4   | Underline                                | :heavy_check_mark: |                              |           |\n| 5   | Slow blink                               |                    |                              |           |\n| 6   | Fast blink                               |                    |                              |           |\n| 7   | Invert                                   |                    |                              |           |\n| 8   | Hide                                     | :heavy_check_mark: |                              |           |\n| 9   | Strikethrough                            | :heavy_check_mark: |                              |           |\n| 10  | Default font                             | :heavy_check_mark: |                              |           |\n| 11  | Alternative font 1                       | :heavy_check_mark: | --ansi-font-1                |           |\n| 12  | Alternative font 2                       | :heavy_check_mark: | --ansi-font-2                |           |\n| 13  | Alternative font 3                       | :heavy_check_mark: | --ansi-font-3                |           |\n| 14  | Alternative font 4                       | :heavy_check_mark: | --ansi-font-4                |           |\n| 15  | Alternative font 5                       | :heavy_check_mark: | --ansi-font-5                |           |\n| 16  | Alternative font 6                       | :heavy_check_mark: | --ansi-font-6                |           |\n| 17  | Alternative font 7                       | :heavy_check_mark: | --ansi-font-7                |           |\n| 18  | Alternative font 8                       | :heavy_check_mark: | --ansi-font-8                |           |\n| 19  | Alternative font 9                       | :heavy_check_mark: | --ansi-font-9                |           |\n| 20  | Gothic                                   |                    |                              |           |\n| 21  | Double underline                         | :heavy_check_mark: |                              |           |\n| 22  | Bold off                                 | :heavy_check_mark: |                              |           |\n| 23  | Italic off                               | :heavy_check_mark: |                              |           |\n| 24  | Underline off                            | :heavy_check_mark: |                              |           |\n| 25  | Blink off                                |                    |                              |           |\n| 26  | Proportional spacing                     |                    |                              |           |\n| 27  | Invert off                               |                    |                              |           |\n| 28  | Hidden off                               | :heavy_check_mark: |                              |           |\n| 29  | Strikethrough off                        | :heavy_check_mark: |                              |           |\n| 30  | Foreground color - black                 | :heavy_check_mark: | --ansi-black                 | #2e3436   |\n| 31  | Foreground color - red                   | :heavy_check_mark: | --ansi-red                   | #cc0000   |\n| 32  | Foreground color - green                 | :heavy_check_mark: | --ansi-green                 | #4e9a06   |\n| 33  | Foreground color - yellow                | :heavy_check_mark: | --ansi-yellow                | #c4a000   |\n| 34  | Foreground color - blue                  | :heavy_check_mark: | --ansi-blue                  | #3465a4   |\n| 35  | Foregorund color - magenta               | :heavy_check_mark: | --ansi-magenta               | #75507b   |\n| 36  | Foreground color - cyan                  | :heavy_check_mark: | --ansi-cyan                  | #06989a   |\n| 37  | Foreground color - white                 | :heavy_check_mark: | --ansi-white                 | #d3d7cf   |\n| 38  | Foreground color - extended (see below)  | :heavy_check_mark: |                              |           |\n| 39  | Default foreground color                 | :heavy_check_mark: |                              |           |\n| 40  | Background color - black                 | :heavy_check_mark: | --ansi-black                 | #2e3436   |\n| 41  | Background color - red                   | :heavy_check_mark: | --ansi-red                   | #cc0000   |\n| 42  | Background color - green                 | :heavy_check_mark: | --ansi-green                 | #4e9a06   |\n| 43  | Background color - yellow                | :heavy_check_mark: | --ansi-yellow                | #c4a000   |\n| 44  | Background color - blue                  | :heavy_check_mark: | --ansi-blue                  | #3465a4   |\n| 45  | Background color - magenta               | :heavy_check_mark: | --ansi-magenta               | #75507b   |\n| 46  | Background color - cyan                  | :heavy_check_mark: | --ansi-cyan                  | #06989a   |\n| 47  | Background color - white                 | :heavy_check_mark: | --ansi-white                 | #d3d7cf   |\n| 48  | Background color - extended (see below)  | :heavy_check_mark: |                              |           |\n| 49  | Default background color                 | :heavy_check_mark: |                              |           |\n| 50  | Proportional spacing off                 |                    |                              |           |\n| 51  | Frame                                    | :heavy_check_mark: | --ansi-frame-outline         | 1px solid |\n| 52  | Encircle                                 |                    |                              |           |\n| 53  | Overline                                 | :heavy_check_mark: |                              |           |\n| 54  | Frame/encircle off                       | :heavy_check_mark: |                              |           |\n| 55  | Overline off                             | :heavy_check_mark: |                              |           |\n| 58  | Underground color - extended (see below) | :heavy_check_mark: |                              |           |\n| 59  | Default underline color                  | :heavy_check_mark: |                              |           |\n| 60  | Right side line                          |                    |                              |           |\n| 61  | Double line on the right side            |                    |                              |           |\n| 62  | Left side line                           |                    |                              |           |\n| 63  | Double line on the left side             |                    |                              |           |\n| 64  | Ideogram stress marking                  |                    |                              |           |\n| 65  | Side lines off                           |                    |                              |           |\n| 73  | Superscript                              | :heavy_check_mark: | --ansi-superscript-font-size | 80%       |\n| 74  | Subscript                                | :heavy_check_mark: | --ansi-subscript-font-size   | 80%       |\n| 75  | Superscript/subscript off                | :heavy_check_mark: |                              |           |\n| 90  | Foreground color - bright black          | :heavy_check_mark: | --ansi-bright-black          | #555753   |\n| 91  | Foreground color - bright red            | :heavy_check_mark: | --ansi-bright-red            | #ef2929   |\n| 92  | Foreground color - bright green          | :heavy_check_mark: | --ansi-bright-green          | #8ae234   |\n| 93  | Foreground color - bright yellow         | :heavy_check_mark: | --ansi-bright-yellow         | #fce94f   |\n| 94  | Foreground color - bright blue           | :heavy_check_mark: | --ansi-bright-blue           | #729fcf   |\n| 95  | Foreground color - bright magenta        | :heavy_check_mark: | --ansi-bright-magenta        | #ad7fa8   |\n| 96  | Foreground color - bright cyan           | :heavy_check_mark: | --ansi-bright-cyan           | #34e2e2   |\n| 97  | Foreground color - bright white          | :heavy_check_mark: | --ansi-bright-white          | #eeeeec   |\n| 100 | Background color - bright black          | :heavy_check_mark: | --ansi-bright-black          | #555753   |\n| 101 | Background color - bright red            | :heavy_check_mark: | --ansi-bright-red            | #ef2929   |\n| 102 | Background color - bright green          | :heavy_check_mark: | --ansi-bright-green          | #8ae234   |\n| 103 | Background color - bright yellow         | :heavy_check_mark: | --ansi-bright-yellow         | #fce94f   |\n| 104 | Background color - bright blue           | :heavy_check_mark: | --ansi-bright-blue           | #729fcf   |\n| 105 | Background color - bright magenta        | :heavy_check_mark: | --ansi-bright-magenta        | #ad7fa8   |\n| 106 | Background color - bright cyan           | :heavy_check_mark: | --ansi-bright-cyan           | #34e2e2   |\n| 107 | Background color - bright white          | :heavy_check_mark: | --ansi-bright-white          | #eeeeec   |\n\nExtended colors:\n\n| Code pattern             | Description                              | CSS Variables      |\n| ------------------------ | ---------------------------------------- | ------------------ |\n| 38;2;{r};{g};{b}         | Set foreground color - (r,g,b)           |                    |\n| 38;5;{n} (0 ≤ n ≤ 15)    | Set foreground color - standard colors   | --ansi-{color}     |\n| 38;5;{n} (16 ≤ n ≤ 231)  | Set foreground color - 6x6 rgb cube      |                    |\n| 38;5;{n} (232 ≤ n ≤ 232) | Set foreground color - 24-step grayscale | --ansi-gray-{step} |\n| 48;2;{r};{g};{b}         | Set background color - (r,g,b)           |                    |\n| 48;5;{n} (0 ≤ n ≤ 15)    | Set background color - standard colors   | --ansi-{color}     |\n| 48;5;{n} (16 ≤ n ≤ 231)  | Set background color - 6x6 rgb cube      |                    |\n| 48;5;{n} (232 ≤ n ≤ 232) | Set background color - 24-step grayscale | --ansi-gray-{step} |\n| 58;2;{r};{g};{b}         | Set underline color - (r,g,b)            |                    |\n| 58;5;{n} (0 ≤ n ≤ 15)    | Set underline color - standard colors    | --ansi-{color}     |\n| 58;5;{n} (16 ≤ n ≤ 231)  | Set underline color - 6x6 rgb cube       |                    |\n| 58;5;{n} (232 ≤ n ≤ 232) | Set underline color - 24-step grayscale  | --ansi-gray-{step} |\n\n## Integrations\n\n### Tailwind\n\nThe Fancy-ANSI Tailwind plugin makes it easy to support theming and to access multiple built-in palettes from your css. To use the plugin, add it to your `tailwind.config.js` file:\n\n```js\n// tailwind.config.js\nmodule.exports = {\n  plugins: [\n    // ...\n    require('fancy-ansi/plugin')\n  ]\n}\n```\n\nNow you can access the built-in palettes using the Tailwind `theme()` function. For example, you can implement two different palettes for light/dark mode like this:\n\n```css\n/* index.css */\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n@layer base {\n  :root {\n    --ansi-black: theme(ansi.colors.vscode.black);\n    --ansi-red: theme(ansi.colors.vscode.red);\n    --ansi-green: theme(ansi.colors.vscode.green);\n    --ansi-yellow: theme(ansi.colors.vscode.yellow);\n    --ansi-blue: theme(ansi.colors.vscode.blue);\n    --ansi-magenta: theme(ansi.colors.vscode.magenta);\n    --ansi-cyan: theme(ansi.colors.vscode.cyan);\n    --ansi-white: theme(ansi.colors.vscode.white);\n    --ansi-bright-black: theme(ansi.colors.vscode.bright-black);\n    --ansi-bright-red: theme(ansi.colors.vscode.bright-red);\n    --ansi-bright-green: theme(ansi.colors.vscode.bright-green);\n    --ansi-bright-yellow: theme(ansi.colors.vscode.bright-yellow);\n    --ansi-bright-blue: theme(ansi.colors.vscode.bright-blue);\n    --ansi-bright-magenta: theme(ansi.colors.vscode.magenta);\n    --ansi-bright-cyan: theme(ansi.colors.vscode.cyan);\n    --ansi-bright-white: theme(ansi.colors.vscode.white);\n  }\n\n  .dark {\n    --ansi-black: theme(ansi.colors.xtermjs.black);\n    --ansi-red: theme(ansi.colors.xtermjs.red);\n    --ansi-green: theme(ansi.colors.xtermjs.green);\n    --ansi-yellow: theme(ansi.colors.xtermjs.yellow);\n    --ansi-blue: theme(ansi.colors.xtermjs.blue);\n    --ansi-magenta: theme(ansi.colors.xtermjs.magenta);\n    --ansi-cyan: theme(ansi.colors.xtermjs.cyan);\n    --ansi-white: theme(ansi.colors.xtermjs.white);\n    --ansi-bright-black: theme(ansi.colors.xtermjs.bright-black);\n    --ansi-bright-red: theme(ansi.colors.xtermjs.bright-red);\n    --ansi-bright-green: theme(ansi.colors.xtermjs.bright-green);\n    --ansi-bright-yellow: theme(ansi.colors.xtermjs.bright-yellow);\n    --ansi-bright-blue: theme(ansi.colors.xtermjs.bright-blue);\n    --ansi-bright-magenta: theme(ansi.colors.xtermjs.magenta);\n    --ansi-bright-cyan: theme(ansi.colors.xtermjs.cyan);\n    --ansi-bright-white: theme(ansi.colors.xtermjs.white);\n  }\n```\n\n### React\n\nFancy-ANSI has a convenient React component that you can import from the `fancy-ansi/react` module:\n\n```jsx\n// ExampleComponent.jsx\nimport { AnsiHtml } from 'fancy-ansi/react';\n\nexport const ExampleComponent = () =\u003e {\n  const text = '\\x1b[34mhello \\x1b[33mworld\\x1b[0m';\n  return \u003cAnsiHtml className=\"font-mono whitespace-pre text-sm\" text={text} /\u003e;\n};\n```\n\n## Examples\n\nYou can see some example implementations in the [`examples/`](examples/) directory:\n\n* [Vite - React](examples/vite-react)\n* [Next.js](examples/nextjs)\n\n## API\n\n### FancyAnsi - The converter class\n\n```\nFancyAnsi\n\n  toHtml(input)\n    * @param {string} input - The input string\n    * @returns {string} Browser-safe HTML string containing stylized ANSI content\n\nExample:\n\n  import { FancyAnsi } from 'fancy-ansi';\n\n  const fancyAnsi = new FancyAnsi();\n  fancyAnsi.toHtml('\\x1b[1mThis is in bold.\\x1b[0m');\n```\n\n### hasAnsi() - Check if a string has ANSI markup\n\n```\nhasAnsi(input)\n\n  * @param {string} input - The input string\n  * @returns {boolean} Boolean indicating whether or not input string contains ANSI markup\n\nExample:\n\n  import { hasAnsi } from 'fancy-ansi';\n\n  if (hasAnsi('\\x1b[1mThis is in bold.\\x1b[0m')) {\n    console.log('string has ansi');\n  } else {\n    console.log('string doesn\\'t have ansi');\n  }\n```\n\n### stripAnsi() - Remove ANSI markup\n\n```\nstripAnsi(input)\n\n  * @param {string} input - The input string\n  * @returns {string} Content of input string with ANSI markup removed\n\nExample:\n\n  import { stripAnsi } from 'fancy-ansi';\n\n  const withoutAnsi = stripAnsi('\\x1b[1mThis is in bold.\\x1b[0m');\n  console.log(`string without ansi: ${withoutAnsi}`);\n```\n\n### colors - Built-in palettes\n\n```\n`fancy-ansi/colors` module\n\nExample:\n\n  import { xtermjs, terminalapp } from 'fancy-ansi/colors';\n\n  console.log(`xterm.js red: ${xtermjs.red}`);\n  console.log(`Terminal.app red: ${terminalapp.red}`);\n\nAvailable palettes:\n\n  * eclipse\n  * putty\n  * terminalapp\n  * ubuntu\n  * vga\n  * vscode\n  * windows10\n  * xterm\n  * xtermjs\n```\n\n## Development\n\n### Get the code\n\nTo develop Fancy-ANSI, first clone the repository then install the dependencies:\n\n```sh\ngit clone git@github.com:kubetail-org/fancy-ansi.git\ncd fancy-ansi\npnpm install\n```\n\n### Run the dev server\n\nFancy-ANSI uses vite for development. To run run the vite dev server, use the `dev` command:\n\n```sh\npnpm dev\n```\n\nNow you can access the demo page and see your changes at [http://localhost:5173/](http://localhost:5173/).\n\n### Run the unit tests\n\nFancy-ANSI uses jest for testing (via vitest). To run the tests, use the `test` command:\n\n```sh\npnpm test\n```\n\nThe test files are colocated with the source code in the `src/` directory, with the filename format `{name}.test.(ts|tsx)`.\n\n### Build for production\n\nTo build Fancy-ANSI for production, run the `build` command:\n\n```sh\npnpm build\n```\n\nThe production files will be located in the `dist/` directory.\n\n## Acknowledgements\n\n* The ANSI parsing code is from [ansi_up](https://github.com/drudru/ansi_up)\n* has/strip methods use [Chalk's](https://github.com/chalk/chalk) [ansi-regex](https://github.com/chalk/ansi-regex)\n* [Fancy Nancy](https://www.fancynancyworld.com)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkubetail-org%2Ffancy-ansi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkubetail-org%2Ffancy-ansi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkubetail-org%2Ffancy-ansi/lists"}