Generative Embroidery with p5.embroider

This article is the December 19th entry for Processing Advent Calendar 2025.

https://nkymut.github.io/p5-advent-2025/

Table of Contents
  1. Generative Embroidery with p5.embroider
    1. Previous Advent Calendar Articles
  2. Introduction
  3. p5.embroider Workflow
    1. 1. Loading the p5.embroider Library
      1. Sample Code
    2. 2. Creating the p5.js Canvas
    3. 3. Setting the Preview Mode
    4. 4. Creating Embroidery Data: beginRecord(), endRecord()
    5. 5. Configuring Embroidery Parameters: setStrokeSettings(), setFillSettings()
      1. Configuring Line Stitching: setStrokeSettings()
      2. Configuring Fill Stitching: setFillSettings()
      3. Thread Trimming: trimThread()
      4. Varying Embroidery Path Width: vertex, vertexWidth
    6. 6. Exporting Embroidery Data: exportEmbroidery()
  4. Example: Fractal Christmas Tree 2025 Edition
  5. Conclusion

Previous Advent Calendar Articles

Introduction

In this article, I’ll introduce how to generatively design embroidery data with p5.js using the p5.embroider library.

In the 2023 p5 Advent Calendar article, I showed how to create digital embroidery by combining p5.js and Ink/Stitch. Now, with p5.embroider developed by the author, you can directly export embroidery data from p5.js drawings.

blue lissajous pattern with embroidery

Let’s dive right in and start generating embroidery data with p5.embroider!

p5.embroider Workflow

Here’s the workflow for designing embroidery data with p5.embroider:

  1. Load the p5.embroider library
  2. Create a p5.js canvas in mm units using the mm2px() function
  3. Set the embroidery preview mode using setDrawMode()
  4. Create embroidery data between beginRecord() and endRecord()
  5. Configure stitch spacing and other settings using setStrokeSettings() and setFillSettings()
  6. Export embroidery data with exportEmbroidery()
  7. Load the embroidery data into your embroidery machine and stitch
  8. Fine-tune the embroidery settings based on the machine output results

1. Loading the p5.embroider Library

To use p5.embroider, add the following script tag to your HTML file, just like any other p5.js library:


<!-- Using CDN: -->
<script src="https://unpkg.com/p5.embroider/lib/p5.embroider.js"></script>
<!-- Using GitHub Pages: -->
<script src="https://nkymut.github.io/p5.embroider/lib/p5.embroider.js"></script>

Sample Code

Here’s sample code that generates embroidery data using p5.embroider:

This code embroiders an 80mm x 80mm rectangle with zigzag stitching on a 100mm x 100mm canvas.

  // Create a 100mm x 100mm canvas
  createCanvas(mmToPixel(100), mmToPixel(100));

  background(200);

  setDrawMode("realistic"); // Set the preview mode

  beginRecord(this); // Start creating embroidery data
  translate(10,10); // Translate the drawing origin to (10,10)mm

  setStrokeSettings({ // Configure stroke stitch settings
    stitchLength: 0.5, // Length of each stitch
    stitchWidth: 0.2, // Width of each stitch
    noise: 0.0, // Random coefficient
    strokeInterpolate: true, // Enable stroke interpolation
  });
  stroke(0, 220, 220); // Set the stroke color
  strokeWeight(5); // Set the stroke weight
  setStrokeMode("zigzag"); // Set stroke stitch mode to zigzag
  
  rect(0, 0, 80, 80); // Draw an 80mm x 80mm rectangle
  trimThread(); // Insert a thread trim command

  endRecord(); // Finish creating embroidery data

  exportEmbroidery("simple.dst"); // Export as TAJIMA DST file

2. Creating the p5.js Canvas

Create the canvas using the createCanvas function as usual.

In p5.embroider, we use mm units instead of pixels for size specifications to create embroidery data at actual size.

Use the mmToPixel() function to specify the canvas size in mm units and convert it to pixels.

The same applies when using the createGraphics() function.


 // Create a 100mm x 100mm canvas
createCanvas(mmToPixel(100), mmToPixel(100));

// Create a 100mm x 100mm p5 graphics instance
let pg = createGraphics(mmToPixel(100), mmToPixel(100)); 


// Unit conversion functions list

mmToPixel(100); // Convert 100mm to pixels
mm2px(100); // Shorthand

pixelToMm(100); // Convert 100 pixels to mm
px2mm(100); // Shorthand

3. Setting the Preview Mode

setDrawMode("stitch"); // Set embroidery mode to toolpath drawing mode

In addition to p5.js’s drawing methods, p5.embroider supports preview modes that let you visualize the embroidery appearance and sewing machine needle movements.

You can switch between embroidery drawing preview modes using the setDrawMode() function.

Currently, three preview modes are supported:

  • “stitch”: Embroidery toolpath drawing mode
  • “p5”: p5.js drawing mode
  • “realistic”: Embroidery simulation mode

4. Creating Embroidery Data: beginRecord(), endRecord()

Create embroidery data within the range enclosed by beginRecord() and endRecord().

p5.js drawing functions (like ellipse() or rect()) within this range are interpreted as p5.embroider embroidery drawings and rendered according to the previously specified preview mode.

Within this range, drawing function arguments are interpreted in mm units, allowing you to design using actual embroidery dimensions.

You can use familiar p5.js drawing functions and existing p5 sketches with little to no modification for embroidery design. This is one of p5.embroider’s key features.

Note that as of December 2025, the text() function is not supported. Check the following Issue https://github.com/nkymut/p5.embroider/issues/2 for the status of supported functions. PRs are of course very welcome!

Outside the range enclosed by beginRecord() and endRecord(), p5.js drawing functions render to the canvas normally, so you can draw UI, animations, and other graphics. In this case, parameters are interpreted in pixel units, so if you want to draw with the same positional relationship as the embroidery data, use the mmToPixel() function to convert from mm units to pixel units.


beginRecord(this);
    // Create embroidery data
    // Record a circle at x:50mm, y:50mm, width:50mm, height:50mm as embroidery data
    ellipse(50, 50, 50, 50); 
endRecord();

// Draw a circle on the canvas at x:50px, y:50px, width:50px, height:50px
ellipse(50, 50, 50, 50); 

5. Configuring Embroidery Parameters: setStrokeSettings(), setFillSettings()

Once you’ve created the embroidery drawing, configure the stitch spacing, fill settings, and other parameters.

Configuring Line Stitching: setStrokeSettings()

Just like regular p5.js drawing functions, configure embroidery parameters for stroke() line drawing using the setStrokeSettings() function. The line weight set by p5’s strokeWeight() function becomes the embroidery width (in mm).

Currently, the following stroke stitch types are supported: straight stitch, zigzag stitch (triangular, rectangular), parallel stitch, and sashiko-style stitch.

stroke(0, 0, 200); // Set the stroke color
strokeWeight(5); // Set the stroke weight to 5mm

// Set the stroke stitch mode to zigzag
// "straight": Straight stitch
// "zigzag"  : Zigzag stitch
// "parallel": Parallel stitch
// "sashiko" : Sashiko-style stitch
setStrokeMode("zigzag"); 

// Set stroke embroidery parameters
setStrokeSettings({
  stitchLength: 0.5, // Length of each stitch
  stitchWidth: 0.2, // Width of each stitch
  noise: 0.0, // Random coefficient
  strokeInterpolate: true, // Enable stroke interpolation
});


// Shorthand:
// Set minimum, length, and random coefficient for stitches
setStitch(0.1, 0.2, 0); 
// Set stitch width
setStitchWidth(0.2); 

Configuring Fill Stitching: setFillSettings()

Like stroke settings, after setting the color with the fill() function, you can configure fill embroidery parameters using the setFillSettings function.

Currently supported fill methods include tatami stitch, satin stitch, and spiral stitch.


fill(220, 220, 0); // Set the fill color

// Set fill embroidery parameters
setFillSettings({
  angle: 45, // Set the fill angle
  stitchLength: 0.5, // Length of each stitch
  stitchWidth: 0.2, // Width of each stitch
  rowSpacing: 0.8, // Set the stitch spacing
  resampleNoise: 0.0, // Random coefficient
});

// Set the fill mode
// "tatami": Tatami stitch
// "satin": Satin stitch
// "spiral": Spiral stitch
setFillMode("tatami"); 

Thread Trimming: trimThread()

Trim threads using the trimThread() function. This function inserts a thread trim command into the embroidery path.

trimThread();

Varying Embroidery Path Width: vertex, vertexWidth

To vary the embroidery width along a path, you can use the z-coordinate of vertex(x,y,z) as the zigzag embroidery width.

You can also use the vertexWidth() function newly added in p5.embroider.

This makes it easy to generate embroidery designs like baseball cap lettering or calligraphy-style embroidery.

setStrokeMode("zigzag");
beginShape();
vertex(10, 10, 1); //1mm width
vertex(30, 10, 5); //5mm width
vertex(50, 10, 8); //8mm width
vertex(70, 10, 5); //5mm width
vertex(90, 10, 1);
endShape();

6. Exporting Embroidery Data: exportEmbroidery()

Finally, calling the exportEmbroidery() function exports the recorded embroidery data as a file.

The drawn embroidery data is recorded as separate embroidery paths for each color specified with stroke() and fill(). This allows you to stitch embroidery paths of the same color together.

If you want to specify the stitching order, you can arrange colors in ascending numerical order to control the embroidery sequence.

Supported export formats include TAJIMA DST files, G-code, SVG, and PNG.

exportEmbroidery("simple.dst"); // Export as TAJIMA DST file
exportEmbroidery("simple.gcode"); // Export as G-code
exportEmbroidery("simple.svg"); // Export as SVG
exportEmbroidery("simple.png"); // Export as PNG

You can load the exported file into an embroidery machine or DIY embroidery machine to stitch your design.

In my environment, TAJIMA DST files loaded successfully on BERNINA, Brother, and E-lucky embroidery machines.

I won’t go into detail here, but there’s also the option of printing embroidery data on paper for hand embroidery or punch needle embroidery.

Example: Fractal Christmas Tree 2025 Edition

So there you have it—a quick overview of how to create embroidery designs with p5.embroider! As an example, let’s update the fractal Christmas tree from the 2023 Advent Calendar using p5.embroider.

In true 2025 fashion, I gave AI (Sonnet 3.5) the 2023 code along with the following prompt, then did some vibe coding to arrive at this result:

By using p5.embroider's function update the fractal xtree generation code to 
1. use vertex(x,y,w) format and branch edge to be narrower and end to be wider yet not to hit with other branches. 
2. use satin stitch to the star to make it mo shiney. 
3. add white stars around tree using stroke stitches  

fractal xmas tree embroidery ver.02

Conclusion

In this article, I introduced how to generatively design digital embroidery data with p5.js using p5.embroider.

You can find additional samples and documentation at the following URLs:

p5.embroider is still in early alpha stage, so there are many unsupported functions and bugs. If you have feature requests or find bugs, please feel free to report them at the following Issue tracker: https://github.com/nkymut/p5.embroider/issues/

We’re also actively looking for contributors to join the development! Feel free to send PRs as well.

Have a wonderful end of the year!