"Telnet based drawing functions and renderers"

Usage no npm install needed!

<script type="module">
  import tomatoSauce from '';



Draw stuff via telnet

How to run

npm install and then run ``./bin/server.js`. It will listen on port 9999 by default.

Configuration variables

Tomato Sauce can be configured using env variables:

  • TOMATO_SAUCE_PORT: The port to listen on. Defauts to 9999.
  • TOMATO_SAUCE_FREQUENCY: How often it will send a screen in miliseconds. Defaults to 333.
  • TOMATO_SAUCE_MODULATION: How much the modulation counter will increase per round. Defaults to 5.
  • TOMATO_SAUCE_SCREEN_PATH: Path from which we will load screens. It defaults to {project_root}/lib/screens
  • TOMATO_SAUCE_RENDERER_PATH: Path from which we will load renderers. It defaults to {project_root}/lib/renderers

Make your own screens

A screen is a function that will receive a modulation value from 0-255, the width of the viewport, the height of the viewport, and a renderer function, and it returns a string that consists of the commands that will be sent to the socket.

  • TomatoSauce.IScreen(modulation <int>, width <int>, height <int>, renderer <TomatoSauce.IRenderer>) -> payload <string>

It should output the required commands that telnet needs to move the cursor and draw. For convenience, a renderer function is passed so calculating color should not be a part of the screen, just moving the cursor around and calling specific colors.

Make your own renderers

The included renderers are wrappers to some common ways of obtaining colors in the terminal: ANSI, 256 colors, 24-bit colors, and a fake color string that uses incorrect color strings to generate random variations.

You can build your own renderer by building a function that receives a red, green, and blue component from 0 to 255 and returns the escape codes to generate the color.

  • TomatoSauce.IRenderer(red <int>, green <int>, blue <int>) -> colorString <string>

Using as a library

The binary just serves as a wrapper to read configuration, and as a bridge to the console. It consumes lib/tomato_sauce. All configuration is optional, and should be passed as an object on instantiation. The instance is an event emitter that will emit a listening event with the server data, and an error event in case something goes wrong.

const TomatoSauce = require('tomato-sauce');

const tomatoSauce = new TomatoSauce(config);

tomatoSauce.on('listening', function () {
  const address =;
  console.log(`Tomato Sauce listening on: ${address.address}:${address.port}`);

tomatoSauce.on('error', function (error) {

Configuration Values

The config object should be a simple object with these keys (All are optional.)

  • port: The port to listen on (Defaults to 9999)
  • frequency: How often we'll send a new frame in milliseconds (Defaults to 333)
  • modulation: How fast the modulation counter will be increased (Defaults to 5)
  • screens: An array containing the screen functions (Defaults to [])
  • renderers: An array containing the renderer functions (Defaults to [])