Open-source project
thread-pond/signature-pad avatar
thread-pond/signature-pad

signature-pad: a jQuery canvas signature widget that stores strokes as JSON

A jQuery plugin for assisting in the creation of an HTML5 canvas based signature pad. Records the drawn signature in JSON for later regeneration.

730 stars280 forksJavaScriptBSD-3-Clause

At a glance

What is it?
signature-pad is a jQuery plugin that turns a div into a signature capture area backed by an HTML5 canvas, and it records the drawn strokes as JSON so the signature can be regenerated later rather than flattened to an image. It suits a legacy form that needs a signature field today, and its dependency on FlashCanvas and jQuery 1.3.2 is a heavy price for a new project.
Who is it for?
signature-pad fits a team maintaining a jQuery era application that needs a signature capture field and wants the strokes preserved as structured JSON rather than a flat image, because regenerating a signature from stored data is the one thing it does that a canvas toDataURL export does not.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 86 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A jQuery plugin for a canvas signature field, with a JSON record of the strokes

signature-pad is a jQuery plugin for assisting in the creation of an HTML5 canvas based signature pad, and the second clause of the description is the part that matters most. It records the drawn signature in JSON for later regeneration.

That distinction is worth pausing on, because it is the difference between this plugin and a canvas export. The obvious way to capture a signature on a canvas is to read the canvas back as a data URL and post a PNG. This plugin instead keeps the geometry: the strokes, their points, and the ordering. A stored signature is therefore a data structure that the plugin can replay into a fresh canvas, which is what the regeneration example demonstrates, and the examples directory carries a sample-signature-output.js file that is presumably that structure.

The reason to want that is not exotic. A signature drawn in one session and shown again later has to look the same, and an image can only be scaled, not redrawn. A stroke record can be re-rendered at a different size, with different smoothing, and can have individual points removed.

The audience is a developer working in jQuery who needs a signature field in a form. The repository layout matches that audience closely. There is a single plugin file, jquery.signaturepad.js, with a minified companion jquery.signaturepad.min.js, a stylesheet at assets, a documentation.md, a Gruntfile.coffee for the build, a .jshintrc, and a package.json that carries no runtime dependencies at all and only a small set of dev dependencies for linting and minification.

The plugin is BSD-3-Clause licensed, credited to Thomas J Bradley, and the README notes that all dependencies, jQuery, json2.js and FlashCanvas, retain their own licenses.

The quick start is four steps and a stylesheet

The setup path is documented in four lines, and the first one is the important one.

You include jquery.signaturepad.css, flashcanvas.js, jquery.js, jquery.signaturepad.js and json2.js in your HTML file. Then you create the HTML following the example at examples/accept-signature.html, then you initialise the widget on the elements you want, and then you remember that most things are configurable, with the options list in documentation.md.

The initialisation call is a single jQuery call on a class selector, `$('.sigPad').signaturePad();`, which is the standard convention for this kind of plugin: mark your div with a class and let the plugin pick it up.

Two of the five script tags deserve a comment, because they are the reason this plugin sits where it sits in history.

json2.js is a polyfill for JSON, and the plugin needs JSON to serialise the stroke data. It was written for a period when JSON was not consistently available in older browsers, and the plugin's own use of JSON for the stroke record is the reason it appears in the dependency list at all.

FlashCanvas is the other one, and it is the significant constraint. The README lists the dependencies as FlashCanvas/1.5, json2.js, and jQuery/1.3.2+. FlashCanvas is a Flash based implementation of the HTML5 canvas API, and it was the standard workaround for browsers that shipped the canvas element without supporting its drawing context. Including flashcanvas.js means the plugin could offer a consistent drawing surface regardless of the browser's canvas support at the time.

A developer picking this up today inherits that whole arrangement, and the plugin's own README does not mention how to drop it. The dependency list in the README is the only statement about it, and it is a list, not a discussion of alternatives.

Four examples, each covering one behaviour you would actually need

The examples directory is the most useful part of the repository, because it covers the four situations a signature field runs into, and the demos are published so they can be opened in a browser.

Accepting a Signature is the baseline: a pad the user can draw on, with a way to submit the result. Requiring a Drawn Signature is the variant where an empty signature is not acceptable, which means the surrounding form has to check whether anything was actually drawn before it submits. Regenerating a Signature is the one that uses the JSON record, showing a stored signature redrawn on the page. Accepting Multiple Signatures covers the case of a form with more than one signatory, such as a contract with a customer and a witness.

There is a fifth example in the directory that the README does not list, full-window.html, which is presumably a layout variant rather than a different behaviour.

The demos are hosted on GitHub Pages under the thread-pond organisation, and the pages are reachable directly, which means you can see the behaviour without setting anything up. The examples are the practical documentation here, because the README itself defers to documentation.md for the options.

What the README does not document is the server side. There is no mention of how the JSON is validated, how a signature is bound to a record, or what happens if the payload is tampered with. A signature drawn in a canvas is not a cryptographic signature in any sense, and the plugin offers no mechanism for making it one, so a form that treats the output as proof of identity needs its own signing and verification scheme on the server. The README is silent on this, which means it is the developer's problem rather than something the plugin addresses.

Converting to an image, and what a canvas export actually gives you

The README has a dedicated section on converting to an image, pointing at documentation.md#converting-to-an-image, which tells you the plugin is not only about the JSON record.

Most users want a picture. A contract needs a stored image of the signature, a database column expects a blob, and an email to the customer needs a visual. So the plugin offers both, and the choice is between a flattened picture and a replayable drawing.

The canvas is the natural source for the image, since the drawing already happened there. The interesting part is the alternative: if you keep the JSON, you can produce the image later, on the server, at whatever size and quality the destination needs, and you can reproduce it exactly rather than rescaling a bitmap. For a document archive that has to be printed at 300 dpi, that difference matters. For a form that just needs a thumbnail, it does not, and the added complexity of storing and replaying points is wasted effort.

The documentation file is where the mechanics live, and the README does not duplicate them. The options list referenced from the quick start is in the same file, and the README's advice to remember that most things are configurable suggests the plugin exposes a wide surface: the pen colour, the line width, the background, the size of the pad, the behaviour when the clear button is pressed, and the shape of the JSON that gets emitted.

The repository also carries a CHANGELOG.md, which is where a project with a long history keeps its record of what changed. The version in package.json is 2.5.2, and the release list confirms the last tagged version is v2.5.2 from 2014-12-22, after v2.5.1 in April 2014 and v2.5.0 in October 2013.

A 2014 plugin, a 2026 last push, and a decade between them

The maintenance picture here needs care, because the two numbers point in different directions.

The last push was on 2026-07-29, so the repository is receiving commits. The releases, however, stopped in 2014. The most recent tag is v2.5.2 from 2014-12-22, with v2.5.1 from 2014-04-15 and v2.5.0 from 2013-10-17 before it. The version in package.json matches the last tag exactly, at 2.5.2.

So the code has been touched more recently than the last release, but there is no release newer than 2014 to install. A team pinning a version gets the 2014 state. A team taking the head of the default branch, main, gets newer commits with no version marker to record them.

There is also a change of hosting. The repository is thread-pond/signature-pad, and the README is written in the past tense about a different owner, crediting Thomas J Bradley of thomasjbradley.ca, with the plugin originally distributed through a .nojekyll file and Grunt build. The main branch, the presence of a package.json with a private flag, and the assets directory all point at a current fork that is still shipping the same plugin file.

The practical consequence is that a 2014 jQuery plugin is now maintained by a fork whose build tooling is Grunt with a coffee file, with jshint for linting and uglify for minification, and matchdep for the task dependencies. There is no test suite in the dev dependencies, and no test directory in the repository layout. The build is a lint and a minify, not a test.

The dependencies tell their own story as well. The dev dependencies are grunt, grunt-contrib-jshint, grunt-contrib-uglify, grunt-text-replace and matchdep, all old enough that they will need attention on a current Node. The runtime dependencies are declared as none in package.json, because jQuery, json2.js and FlashCanvas are loaded by script tag in the page, not installed through the package manager. That is consistent with a plugin that predates bundlers, and it means the plugin manager or bundler story has to be built by the consumer.

Against a canvas toDataURL export and against a modern pointer event library

The alternative that most teams will actually reach for is not another signature plugin, it is about twenty lines of code that listens for pointer events on a canvas and calls toDataURL on it.

That approach wins on every axis except one. It has no dependencies at all, it uses pointer events so it works on touch screens and with a stylus, it produces a PNG directly, and it is a few dozen lines rather than a plugin with an options surface. The reason to prefer signature-pad over it is the one the README leads with: the JSON stroke record.

So the decision reduces to whether you need to replay a signature. If a signature is only ever stored and displayed as an image, the hand-written version is better, and the plugin's own dependency on FlashCanvas and jQuery 1.3.2 makes it a strange choice for a new build. If you need to redraw a signature at a different resolution, or to let a user undo a stroke, or to keep a vector record for a legal record, then the stroke data is worth having and a hand-written implementation would have to build it.

The other alternative, a modern signature library built on pointer events and published as an npm package with types and tests, gives you the replay capability without the legacy stack, at the cost of a dependency with its own release cadence and its own opinions about the data format.

Whichever direction you go, one thing does not change and it is the point the README never makes. A canvas signature is a drawing, not a signature in the cryptographic sense, and it carries no evidence of who made it. The library that draws it does not change that, and any system that treats the result as proof of identity needs signing and verification of its own on the server side.

Editorial conclusion

signature-pad fits a team maintaining a jQuery era application that needs a signature capture field and wants the strokes preserved as structured JSON rather than a flat image, because regenerating a signature from stored data is the one thing it does that a canvas toDataURL export does not. It does not fit a new project, since it depends on FlashCanvas and json2.js and targets jQuery 1.3.2 and later, and it does not fit a mobile web form, since the plugin predates pointer events. Before adopting it, read documentation.md for the options list, because the README states that most things are configurable and the examples directory already covers accepting a signature, requiring a drawn one, regenerating one, and accepting multiple ones, so the four behaviours you are likely to need are already demonstrated rather than documented.

Frequently asked questions

How do I set up signature-pad in a page?

The README gives four steps: include jquery.signaturepad.css, flashcanvas.js, jquery.js, jquery.signaturepad.js and json2.js in your HTML, create the markup following the accept-signature example, then initialise the widget with $('.sigPad').signaturePad();. Most options are documented in documentation.md.

What dependencies does the signature-pad plugin need?

The README lists FlashCanvas/1.5, json2.js, and jQuery/1.3.2 or later, and they are loaded as script tags in the page rather than installed through the package manager. The plugin's own package.json declares no runtime dependencies.

How does signature-pad store the drawn signature?

The plugin records the drawn signature in JSON for later regeneration, rather than flattening the canvas to an image. The examples directory includes a regenerate-signature example and a sample-signature-output.js file, and the README also documents converting a signature to an image.

What examples does the signature-pad repository provide?

The examples cover accepting a signature, requiring a drawn signature, regenerating a signature and accepting multiple signatures, and hosted demos for the first three are published on GitHub Pages. The examples directory also contains a full-window.html page that the README does not list.

Is signature-pad still maintained?

The last push was on 2026-07-29, but the most recent tagged release is v2.5.2 from 2014-12-22, and the version in package.json is still 2.5.2. The repository is hosted under the thread-pond organisation, and the original author is credited as Thomas J Bradley.

Official sources

  1. Issues
  2. License: BSD-3-Clause
  3. README
  4. Releases
  5. thread-pond/signature-pad on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/thread-pond-signature-pad.svg)](https://hysenlabs.com/projects/thread-pond-signature-pad)

Was this useful?