Skip to content

tool3/shellfie

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

41 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

shellfie

Take a shell selfie.
Your terminal output deserves better than a blurry screenshot.

shellfie

Feature shellfie carbon-now-cli svg-term termtosvg
Zero dependencies
No native bindings
No headless browser
Full ANSI support
24-bit true color
Runs in browser
Synchronous API
import { execSync } from "child_process";
import shellfie from 'shellfie'

const log = execSync("git log --oneline --graph --color=always").toString();
const svg = shellfie(log, { title: "git log" });

Git Log

Why SVG?

Infinitely scalable — pixel-perfect at any zoom level, retina-ready by default.
Selectable text — copy code directly from the image.
Embeddable everywhere — high quality embedding in READMEs, docs, blogs, everywhere.
Tiny files — 2-10KB vs blurry 500KB+ PNGs.
No rendering pipeline — runs anywhere JavaScript runs.

Install

npm install shellfie

Usage

import shellfie from "shellfie";

const svg = shellfie(terminalOutput, {
  template: "macos",
  title: "npm test",
});

Browser

<script type="module">
  import shellfie from "https://esm.sh/shellfie";

  const svg = shellfie("\x1b[32m$ npm test\x1b[0m\nAll tests passed!", {
    template: "macos",
    title: "terminal",
  });

  document.body.innerHTML = svg;
</script>

Templates

macOS Windows Minimal
macos windows minimal
shellfie(output, { template: "macos" }); // default
shellfie(output, { template: "windows" });
shellfie(output, { template: "minimal" });

Custom Templates

Create your own templates with createTemplate:

import shellfie, { createTemplate } from "shellfie";

const myTemplate = createTemplate("my-template", {
  titleBar: true,
  titleBarHeight: 40,
  borderRadius: 10,
  controls: true,
  controlsPosition: "left",
  controlStyle: {
    close: "#ff5f56",
    minimize: "#ffbd2e",
    maximize: "#27c93f",
    radius: 6,
    spacing: 20,
    size: 12,
  },
  padding: 16,
  shadow: true,
  border: false,
  borderColor: "#333333",
  borderWidth: 0,
  header: {
    backgroundColor: "rgb(36, 37, 38)",
    border: false,
  },
});

shellfie(output, { template: myTemplate });

Templates can include default header and footer configurations. User options always override template defaults:

// Template has header.backgroundColor set, but user can override it
shellfie(output, {
  template: myTemplate,
  header: { backgroundColor: "#000000" }, // overrides template default
});

Options

shellfie(input, {
  template?: "macos",                             // 'macos' | 'windows' | 'minimal' | Template
  title?: "my-terminal",                          // window title
  width?: 80,                                     // terminal columns (auto-detected if not set)
  padding?: 16,                                   // number | [v, h] | [top, right, bottom, left]
  controls?: true,                                // show window control buttons
  controlsPosition?: "left",                      // 'left' (macOS) or 'right' (Windows)
  fontSize?: 14,                                  // font size in pixels
  lineHeight?: 1.4,                               // line height multiplier
  fontFamily?: "'SF Mono', Monaco, monospace",    // font stack
  customGlyphs?: true,                            // pixel-perfect box drawing characters
  embedFont?: true,                               // embed default font as base64 (async only)
  customFont?: {                                  // use your own font
    data: base64FontData,                         //   base64-encoded font data
    format: "woff2",                              //   'woff2' | 'woff' | 'ttf'
  },
  theme?: customTheme,                            // custom color theme or see themes below
  watermark?: "Generated by shellfie",            // bottom-right text (supports ANSI)
  watermarkPadding?: 16,                          // number | [v, h] | [top, right, bottom, left]
  header?: {                                      // header configuration
    backgroundColor?: "#2d2d2d",                  //   title bar background color
    height?: 40,                                  //   title bar height in pixels
    border?: true,                                //   show bottom border
    borderColor?: "#1a1a1a",                      //   border color
    borderWidth?: 1,                              //   border width in pixels
  },
  footer?: {                                      // footer configuration
    backgroundColor?: "#2d2d2d",                  //   footer background color
    height?: 30,                                  //   footer height in pixels
    border?: true,                                //   show top border
    borderColor?: "#1a1a1a",                      //   border color
    borderWidth?: 1,                              //   border width in pixels
  },
});

Font Embedding

For portable SVGs that render identically everywhere:

import { shellfieAsync } from "shellfie";

const svg = await shellfieAsync(input, { embedFont: true });

The font gets base64-encoded directly into the SVG. No external requests, no CORS issues, no "why does this look different on their machine" debugging sessions.

Themes

shellfie comes with 12 built-in themes:

import shellfie, { dracula, nord, tokyoNight } from "shellfie";

shellfie(output, { theme: dracula });
Dracula Nord Tokyo Night
Dracula Nord Tokyo Night
One Dark Monokai Catppuccin Mocha
One Dark Monokai Catppuccin Mocha
GitHub Dark GitHub Light Gruvbox Dark
GitHub Dark GitHub Light Gruvbox Dark
Gruvbox Light Solarized Dark Solarized Light
Gruvbox Light Solarized Dark Solarized Light

Custom Themes

import shellfie, { createTheme } from "shellfie";

const theme = createTheme({
  name: "ocean",
  background: "#0a2540",
  foreground: "#e6f1ff",
  red: "#ff6b6b",
  green: "#69db7c",
  // ... all 16 ANSI colors
});

shellfie(output, { theme });

Full Color Support

24-bit True Color & 256-color palette

import gradient from "gradient-string";
import shellfie from "shellfie";

const svg = shellfie(gradient.rainbow("Hello World"), {
  template: "macos",
  title: "gradient string",
});

Gradient String

Works with any ANSI output

import Chartscii from "chartscii";
import shellfie from "shellfie";

const chart = new Chartscii(data, {
  barSize: 2,
  fill: "▒",
  colorLabels: true,
  orientation: "vertical",
  valueLabels: true,
});

const svg = shellfie(chart.create(), {
  template: "macos",
  title: "Chartscii",
  padding: 50,
});

Chartscii

CLI tools, test runners, anything

shellfie(execSync("git diff --color=always").toString());
shellfie(execSync("npm test 2>&1").toString());
shellfie(execSync("ls -la --color=always").toString());

Utilities

import { parse, render, stripAnsi, getMaxWidth } from "shellfie";

const lines = parse("\x1b[31mred\x1b[0m text");
const svg = render(lines, options);

stripAnsi("\x1b[31mred\x1b[0m"); // 'red'
getMaxWidth(lines); // 80

Related

License

MIT — do whatever you want with it. If you build something cool, I'd love to see it.

About

Terminal output → SVG. Zero dependencies.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors